为什么我们在Verilog / Systemverilog中使用Always Block设计的Combinatorial Circuits中使用Blocking语句?为什么不Nonblocking?

它在任何地方都被提到这个作为指导,但经过多次思考后我想知道如果我们在Always Block for Combinatorial中使用Nonblocking语句会造成什么伤害.我不会将两者混合在一起.但我觉得当我们在Always Block中使用Nonblocking for Combinatorial语句时,它更准确地代表了硬件.不是吗?

例如,如果我们采取以下电路:

在此图中,当输入a,b,c被提供时,输出x1和x将不会立即可用.将有门延迟.第一个x1将可用,然后x将可用.如果我们使用阻止语句,它们都可以立即使用如果我们使用非阻塞,它更准确地类似于硬件.

例如,如果我们根据上图获取以下代码

module block_nonblock(output logic x,x1,y,y1,input logic a,b,c);

always@* begin : BLOCKING
    x1 = a & b;
    x  = x1 & c; 
end

always@* begin : NONBLOCKING
    y1 <= a & b;
    y  <= y1 & c; 
end

endmodule

这综合为:

两者都被合成为和门,并给出相同的模拟结果,但是当我们检查增量时间输出的变化时,我觉得与阻塞相比,非阻塞更准确地匹配硬件.

我还经历了:IEEE P1364.1 / D1.6Verilog®寄存器传输级综合标准草案,
它指定使用非阻塞进行顺序建模,但没有使用“阻止”使用“始终”进行组合建模
 块.它说不要在组合语句中混合使用两者(阻塞和非阻塞).

因此,我们不应该在处理纯组合逻辑的总块中使用非阻塞用于组合语句(非顺序/不涉及时钟)

最佳答案
造成的危害在于模拟;在表现和比赛条件.

对于a或b中的每次更改,您的NONBLOCKING代码都会执行两次.非阻塞分配更新被调度到稍后的事件队列中,这会导致块重复执行时产生更大的波纹效应.

当您模拟RTL代码时,您在没有物理延迟的情况下这样做,并且综合工具了解逻辑将如何实现.但是仿真工具不能做到这一点,也需要使用不可合成的代码.他们必须完全按照书面执行代码.而且他们还必须在具有单个或有限数量线程的处理器上处理大量并发执行代码.因此,仿真在软件中引入了实际硬件中不存在的竞争条件.编写顺序逻辑时,非阻塞分配可以防止这些竞争条件.但是如果在组合逻辑中使用它们,它们会产生相反的影响,特别是在用于生成时钟的组合逻辑中时.

转载注明原文:为什么我们在Verilog / Systemverilog中使用Always Block设计的Combinatorial Circuits中使用Blocking语句?为什么不Nonblocking? - 代码日志