想知道始终阻止事件控制语句的行为:
always @(posedge clk) begin: TEST
...
@(wait_for_signal_from_subsystem);
...
@(wait_for_another_signal_from_subsystem);
...
end
在事件信号进入之前,进程会“卡住”,还是每次clk边缘进入时都会重新启动?
这也是可综合的(Quartus II说是,但还没有模拟......)?这是一个很好的做法,还是有更好的方法解决这个问题?
答案 0 :(得分:1)
是的,正如你所说的那样“卡住”。一次只能激活一个块的“循环”,如果它没有完成循环,它将不会重新进入。
由于块内的等待操作,你试图在那里做的事情可能无法合成。
我不知道你的设计的确切细节,但我会用一个小的有限状态机来处理它。我假设来自子系统的信号并不比时钟快,所以它看起来像是:
always @* begin
if(state_f == `WAIT_FOR_FIRST)
state_nxt = got_first_signal ? `WAIT_FOR_SECOND : `WAIT_FOR_FIRST;
else if(state_f == `WAIT_FOR_SECOND)
state_nxt = got_second_signal ? `DONE_STATE : `WAIT_FOR_SECOND;
else if(state_f == `DONE_STATE)
state_nxt = `WAIT_FOR_FIRST;
else
state_nxt = 2'bxx;
end
always @(posedge clk) begin
state_f <= state_nxt;
end
答案 1 :(得分:1)
假设您正在设计硬件而不是非合成的测试平台代码,这不是一个好的做法,并且可能无法完成您想要的任何操作。
从语言的角度来看,这将进行编译和模拟。 将阻止等待始终块内的事件,而不是在时钟的每个副本上重新启动。我无法为此找到规范参考,但这是我在模拟中观察到的。如果你让它合成没有错误,我很好奇这会合成什么。
如果来自另一个子系统的信号已经在同一个时钟域(与clk
同步),那么你可以在每个时钟边缘检查它的状态,并使用它做一些事情。
always @(posedge clk) begin: TEST
if (the_other_signal == 1'b1) begin
...
end
end
还需要考虑其他一些事项:
clk
异步,那么你有一个时钟域交叉,你需要在看到它之前同步输入信号。