下面介绍阻塞和非阻塞语句的本质区别和在FPGA设计中的不同运用。

Verilog HDL 对于变量赋值的时候,有阻塞和非阻塞两种方式:

1、阻塞: 用 “=”

2、非阻塞 : 用 “<=”

1.阻塞语句

        顾名思义,即本条语句具有影响下一条语句的作用,在同一个进程always中,一条阻塞赋值语句的执行是立刻影响着下条语句的执行情况和结果。如果该条语句没有执行完,那么下条语句不可能进入执行状态的,因此,从字面层上理解,该条语句阻塞了下面语句的执行。
        下面代码解释:在上升沿触发的always进程里,先执行b=c,再执行a=b,那么本质上,在一个时钟沿触发里面,a=c成立。也就是说,不要b变量,直接在进程里赋值a=c,结果是一样的。

always @(posedge clk)
    begin
        b = c;
        a = b;
    end

2.非阻塞语句

       下面代码解释,b<=c,不会因为a<=b没有执行完毕而不执行,只要时钟触发进程,那么a<=b,b<=c同时执行。所以,如果c为1,b为0,a为1的话,那么在在非阻塞语句的进程里面,一个时钟沿到来,由于他们之间是同时执行的,所以把c的1赋给了b,把b的0赋给了a。

always @(posedge clk)
    begin
        a <= b;
        b <= c;
    end

3.总结

       阻塞语句是顺序执行的,而非阻塞语句是同时执行的。(在一次触发进程里,无论是阻塞和非阻塞语句,每条语句只执行一次)。
       设计里面运用好阻塞语句和非阻塞语句,总体上来讲,遵循大体原则:阻塞语句运用在组合逻辑电路设计里面,非阻塞语句运用在时序逻辑电路设计里面。但是一般来讲,一个设计往往包含着组合逻辑和时序逻辑。可以再细分为以下几个情况:

  • 1: 当为时序逻辑建模,使用“非阻塞赋值”。
  • 2: 当为锁存器(latch) 建模,使用“非阻塞赋值”。
  • 3: 当用always块为组合逻辑建模,使用“阻塞赋值”
  • 4: 当在同一个always块里面既为组合逻辑又为时序逻辑建模,使用“非阻塞赋值”。
  • 5: 不要在同一个always块里面混合使用“阻塞赋值”和“非阻塞赋值”。
  • 6: 不要在两个或两个以上always块里面对同一个变量进行赋值。
  • 7: 使用$strobe以显示已被“非阻塞赋值”的值。
  • 8: 不要使用#0延迟的赋值。