在Verilog测试平台中,我正在尝试编写以下行为:
等到事件发生(上升/下降沿)最长时间,即相当于VHDL指令:
wait until <event> for <duration>;
具有以下行为(提醒):
除非我弄错了,否则我在Verilog中找不到与此函数直接等价的东西...所以我尝试了以下代码:
reg watchdog;
// ...
// Set a signal 'watchdog' in background which will be triggered in 10 us.
fork
watchdog <= #10_000 1'b1;
join
// Wait until SIGNAL is set to '1' *OR* watchdog event occurs.
@(posedge SIGNAL or posedge watchdog);
// Reset the watchdog
watchdog <= 1'b0;
此代码完成工作,但最后一条指令不取消或取代fork
指令。因此,在第二次调用此代码时(例如watchdog <= #50_000 1'b1;
),可能会触发第一个watchdog
(不幸的是很快)。
有什么好主意吗? (取消第一个计划fork
的等效或方式?)
P-S:在SystemVerilog中执行它不是一个选项......; - )
答案 0 :(得分:4)
要在Verilog中执行此操作,您需要使用disable
。我建议完全摆脱watchdog
信号,只使用fork
的两个分支。
以下是一个工作示例。请注意,如果该分支成功,则fork的每个分支都会调用disable f
。禁用fork将终止未成功的分支。
module top;
reg signal;
task test();
fork : f
begin
// Timeout check
#10
$display("%t : timeout", $time);
disable f;
end
begin
// Wait on signal
@(posedge signal);
$display("%t : posedge signal", $time);
disable f;
end
join
endtask
initial begin
// test signal before timeout
fork
test;
begin
signal = 0;
#5;
signal = 1;
#5;
signal = 0;
#10;
end
join
// test signal after timeout
fork
test;
begin
signal = 0;
#15;
signal = 1;
#5;
end
join
end
答案 1 :(得分:1)
您的fork join
只有一个进程,因此您没有并行执行任何操作。
这应该做你想要的:
fork : wait_or_timeout
begin
#10_000; //#10ms
disable wait_or_timeout;
end
begin
@(posedge SIGNAL);
disable wait_or_timeout;
end
join