Small example of a reentrant task usage.

From: Adam Krolnik (krolnik@lsil.com)
Date: Thu Sep 07 2000 - 11:51:59 PDT


Here is a small, simple reentrant task usage.

Yes, (as with simple examples) there are other ways.

<p> Adam Krolnik
    Verification Mgr.
    LSI Logic Corp.
    Plano TX. 75074

// Small example of a reentrant task. A task is defined that consumes time
// to generate the actual stimulus. Multiple calls may occur to generate overlapped
// transactions.

module test;

  initial begin

    ...

<p>// Execute 2 writes with varied spacing. Check data after...
  for(i=0; i < 30; i = i + 1)
        begin
        fork
          begin // Start in the middle of the range.
          repeat (MIDDLE) @(posedge clk);
          newdata = gendata();
          do_write(mid_addr, newdata);
      end
        
          begin // Do the variable timing write.
          repeat (i) @(posedge clk);
          secdata = gendata();
          do_write(fir_addr, secdata);
          end
        join

        repeat (5) @(posdege clk);
        do_read(fir_addr, actdata);
        checkdata(actdata, secdata,
                          "Wrong data returned for first sweep address.");

        do_read(mid_addr, actdata);
        checkdata(actdata, newdata,
                          "Wrong data returned for second sweep address.");

        repeat (10) @(posedge clk); // Delay a bit until next iteration.
        end

  end

  // A task to do a write on the bus. Allow multiple task calls to overlap each other.
  // Overlap on the second half of the transaction being done.
  task automatic do_write;
        input [31:0] address, data;
        begin
        // necessary declarations.
    bus_req = 1;

        // Ensure two tasks not starting at same time. And request bus too.
        while (in_addr != 0)
          begin
          @(posedge clk)
          bus_req <= #0 1;
          end
        in_addr = 1;

        // Request the bus, wait for grant before proceeding.
        while (!bus_gnt) begin @(posedge clk); end
        // Got grant, stop requesting bus,
        bus_req <= 0;

        // Drive transaction onto bus.then allow next transaction to start.
        bus_addr <= address;
    bus_type <= WRITE;
    bus_data <= data;
    @(posedge clk) in_addr = 0;
        #0; // Allow other tasks to startup.

        while (!bus_done) begin @(posedge clk); end
        bus_data <= 'bz;
        
        end
  endtask // do_write
  
        
  // Do reads on the bus. Similar structure as write task.
  task automatic do_read;
        input [31:0] address;
         output [31:0]data;
        begin
    bus_req = 1;

        // Ensure two tasks not starting at same time. And request bus too.
        while (in_addr != 0)
          begin
          @(posedge clk);
          bus_req <= #0 1;
          end
        in_addr = 1;

        // Request the bus, wait for grant before proceeding.
        while (!bus_gnt) begin @(posedge clk); end
        // Got grant, stop requesting bus,
        bus_req <= 0;

        // Drive transaction onto bus.then allow next transaction to start.
        bus_addr <= address;
    bus_type <= READ;
    @(posedge clk) in_addr = 0;

        #0; // Allow other tasks to startup.
        while (!bus_done) begin @(posedge clk); end
        data = bus_data;
        end
  endtask // do_read
        

endmodule

        
        
  
        



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:54:13 PDT and
sponsored by Boyd Technology, Inc.