我知道我应该在顺序总是分配中使用非阻塞分配。但是,我偶然碰巧在我的部分代码中使用阻塞赋值,这里是:
reg tb_strobe = 0;
reg [9:0] tb_strobe_cnt = 0;
reg tb_sync = 0;
always@(posedge tb_clkh)
begin
if (~tb_resetl) begin
tb_strobe <= 0;
tb_strobe_cnt <= 0;
tb_sync <= 0;
end
else begin
if (tb_strobe_cnt == 1022) begin
tb_strobe <= 1;
tb_strobe_cnt <= tb_strobe_cnt + 1;
end else if (tb_strobe_cnt == 1023) begin
tb_strobe <= 0;
tb_strobe_cnt <= 0;
end else begin
tb_strobe <= 0;
tb_strobe_cnt <= tb_strobe_cnt + 1;
end
if (tb_strobe == 1) begin
tb_sync = 1; // <-- this is the mistakenly used blocking assignment
end else begin
end
end
end
然后我的模拟器表现得无法预测,一旦我将该任务修复为非阻塞,它就开始正常工作!!!!
我很好奇以上(在我的具体代码中)出了什么问题? 以我使用它的方式,因为我只在代码中调用 tb_sync 一次,我没想到任何不可预知的行为...... 并且 tb_sync 未在代码中的任何其他位置分配。知道什么是错的吗?
答案 0 :(得分:1)
非阻塞分配用于防止在同一时钟边沿上写入和读取相同变量的多个进程之间的竞争条件。它只需要一个进程写入,另一个进程在同一个时钟边缘读取相同的变量来创建该竞争。您的示例未显示读取 tb_sync 的过程,但我假设该比赛所在的位置。