Verilog always块中变量默认值设置及赋值执行疑问
关于Verilog时序块中非阻塞赋值执行逻辑的解答
先把你的代码整理成更易读的格式:
always @(posedge clk) begin r <= 3; if( cond1 ) a <= 1; else if( cond2 ) begin a <= 2; r <= 3; end else a <= 3; end
直接给你结论:最上方的r <= 3语句在第一个(cond1为真)和最后一个(cond1/cond2都为假)分支里都会被评估,并且最终会生效。
具体解释:
Verilog的时序always块(带时钟沿触发的)里,语句是按顺序逐行评估的,但非阻塞赋值(<=)的实际变量更新,是在时钟沿触发后的「非阻塞赋值调度阶段」统一完成的。
针对你的三个分支场景:
当
cond1为真时:
程序会先执行第一行的r <= 3——这一步会把「r要更新为3」这个操作放进非阻塞赋值队列,然后进入if分支执行a <= 1。因为这个分支里没有其他对r的赋值,所以最终r会被更新为3,也就是最上方的赋值语句完全生效。当
cond2为真时:
同样先执行r <= 3放入队列,然后进入else if分支,先执行a <=2,再执行r <=3——这时候又把「r要更新为3」放进队列(两次赋值的目标值一样,所以结果和只执行一次没区别),最终r还是3。如果这里把r <=3改成r <=4,那最终r会是4,因为最后一次评估的赋值会覆盖队列里之前的记录。当
cond1和cond2都为假时:
先执行r <=3放入队列,然后进入最后一个else分支执行a <=3。没有其他对r的赋值,所以r最终被更新为3,最上方的语句生效。
简单来说,你现在写的这个默认值方式是有效的——不管进入哪个分支,r都会被设置为3(除非某个分支里有对r的其他赋值,但你的代码里cond2分支也是赋值3,所以结果一致)。
内容的提问来源于stack exchange,提问作者Roarer
相关产品推荐
相关产品推荐

