Mousstix
Mousstix

Reputation: 323

Verilog equivalent of "wait until ... for ..."?

In a Verilog testbench, I'm trying to code the following behavior:

which has the following behavior (reminder):

Unless I'm mistaken, I did not find any direct equivalent of this function in Verilog... So I tried the following code:

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;

This code does the work but the last instruction does not cancel or supercede the fork instruction. So, in a second call to this code (with for example watchdog <= #50_000 1'b1;), the first watchdog may be triggered (too soon unfortunately).

Any better idea? (either an equivalent or a way to cancel the first planned fork?)

P-S : to do it in SystemVerilog is not an option... ;-)

Upvotes: 12

Views: 50582

Answers (2)

Morgan
Morgan

Reputation: 20514

Your fork join only has one process, so you are not doing anything in parallel.

This should do what you want:

fork : wait_or_timeout
  begin
    #10_000; //#10ms
    disable wait_or_timeout;
  end
  begin
    @(posedge SIGNAL);
    disable wait_or_timeout;
  end
join

Upvotes: 4

dwikle
dwikle

Reputation: 6978

To do this in Verilog you need to use disable. I would suggest getting rid of the watchdog signal entirely and just using two branches of a fork.

Below is a working example. Note that each branch of the fork calls disable f if that branch succeeds. Disabling the fork will terminate the branch which did not succeed.

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

Upvotes: 8

Related Questions