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。したがって、このコードへの 2 回目の呼び出し (たとえばwatchdog <= #50_000 1'b1;) では、最初の呼び出しwatchdogがトリガーされる可能性があります (残念ながら早すぎます)。

もっと良いアイデアはありますか?(最初の計画をキャンセルする同等または方法のいずれかfork?)

PS:SystemVerilogでそれを行うことはオプションではありません... ;-)

4

2 に答える 2

6

Verilog でこれを行うには、disable. シグナルを完全に取り除き、watchdoga の 2 つのブランチのみを使用することをお勧めしforkます。

以下は実際の例です。fork の各ブランチは、disable fそのブランチが成功した場合に呼び出すことに注意してください。フォークを無効にすると、成功しなかったブランチが終了します。

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プロセスが 1 つしかないため、並行して何も実行していません。

これはあなたが望むことをするはずです:

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 に答える