x <= y + c; //语句1 y <= a + b; //语句2
end
虽然语句1的在语句2之前,但是由于是非阻塞赋值,语句1的执行不影响语句2的执行,在该仿真时刻完了后,才更新左端的值。若该仿真时刻y=5(旧值),c=4,a=3,b=1,则x=8,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
由于仿真时刻完了后才会去更新左端的值,所以上面两个过程将最终形成一反馈移位寄存器。
在实际使用中,我们需要遵循以下的原则: 1.在时序逻辑中,使用非阻塞赋值; 2.在组合逻辑中,使用阻塞赋值;
3.在同一个always块中,不要混合使用阻塞赋值和非阻塞赋值;
4.在同一个always块中,如果既有组合逻辑又有时序逻辑,使用非阻塞赋值; 5.always模块的敏感表为电平敏感信号时,使用阻塞赋值; 6.不要使用#0时延进行赋值。 7.不要在阻塞赋值中使用时延语句。
8.在行为级描述中,若语句间是顺序执行的关系,使用阻塞赋值。
另外一点需注意的就是,阻塞赋值是相对时间赋值,非阻塞赋值是绝对时间赋值。
4.2 HDL代码的可综合性
任何符合HDL语法标准的代码都是对硬件行为的一种描述,但不一定是可直接对应成电路的设计信息。行为描述可以基于不同的层次,如系统级,算法级,寄存器传输级(RTL)、门级等等。以目前大部分EDA软件的综合能力来说,只有RTL或更低层次的行为描述才能保证是可综合的。绝大部分电路设计必须遵循RTL的模式来编写代码,而不能随心所欲得