非阻塞赋值和阻塞赋值能出现在一个always块内吗?可以,但请慎用

2023-11-09 14:57:31 浏览数 (1)

我们用了两篇文章,分别讨论了Verilog HDL里面的“非阻塞赋值”和“阻塞赋值”。用实例分析了如果在一个always块内等式右边的表达式或者变量,是另一个always块内等式左边的表达式或者变量,仿真器在同一个时间(同一个时钟的边沿)内同时执行两个等式,这就会导致竞争产生。令人难受的是,一般这种竞争问题,很难去Debug,因为有时候,我们也不太清楚仿真器是如何调度RTL代码。为了规避竞争的产生,我在文章里面推荐了4中编码方式,如果能够认真体会的话,应该可以规避大量的竞争。而深刻理解“非阻塞赋值”,则能够更好的描述时序逻辑电路。

我们在建议的编码原则里面,讲到有一条,在一个always块内,只出现一种赋值类型,不能混合使用非阻塞赋值和阻塞赋值。有的朋友就问我,是不是always块里面就完全不能混合使用呢?今天我就再谈一下这个问题。

一个always块内,两种赋值方式不能混用?

首先给出答案,在一个always块里面,这两种方式是可以混用的。Verilog语法并没有禁止这样做,所以我们看两个例子:

  • 例1

reg test_o1

reg test_o2;

always@(posedge clk or negedge rst_n)

begin

if(~rst_n)

test_o1 <= 1'b0;

else

begin

test_o2 = 1'b1;

test_o1 <= test_o2;

end

end

在这个例子里面,我们认为功能是正确的,因为非阻塞赋值和阻塞赋值虽然出现在一个always块里面,但是它们分别作用在不同的变量test_o1/test_o2。尽管如此,这样编码除了少两行代码之外,没有什么好处,所以,我还是依然不推荐这么做。

  • 例2

reg test_o1

reg test_o2;

always@(posedge clk or negedge rst_n)

begin

if(~rst_n)

test_o1 = 1'b0;

else

begin

test_o2 = 1'b1;

test_o1 <= test_o2;

end

end

在这个例子里面,功能仿真是没有问题的,但是Design Compile会报出ERROR,因为对同一个变量test_o1 ,既有“非阻塞赋值”,又有“阻塞赋值”,我们必须要修改完毕,才能通过Design Compile综合。所以还是那句老话,不推荐这么编码。

小结

今天的文章,我们讨论了Verilog HDL中的非阻塞赋值和阻塞赋值。并且举了2个实例来进一步说明非阻塞赋值和阻塞赋值的问题。所以我依然建议不要混用。

上述内容由久芯网www.9icnet.com编辑整理发布,请勿转载。

0 人点赞