9

在 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?)

PS:在 SystemVerilog 中执行此操作不是一种选择... ;-)

4

2 回答 2

6

要在 Verilog 中执行此操作,您需要使用disable. 我建议完全摆脱watchdog信号,只使用 a 的两个分支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
于 2012-09-11T14:39:24.277 回答
2

fork join只有一个进程,因此您没有并行执行任何操作。

这应该做你想要的:

fork : wait_or_timeout
  begin
    #10_000; //#10ms
    disable wait_or_timeout;
  end
  begin
    @(posedge SIGNAL);
    disable wait_or_timeout;
  end
join
于 2012-09-11T14:38:44.280 回答