block_nonblock.v 文件
module block_nonblock( Clk , Rst_n, a , b , c , out ); input Clk ; input Rst_n ; input a ; input b ; input c ; // out = a+b+c ; // d = a+b ; // out = d +c ; output reg [1:0]out ; reg [1:0]d ; always@(posedge Clk or negedge Rst_n ) if(Rst_n == 1'b0) out = 2'b0 ; else begin out <= a + b + c; //建议使用阻塞赋值 end //非阻塞赋值 : 运算符: <= ,前后执行时【并行运算】,代码执行不分前后(结构时确定没有问题的(多条语句赋值不存在前后顺序), //但是如果多条语句中的数据或者说变量存在关联,那么需要考虑的是逻辑结构的延时 //或者说是D触发器的延时问题导致的数据出现的错误) //阻塞赋值 : 运算符: = ,执行语句【有先后顺寻】,存在延迟情况,存在不确定性(有的时候会出现问题) /********* 非阻塞赋值 **********/ /* 方式①: out <= a + b + c; */ /* 方式②: d <= a + b ; out <= a + b + c; */ /* 方式③: out <= d + c; d <= a + b ; */ /********* 阻塞赋值 **********/ /* 方式④: 非并行运算 d = a + b ; out = d + c; */ /* 方式⑤: 非并行运算 out = d + c; d = a + b ; */ // 这里可以通过仿真结果得到, 方式④和方式①得到的电路是一样的,也就是我们想要的效果 // 这里可以通过仿真结果得到, 方式②和方式③得到的电路是一样的, // 这里可以通过仿真结果得到, 方式④和方式⑤得到的电路是【不一样】的, // 但是电路输出结果会因为延时得到的结果会存在延时的数据错误,我们需要在设计的时候需要去避免 endmoduleblock_nonblock_tb.v 文件
`timescale 1ns/1ns `define clock_period 20 module block_nonblock_tb; reg Clock; reg Rst_n; reg a,b,c; wire [1:0]out; block_nonblock block_nonblock0(Clock,Rst_n,a,b,c,out); //新的一种模块名称加载 initial Clock = 1; //时钟信号 always#(`clock_period/2) Clock = ~Clock; initial begin Rst_n = 1'b0; a = 0; b = 0; c = 0; #(`clock_period*200 + 1); //信号初始化 ,+1 避免和时钟信号对齐,仿真时更加接近实际的电路 Rst_n = 1'b1; #(`clock_period*200); a = 0 ; b = 0 ; c = 0; #(`clock_period*200); a = 0 ; b = 0 ; c = 1; #(`clock_period*200); a = 0 ; b = 1 ; c = 0; #(`clock_period*200); a = 0 ; b = 1 ; c = 1; #(`clock_period*200); a = 1 ; b = 0 ; c = 0; #(`clock_period*200); a = 1 ; b = 0 ; c = 1; #(`clock_period*200); a = 1 ; b = 1 ; c = 0; #(`clock_period*200); a = 1 ; b = 1 ; c = 1; #(`clock_period*200); #(`clock_period*200); $stop; end endmodule