How do I create a pipelined Driver Sequencer REQ and RSP channel?

In reply to Tudor Timi:

Hi Timi,

This is the original method I had implemented. The problem with this is that calls to the drive_control_cycle() and read_control_cycle() tasks each block for 1 cycle and as such `uvm_do_on_with(ctrl_sequencer) will block for 2 cycles.

I need something more like this for my sequence and the entire sequence (execution of the body) should take one cycle as I need to start sending a REQ again on the next cycle…


virtual task body();
 for (int i = 0; i < max_seq_length; i++)
      begin
         // --- Request to CTRL driver - Tell me what I should do.

         ctrl_req = ctrl_packet::type_id::create("ctrl_req");
         ctrl_rsp = ctrl_packet::type_id::create("ctrl_rsp");

         start_item(ctrl_req, -1, ctrl_seqr); // Needed for calculation of RSP
         finish_item(ctrl_req);

         // --- Calculations based on REQ

         starting_agent    = $urandom_range(num_agents - 1, 0);
         available_credits = BUF_DEPTH - ctrl_req.used_credits;
         num_instructions  = $urandom_range(available_credits, 0);

         if (num_instructions > num_agents) num_instructions = num_agents;

         // --- Response to CTRL driver - Do what you're told to.

         start_item(ctrl_rsp, -1, ctrl_seqr);
         ctrl_rsp.copy(ctrl_req);
         assert(ctrl_rsp.randomize());
         ctrl_rsp.starting_inst = starting_agent;
         ctrl_rsp.number_inst   = num_instructions;
         finish_item(ctrl_rsp);

         // --- Data Sequencer control based off of CTRL request.

         for (int i = starting_agent; i < (starting_agent + num_instructions); i++)
         begin
            int sel = i % num_agents;
            data_packet[sel] = data_packet::type_id::create("data_packet");

            `uvm_info("VSEQUENCE", $sformatf("***** Starting a DATA packet on agent %0d *****", sel), UVM_HIGH)
            fork begin
               start_item(data_packet[sel], -1, data_seqr[sel]);
               assert(data_packet[sel].randomize());
               finish_item(data_packet[sel]);
            end join_none
         end
         wait fork;
      end
endtask : body

The problem here is that finish_item() blocks until the driver calls item_done() so I think I may also need a way for the ctrl_driver to deal with both REQ and RSP’s at the same time and may need (as you mention) a “driver → sequencer response path”.

I am a little confused by this approach but it seems the only option.

Thanks,
Tom