在verilog中实现硬件:= vs< =

时间:2017-11-21 08:10:41

标签: verilog hardware operator-keyword

假设我在Verilog中有以下代码:

module A (clk,a,c);

input clk;
input a;
output c;

wire clk;
wire a;
reg c;
reg b;

always @(posedge clk)
begin
   b = a;
   c = b;
end

endmodule

让我们假设这个模块实现了一些Flip Flop,它有两个输入(a和clk)并且有一个输出(c)

我已经读过operator =和operator< =之间的主要区别在于当使用operator =时,命令是按顺序依次执行的(意思是:b得到a和c的值得到了b)的值,当使用运算符< =命令在同一时间执行时(意思是:b得到a的值,c得到b的值)。

现在,我的问题是:

我可以说,如果我们使用operator =然后b得到a的新值,c得到b的旧值(当前一个时钟周期内的值) 如果我们使用运算符< =然后b得到a的新值,c也得到a的新值?

不知何故,这对我来说是有意义的,但在这两种情况下,c的值应该是当前时钟周期中收到的a,这是一个总是阻塞意义

谢谢你, 迈克尔

2 个答案:

答案 0 :(得分:0)

Verilog模拟由与事件相关的微步(或delta周期)组成。事件实际上是变量值的任何变化,导致重新评估其他块。因此,增量循环是一个需要模型静止的步骤。

增量循环本身由多个调度桶组成,在循环中一个接一个地执行。在非常简化的视图中,至少有一个阻塞桶和非阻塞桶。所有阻塞分配都在第一个桶中进行评估,所有阻塞分配都在第二个桶中进行评估。

所以,在你的情况下

always @(posedge clk)
begin
   b = a;
   c = b;
end

b在第一个广告资源中得到评估,c也是如此,因此它变为a的值。因此,a为1,则b的值为1,第一个存储区中的值c也将变为“1”。

你使用非阻塞分配,verilog将在第一个桶中运行,但它只会安排在第二个桶中执行非阻塞分配。所以,在这段代码中

always @(posedge clk)
begin
   b <= a;
   c <= b;
end

b将被安排在第二个桶中获得a int的值,c将被安排在第二个桶中成为b的值。但是后者安排分配当前值b而不是将在第二个桶中评估的值。

因此,在上述情况下,a的值为1,b的值为0,c将在第二个存储桶中变为 0

当然,如果c导致更多第一桶类型的事件,则verilog将返回第一个存储桶并再次评估所有事件。实际上,在verilog中有超过2个桶,在系统verilog中有更多桶。

使用阻止和非阻塞分配以及为什么它们存在于verilog中有一定的推理。但为简单起见,您应该遵循一个简单的方法:所有输出状态元素,如触发器和锁存器必须使用非阻塞分配进行分配,所有组合逻辑和时钟都应使用阻塞分配。这样可以避免对种族和毛刺效应进行整齐的调试。因此,在您的情况下,假设b只是翻牌中的中间节点,应使用以下代码:

always @(posedge clk)
begin
   b = a;
   c <= b;
end

在这种情况下,b将在第一个桶中立即变为a的值,但是根据该阻塞分配,将使用非阻塞分配来分配此触发器c的输出。全行业的方法论,

答案 1 :(得分:0)

当您使用阻塞分配时,块中的引用(读取)与赋值(写入)的顺序会对其实现产生影响。在您的示例中,您对b进行了写入,然后将其读取。所以b本质上是一个表示组合逻辑的临时变量。但是如果你在变量写入块之前读取变量,则可以获得上一个循环中的值;触发器的输出。

使用非阻塞分配时,顺序不再重要 - 您始终从上一个循环中获取值。这就是为什么当一个块写入时有多个始终为@(posedge clock)且其他块读取相同变量时必须使用非阻塞赋值的原因,您总是从上一个循环中获取值。如果您要使用阻塞分配,则在模拟中,读取和写入之间没有保证的顺序。