我是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;
根据这本书可以正常工作,但我不明白为什么?是因为在这种情况下,由于非阻塞分配,并行块是并行执行的吗?
答案 0 :(得分:1)
因为Verilog“分层事件队列”具有不同的区域,所使用的赋值运算符的类型会对代码的执行方式产生影响。细节可以在IEEE Verilog标准的第5部分找到,但就你的问题而言,它大致归结为:
立即评估阻止分配(在第一个示例中),即激活它们所在的always
块时。由于两个块都是并行的,因此它们的激活顺序是不确定的。
在同一时间段的所有块完成执行后,非阻塞分配不会立即执行,而是预定。
因此,当遇到上升clk
边缘时,在第一个示例中,模拟器将
always
块always
块并执行相同的操作,此时第一个变量的值已经更改。在你的第二个例子中,模拟器将
always
块=
符号的右侧,并将其在此处找到的值作为非阻塞分配更新事件安排到=
左侧的变量。always
块并执行相同的操作。请注意,这两个变量的值仍然在上升clk
边缘之前。