Search code examples
taskforkverilog

Use of Fork-Join in Verilog


I would like to do a task that checks in parallel one of the two statements commented below and that doesn't break the execution of the program that follows it: The Task checks if startTx has been generated. It must wait for startTx signal 5 clock cycles. If the startTx is asserted, it prints a successful message. If not (after the timeout), it prints an error message and increases the error counter.

What I've done so far is:

    task checkStart;
      begin
      fork
    // evento 1
        begin
          waitCycles(5); // timeOut
          $display("[Error! %t] Time Out has been reached", $time);
          errors = errors + 1;
        end
    // evento 2
        begin 
          @(posedge(startTx))
          $display("[Info] startTx has been generated successfully"); 
        end
      join
      disable fork; 
      end
    endtask

But doesn't seem to be working as it apparently checks for both statements to be true and I would like something as 'join_any' from SystemVerilog that breaks whenever one of both statements become true.


Solution

  • This works without using the SystemVerilog join_any. Comment startTx or uncomment it to see the two conditions that occur.

    module tb ();
    
      bit SIGNAL;
      bit startTx;
    
      int errors;
      
      task checkStart;
        fork
          // evento 1
          begin  : timeout
          #500; // timeOut
          $display("[Error! %t] Time Out has been reached", $time);
          errors = errors + 1;
          $finish;
          end
        // evento 2
        begin  :wait_for_signal
          @(posedge(startTx))
          $display("[Info] startTx has been generated successfully"); 
          disable timeout;
        end
         //
        join
        //  
        $display("+++++ Finished checkStart ++++++");
      endtask  
            
    initial
     begin
       checkStart();
        // Do something else
        #20;
        $display("**** normal finish ****");
        $finish;   
     end
      
    initial
      begin
        #1;
        // coment one of these at a time
        //startTx = 1;
        startTx = 0;
      end
    
    endmodule