为什么我们在使用Verilog/Systemverilog中的Always Block设计的组合电路中使用阻塞语句?为什么不使用非阻塞?

为什么我们在使用Verilog/Systemverilog中的Always Block设计的组合电路中使用阻塞语句?为什么不使用非阻塞?,verilog,fpga,system-verilog,synthesis,register-transfer-level,Verilog,Fpga,System Verilog,Synthesis,Register Transfer Level,在任何地方都会提到这一点作为指导,但经过深思熟虑后,我想知道如果我们在组合运算中使用Always Block中的非阻塞语句,它会造成什么危害。我不会把两者混在一起。但我觉得当我们在Always Block中对组合语句使用非阻塞时,它更准确地表示硬件。是不是 例如,如果我们采用以下电路: 在该图中,当提供输入a、b、c时,输出x1和x将不会立即可用。将有登机口延误。首先x1可用,然后x可用。如果我们使用阻塞语句,这两种语句都可以立即使用。如果我们使用非阻塞,它更准确地类似于硬件 例如,如果我们根

在任何地方都会提到这一点作为指导,但经过深思熟虑后,我想知道如果我们在组合运算中使用Always Block中的非阻塞语句,它会造成什么危害。我不会把两者混在一起。但我觉得当我们在Always Block中对组合语句使用非阻塞时,它更准确地表示硬件。是不是

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

在该图中,当提供输入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
模块块\非块(输出逻辑x、x1、y、y1、输入逻辑a、b、c);
始终@*开始:阻塞
x1=a&b;
x=x1&c;
结束
始终@*开始:非阻塞
y1你问“那么,我们不应该对顺序组合语句使用非阻塞吗?”答案是否。

如果在时钟始终块中对组合逻辑使用非阻塞分配,将得到比预期更多的触发器。基本上,时钟始终块中的非阻塞分配在您模拟和推断触发器时的行为类似于触发器

所以

1-对闸门和闸门使用阻塞分配


2-对触发器使用非阻塞分配。

危害在模拟中;在性能和比赛条件方面

对于ab中的每个更改,您的非阻塞代码执行两次。非阻塞分配更新被安排到稍后的事件队列中,这会导致更大的涟漪效应,块会被重复执行


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

您自己对电路行为的描述实际上表明使用了阻塞操作

你说:(我的)

在该图中,当输入a、b、c被提供时,输出x1和x1 x将不会立即可用。将有登机口延误第一个x1 将可用然后x将可用。如果我们使用阻塞 这两个语句都可以立即使用。如果我们使用非阻塞,它 更准确地模拟硬件

因此,您需要
x1
x
之前可用。所以你的总是阻塞必须使用阻塞赋值,所以

always@* begin : BLOCKING
    x1 = a & b;
    x  = x1 & c; 
end
x1
首先会有一个已知值,然后,
x
才会有一个值。如果您使用非阻塞

always@* begin : NON BLOCKING
    x1 <= a & b;
    x  <= x1 & c; 
end
始终@*开始:非阻塞

我已经找到了一个满意的答案,需要输入。我觉得我们应该对组合语句和顺序语句使用非阻塞语句

对于顺序,很明显我们应该使用y

我将描述组合块的原因。 对于组合段,我们将使用非阻塞语句,因为当我们使用阻塞或非阻塞语句时,即使它最终为我们提供相同的硬件或RTL;非阻塞语句向我们展示了模拟中的小故障。这些小故障也会出现在硬件中(由于门延迟),因此我们可以在模拟中看到它们时进行纠正,以便在设计/开发周期的后期造成较少的危害

在我最初在问题中提到的电路中,如果我们将输入作为(A=1,B=1,C=0)一起给出,然后在10 ns后将它们一起更改为(A=1,B=0,C=1),那么我们可以看到有一个小故障。这个小故障也会出现在实际的硬件中。但这仅通过非阻塞语句输出(Y)而不是阻塞语句输出(X)在模拟中显示。一旦我们发现一个小故障,我们将采取额外的措施来防止这种情况发生,这样它就不会在硬件中发生


因此,我认为可以安全地得出结论,我们必须对组合块使用非阻塞语句。

我们不应该在组合块中使用非阻塞赋值,因为如果我们使用非阻塞,它将推断设计中的传输延迟,因此我们的结果将永远不会达到我们预期的结果,但是如果我们使用阻塞,这种阻塞将能够抑制设计中的传输延迟,我们可以放心地说,波形中没有小故障。因此,建议我们在组合设计中使用阻塞语句。

相关注意:最新标准是(免费的)。对不起。。我的意思是“那么,我们不应该对处理纯组合逻辑(非顺序/不涉及时钟)的always块中的组合语句使用非阻塞吗?”“我理解你的意思,但我的目的是编写一个最能描述上述电路的代码。如果我使用阻塞语句,它是否会更准确地类似于硬件(因为,将首先确定X1的正确值,然后确定X的值)。如果使用非阻塞