非阻塞赋值的理解

一、源代码

module block_nonblock(clk,rst_n,a,b,c,out);
    input clk;input rst_n;input a;input b;input c;output out;
    reg [1:0]out;reg [1:0]d;
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        out <= 2'b0;
    else begin
        d <= a + b;
        out <= c + d;   //此处都是非阻塞赋值 <=
    end
endmodule

二、测试文件

 `timescale 1ns / 1ps
module block_nonblock_tb();
    reg clk;reg rst_n;reg a;reg b;reg c;
    wire [1:0]out;
    block_nonblock block_nonblock_inst0( .clk(clk),.rst_n(rst_n),.a(a),.b(b),.c(c),.out(out));
    initial clk = 0;
    always #10 clk = ~clk;      
    initial begin
    rst_n = 0;a = 0;b = 0;c = 0;#201;
    rst_n = 1;#200;   a = 0;b = 0;c = 1;#200;
    a = 0;b = 1;c = 0;#200;   a = 0;b = 1;c = 1;#200;
    a = 1;b = 0;c = 0;#200;   a = 1;b = 0;c = 1;#200;
    a = 1;b = 1;c = 0;#200;   a = 1;b = 1;c = 1;#200;
    $stop;
    end
endmodule

三、波形

1、疑问:

在2处的上升沿,a=1,b=1, d <= a + b(1+1=10) 所以 d 的值是 10

c=0,out <= d + c ,按理说,10 + 0 = 10 ,也就是 out 应该是 10,但是却是01?

其实这是非阻塞赋值引起的现象。

2、理解误区:

d <= a + b;  

out <= c + d;

按照这个代码,可能我们会理解成,先执行第一条语句,

再执行第二条语句(即我们理解成先算出 d 的结果,再将 d 的结果带入第二条语句,算出 out 的结果)

这种理解,是阻塞赋值的思想(阻塞赋值即,只有先执行完前面的语句,才能执行后面的语句。)

但是,上面两条语句是非阻塞赋值,非阻塞赋值的两条语句会同时执行!

3、答案:

d <= a + b;  

out <= c + d;

在2上升沿处,两条语句要同时执行。

但是在2上升沿处,第一条语句还没有执行完,d值还没有产生,第二条语句没有对应的 d 值,out的值怎么计算?

要计算 2 处上升沿的 out 值,这条语句(out <= c + d;)中 d 的值只能用 1处上升沿的 d 值!

所以 第二条语句(out <= c + d;)的理解应该是 

所以 2处上升沿的out 值 =  2处上升沿的c值 + 1处上升沿的 d 值!

四、源代码生成的电路图

 ( d 和 out 变量都生成了寄存器。在上面的源代码中,即便改变两条非阻塞赋值语句的顺序,生成的电路图也一样。非阻塞赋值的多条语句,只表示电路的连接方式,所以vivado生成的电路都一样。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值