在Verilog HDL设计中,经常会遇到阻塞赋值与非阻塞赋值,这是学习逻辑设计时最基础的知识点。设计者经常会在书中看到一些建议:什么时候该用阻塞赋值,什么情况下使用非阻塞赋值。可是,如果仅仅按照这样的设计推荐来进行设计的话,经常会碰到一头雾水的情况。本文就对阻塞赋值和非阻塞赋值进行详细的讨论,深入分析这两种赋值语句的区别。
“阻塞”与“非阻塞”疑问的由来,主要体现在always或initial语句中。
在任何书上都会碰到的分析为:阻塞赋值“=”与非阻塞赋值“<=”的区别在于:非阻塞赋值语句右端表达式计算完后并不立即赋值给左端,而是马上启动下一条语句继续执行;而阻塞赋值语句在每个右端表达式计算完后立即赋值给左端变量。
1、语义分析
首先来看阻塞赋值与非阻塞赋值在语义上的含义。
always @ (posedge clk)
begin
q1 = d;
q2 = q1;
q3 = q2;
end
在所有的语句执行完以后,该always语句等待clk的上升沿到来,从而再次触发begin...end语句块。
其次来分析非阻塞赋值。
非阻塞赋值,就是指当前语句的执行互惠阻塞下一语句的执行。下面为非阻塞赋值的语句结构:
sum <= A+B
上式中左边的A+B称之为右式(RHS)计算事件,SUM称之为左式(LHS)更新事件。无论左式还是右式,都有可能即是变量,又是表达式。
非阻塞赋值的RHS计算属于活跃事件,需要优先执行,因此首先执行A+B,然后产生一个更新事件,把计算结果更新到SUM中,将“更新事件”放入事件队列中,但不会马上执行,即使这个更新事件属于当前时间的事件。因为非阻塞赋值的更新事件优先级较低,