通过阻塞赋值和竞争推断出的寄存器 [英] register inferred by blocking assignment and races

查看:30
本文介绍了通过阻塞赋值和竞争推断出的寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 verilog 的新手,对以下代码中的竞争条件有疑问,该代码取自 Pong P. Chu 的 Veriloog 示例的 FPGA Prototyping.代码是:

I am new to verilog and have a doubt concerning the race conditions in the following code which is taken from FPGA Prototyping by Veriloog Examples by Pong P. Chu. The code is:

always @(posedge clk)
a = b;
always @(posedge clk)
b = a;

这将根据首先执行哪个 always 块来推断竞争.但始终块应该并行执行.如果我错了,请纠正我.我知道存在阻塞赋值,但它如何影响块的第一个语句,即 always 语句?使用非阻塞赋值的第二个代码是:-

This will infer races depending on which always block gets executed first. But always blocks should get executed in parallel. Correct me if I am wrong. I know there is blocking assignment but how does it affect the first statement of the block, which is the always statement? The second code using the non-blocking assignment is:-

always @(posedge clk)
begin //b(entry) = b
a <= b; //a(exit) = b(entry)
end //a = a(exit)

always @(posedge clk)
begin //a(entry) = a
b <= a; //b(exit) = a(entry)
end //b = b(exit)

根据书中的说明,这可以正常工作,但我不明白为什么?是不是因为非阻塞赋值,在这种情况下always块是并行执行的?

This will work fine according to the book but I couldn't understand why? Is it because the always blocks are executed in parallel in this case because of non-blocking assignment?

推荐答案

由于 Verilog分层事件队列"具有不同的区域,所使用的赋值运算符类型会影响代码的执行方式.详细信息可以在 IEEE Verilog 标准的第 5 节中找到,但就您的问题而言,大致可以归结为:

Because the Verilog "stratified event queue" has different regions, the type of assignment operator used makes a difference in how the code is executed. The details can be found in section 5 of the IEEE Verilog standard, but in terms of your question, it boils roughly down to this:

  • 阻塞赋值(在你的第一个例子中)被立即评估,即当它们所在的 always 块被激活时.由于两个块是并行的,它们的激活顺序是不确定的.

  • The blocking assignments (in your first example) are evaluated immediately, i.e. when the always block they're in is activated. Since both blocks are parallel, order of their activation is undefined.

非阻塞赋值不会立即执行,而是在同一时间步的所有块执行完毕后调度.

The non-blocking assignments are not executed immediately but rather scheduled after all blocks of the same time step have finished executing.

因此,当遇到 clk 上升沿时,在您的第一个示例中,模拟器会

So when encountering a rising clk edge, in your first example a simulator would

  1. always 块中随机选择一个
  2. 发现该赋值是阻塞赋值并立即执行它,因此更改该赋值中的左侧变量.
  3. 选择另一个 always 块并执行相同操作,此时第一个变量的值已经更改.
  1. Pick at random one of the always blocks
  2. Find that the assignment is a blocking one and execute it immediately, therefore changing the left-hand variable in that assignment.
  3. Pick the other always block and do the same, at which point the value of the first variable was already changed.

在您的第二个示例中,模拟器将

In your second example, the simulator would

  1. always 块中随机选择一个
  2. 发现分配是非阻塞的,因此
  3. 评估 = 符号的右侧,并将它在那里找到的值安排为一个非阻塞分配更新事件到 = 左侧的变量.
  4. 选择另一个 always 块并执行相同的操作.请注意,这两个变量仍然具有 clk 上升沿之前的值.
  5. 由于所有块都执行完毕,更新所有为非阻塞分配更新事件安排的变量,有效地交换它们的值.
  1. Pick at random one of the always blocks
  2. Find that the assignment is a non-blocking one and therefore
  3. evaluate the right-hand side of the = sign and schedule the value it found there as a non-blocking assign update event to the variable left of the =.
  4. Pick the other always block and do the same. Note that both variables still have their values from before the rising clk edge.
  5. Since all blocks are done executing, update all variables which were scheduled for non-blocking assign update events, effectively swapping their values.

这篇关于通过阻塞赋值和竞争推断出的寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆