4.1.3阻塞赋值与非阻塞赋值
在Verilog HDL中,有两种过程性赋值方式,即阻塞赋值(blocking assignment)和非阻塞赋值(non-blocking assignment)。这两种赋值方式有着根本的区别,如果使用不当,综合出来的结果会和设计的期望结果相去甚远。
1.阻塞赋值的操作符为 “ = ”。它的含义是在计算等式右侧表达式值及完成其赋值时不会被其他的verilog语句打断,就是说,在当前赋值没有完成之前,它阻塞了其他verilog语句的执行。
例如:begin
x = y + c; //语句1 y = a + b; //语句2
end
语句1和语句2都要求在同一仿真时刻执行,但在语句1没有执行完之前,是不会执行语句2的,它"阻塞"语句2的执行。这里说的"执行完"指的是在本时刻计算完y+c的值,并赋给y。若该仿真时刻y=5(旧值),c=4,a=3,b=1,则x=9,y=4。
还有下面的情况,过程1和过程2是同一个module中的两个always语句块。
过程1: 过程2:
always @ (posedge clk or negedge rst_n) always @ (posedge clk or negedge rst_n) begin begin
if ( rst_n == 1'b0) if ( rst_n == 1'b0) y = 1'b0; x = 1'b1; else else
y = x; x = y; end end
仿真开始时,两个always语句块将并行地同时执行。如果仿真器先执行过程2的话,则在复位完后,x、y的值最终都会变为1;如果先执行过程1,则x、y的值最终都会变为0。
为什么会出现这种情况呢?因为按照Verilog的标准,上例中两个always块是并行执行的,与书写的前后顺序无关,但是,verilog标准没有规定在这种特殊情况下的执行顺序。所以,这需要我们在编程时避免这样的代码。
2.非阻塞赋值的操作符为 “ <= ”。它的含义是在赋值操作时刻开始时计算等式右边,赋值操作时刻结束时更新等式左边。在这期间,可以执行其它verilog语句,也不阻塞其它verilog语句的执行。 例如: begin