Vivado下组合逻辑模块的仿真 | 您所在的位置:网站首页 › vivado如何关联modelsim › Vivado下组合逻辑模块的仿真 |
文章目录
与门或门非门异或门同或门比较器半加器全加器乘法器数据选择器3-8 译码器三态门
组合逻辑电路的特点是任意时刻的输出仅仅取决于输入信号,输入信号变化,输出立即变化,其变化不依赖于时钟。
本文中的例子中模块名都是gate,仿真测试文件中的模块名都是sim_gate。如果你在一个工程下创建了好几个.v文件,要运行其中的一个仿真,可以选中该文件,点击Set as Top,这样仿真的就是置于顶部的那个文件了。
与门
与门的代码如下。 module gate(a,b,c); input a; input b; output c; assign c = a & b; endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg a; reg b; wire c; initial begin a = 0; b = 0; forever begin #({$random}%100) //生成一个0-99的随机数,以 ns 为单位延迟该随机数的时长 a = ~a; #({$random}%100) b = ~b; end end gate uut_gate( .a(a), .b(b), .c(c) ); endmodule与门的仿真结果如下图所示,仿真运行时间设置为1us。 或门的代码只需要将与门代码中的"&“改为”|"即可。 或门的仿真结果如下图所示。 非门的代码比与门的代码更简单,不再需要变量c,b=~a即可,然后把仿真文件中的代码删减一下即可。 非门的仿真结果如下图所示。 异或门的代码只需要将与门代码中的"&“改为”^"即可。 异或门的仿真结果如下图所示。 同或门的代码只需要将与门代码中的"&“改为”^~"即可。 同或门的仿真结果如下图所示。 比较器这里以 c=a>b 为例说明,如果 a>b,那么c的值为1,否则为0。对于二进制来说,只有a=1,b=0时,c=1。 比较器的代码只需要将与门代码中的"&“改为”>"即可。 比较器的仿真结果如下图所示。 半加器和全加器是算术运算电路中的基本单元,由于半加器不考虑从低位来的进位,所以称为半加器。 半加器的真值表如下表所示。 absumcount0000011010101101半加器的代码如下。 module gate(a,b,sum,count); input a; input b; output sum; output count; assign sum = a + b; assign count = a & b; endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg a; reg b; wire sum; wire count; initial begin a = 0; b = 0; forever begin #({$random}%100) a = ~a; #({$random}%100) b = ~b; end end gate uut_gate( .a(a), .b(b), .sum(sum), .count(count) ); endmodule半加器的仿真结果如下图所示。 全加器在半加器的基础上考虑来自低位的进位,因此实现起来更加复杂,参与运算的数也比半加器多一个。 全加器的真值表如下表所示。 abcinsumcount0000001010100101100100110011011010111111全加器的代码如下。 module gate(a,b,sum,count,cin); input a; input b; input cin; output sum; output count; assign {count,sum} = a + b + cin; //通过一个位拼接运算达到计算count和sum的目的 endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg a; reg b; reg cin; wire sum; wire count; initial begin a = 0; b = 0; cin = 0; forever begin #({$random}%100) a = ~a; #({$random}%100) b = ~b; #({$random}%100) cin = ~cin; end end gate uut_gate( .a(a), .b(b), .cin(cin), .sum(sum), .count(count) ); endmodule全加器的仿真结果如下图所示。 乘法器这里在设置时将两个乘数设置为两位的,这样其最大表示十进制的3,相乘后最大表示十进制的9,因此需要4位二进制的输出。 乘法器的代码如下。 module gate(a,b,c); input[1:0] a; input[1:0] b; output[3:0] c; assign c = a * b; endmodule仿真测试代码如下。 module sim_gate(); reg[1:0] a; reg[1:0] b; wire[3:0] c; initial begin a = 0; b = 0; forever begin #({$random}%100) a = {$random}%4; #({$random}%100) b = {$random}%4; end end gate uut_gate( .a(a), .b(b), .c(c) ); endmodule乘法器的仿真结果如下图所示。 下面这个例子是四选一数据选择器,选择信号是两位,输入信号是4个,可以将其设置为1位,也可以设置为多位,输出信号与输入信号的位数一致。 四选一数据选择器的选择情况如下表所示。 selmux00(0)a01(1)b10(2)c11(3)d数据选择器的代码如下。 module gate(a,b,c,d,sel,mux); input[2:0] a; input[2:0] b; input[2:0] c; input[2:0] d; input[1:0] sel; output reg[2:0] mux; always@(a,b,c,d,sel) begin case(sel) 2'b00 : mux = a; 2'b01 : mux = b; 2'b10 : mux = c; 2'b11 : mux = d; endcase end endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg[2:0] a; reg[2:0] b; reg[2:0] c; reg[2:0] d; reg[1:0] sel; wire[2:0] mux; initial begin a = 0; b = 0; c = 0; d = 0; forever begin #({$random}%100) a = {$random}%8; #({$random}%100) b = {$random}%8; #({$random}%100) c = {$random}%8; #({$random}%100) d = {$random}%8; end end initial begin sel = 2'b00; #250 sel = 2'b01; #250 sel = 2'b10; #250 sel = 2'b11; end gate uut_gate( .a(a), .b(b), .c(c), .d(d), .sel(sel), .mux(mux) ); endmodule输入是1位时,数据选择器的仿真结果如下图所示。 3-8 译码器的译码情况如下表所示。 addrdecoder000(0)11111110001(1)11111101010(2)11111011011(3)11110111100(4)11101111101(5)11011111110(6)10111111111(7)011111113-8 译码器的代码如下。 module gate(addr,decoder); input[2:0] addr; output reg[7:0] decoder; always@(addr) begin case(addr) 3'b000 : decoder = 8'b1111_1110; 3'b001 : decoder = 8'b1111_1101; 3'b010 : decoder = 8'b1111_1011; 3'b011 : decoder = 8'b1111_0111; 3'b100 : decoder = 8'b1110_1111; 3'b101 : decoder = 8'b1101_1111; 3'b110 : decoder = 8'b1011_1111; 3'b111 : decoder = 8'b0111_1111; endcase end endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg[2:0] addr; wire[7:0] decoder; initial begin addr = 3'b000; #125 addr = 3'b001; #125 addr = 3'b010; #125 addr = 3'b011; #125 addr = 3'b100; #125 addr = 3'b101; #125 addr = 3'b110; #125 addr = 3'b111; end gate uut_gate( .addr(addr), .decoder(decoder) ); endmodule3-8 译码器的仿真结果如下图所示。 三态门是FPGA中经常用到的器件,使能信号用于打开或关闭三态门。 三态门的代码如下。 module gate(en,in,out); input en; input in; output out; assign out = en ? in : 1'bz; endmodule仿真测试代码如下。 `timescale 1ns / 1ps module sim_gate(); reg en; reg in; wire out; initial begin en = 1; #250 en = 0; #250 en = 1; #250 en = 0; end initial begin in = 0; forever begin #({$random}%100) in = ~in; end end gate uut_gate( .en(en), .in(in), .out(out) ); endmodule三态门的仿真结果如下图所示。 仿真测试代码如下。 module sim_gate(); reg en0; reg in0; wire out0; reg en1; reg in1; wire out1; wire bio; initial begin en0 = 0; en1 = 1; #200 en0 = 0; en1 = 0; #50 en0 = 1; en1 = 0; #200 en0 = 0; en1 = 0; #50 en0 = 0; en1 = 1; #250 en0 = 1; en1 = 0; end initial begin in0 = 0; in1 = 0; forever begin #({$random}%100) in0 = ~in0; #({$random}%100) in1 = ~in1; end end gate uut_gate0( .en(en0), .in(in0), .out(out0), .bio(bio) ); gate uut_gate1( .en(en1), .in(in1), .out(out1), .bio(bio) ); endmodule双向的输入和输出的仿真结果如下图所示。 参考资料: ZYNQ 开发平台 FPGA 教程 AX7020 |
CopyRight 2018-2019 实验室设备网 版权所有 |