Verilog相当于“等到......为......”?

时间:2012-09-11 13:01:01

标签: vhdl verilog

在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中执行它不是一个选项......; - )

2 个答案:

答案 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