阻塞和非阻塞赋值


1 阻塞赋值

2 非阻塞赋值

3 自触发always块

  • 使用阻塞赋值不能自触发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    module osc(clk);
    output clk;
    reg clk;
    initial begin
    #10 clk = 0;
    end//initial
    always @(clk)
    #5 clk = ~clk;
    endmodule

    当语句执行到 clk = ~clk,clk的值立马改变,在此期间不允许其他语句干扰,always块也无法感知到clk的翻转,所以不能出发always块

  • 非阻塞赋值可以产生自触发振荡器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    module osc(clk);
    output clk;
    reg clk;
    initial begin
    #10 clk = 0;
    end//initial
    always @(clk)
    #5 clk <= ~clk;
    endmodule

    当clk第一次改变的时候,@(clk)被触发,此时赋值表达式的RLS就已经被计算出来了,并将给LHS赋值的事件安排在更新事件队列中。在非阻塞赋值事件更新队列被激活后,又遇到了@(clk)触发语句,always再次对clk的值变化产生感应。非阻塞的LHS被更新时,always再次被触发。

使用原则

  • 组合逻辑块使用阻塞赋值
  • 时序逻辑使用非阻塞赋值
  • 组合和时序逻辑同时存在使用非阻塞赋值
  • 在一个always中不要既有阻塞又有非阻塞赋值

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!