通过阻止分配和比赛来推断注册

时间:2015-09-03 06:56:25

标签: verilog

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

#include <iostream>
#include <string>
#include <conio.h>

using namespace std;
string name = "";


int main() 
{
    char temp;
    cout << "Enter a string: ";
    for (int i = 0; i < 12; i++) { //Replace 12 with character limit you want
        temp = _getch();
        name += temp;
        cout << temp;
    }
    system("PAUSE");
}

这将推断比赛取决于首先执行块总是执行。但总是块应该并行执行。如果我错了,请纠正我。我知道有阻塞赋值,但它如何影响块的第一个语句,这是始终声明? 使用非阻塞分配的第二个代码是: -

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

根据这本书可以正常工作,但我不明白为什么?是因为在这种情况下,由于非阻塞分配,并行块是并行执行的吗?

1 个答案:

答案 0 :(得分:1)

因为Verilog“分层事件队列”具有不同的区域,所使用的赋值运算符的类型会对代码的执行方式产生影响。细节可以在IEEE Verilog标准的第5部分找到,但就你的问题而言,它大致归结为:

  • 立即评估阻止分配(在第一个示例中),即激活它们所在的always块时。由于两个块都是并行的,因此它们的激活顺序是不确定的。

  • 在同一时间段的所有块完成执行后,非阻塞分配不会立即执行,而是预定

因此,当遇到上升clk边缘时,在第一个示例中,模拟器将

  1. 随机选择一个always
  2. 发现分配是阻塞分配并立即执行,因此更改该分配中的左侧变量。
  3. 选择另一个always块并执行相同的操作,此时第一个变量的值已经更改。
  4. 在你的第二个例子中,模拟器将

    1. 随机选择一个always
    2. 发现作业是非阻止的,因此
    3. 评估=符号的右侧,并将其在此处找到的值作为非阻塞分配更新事件安排到=左侧的变量。
    4. 选择另一个always块并执行相同的操作。请注意,这两个变量的值仍然在上升clk边缘之前。
    5. 由于所有块都已执行,因此请更新为非阻塞分配更新事件安排的所有变量,并有效地交换它们的值。