Driver Response to Sequence

Write the driver code for a driver that needs to send packets immediately every time it sees something from the sequencer, and move on if nothing is there. The driver should simultaneously be checking for responses from the DUT and match that response to one of the previously driven packets. Send the response back to the sequence.

class my_driver extends uvm_driver#(my_tx);

  virtual my_intf vif;
  int id_queue[$];
  function new(string name="",uvm_component parent);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);

    if(!uvm_config_db#(virtual my_intf)::get(this,"","vif",vif))
      `uvm_fatal(get_type_name(),"Virtual interface not found")


      endfunction


      task run_phase(uvm_phase phase);

    forever begin

      fork

        begin
          seq_item_port.get_next_item(req);
          id_queue.push_back(req.id);
          drive_tx(req);
          seq_item_port.item_done();

        end


        begin

          @(posedge vif.clk);
          if(vif.valid==1) begin

            my_tx rsp = my_tx::type_id::create("rsp")
            rsp.id = vif.id;
            foreach(id_queue[i]) begin
              if(rsp.id == id_queue[i].id)begin
                rsp  = id.queue[i];
                id_queue.delete(i);
                break;
              end

            end
            seq_item_port.item_done(rsp);
          end
        end

        end

        endtask


        endtask

Is my solution correct for this question?

Item done will also send the response but you can make use of get_response and rsp_port,

Since here you are using fork join and calling item done 2 times if the 1st thread is doing something but your second thread might end the item in one clock ignoring main threads completion.

So, should I not use fork…join in this case? What other methods I can use? Also, would using get() and put() a better option to send response to the sequence?

1 Like

If your agent and sequences behave like slave vip,
Then i think better collect the response 1st from the monitor and then drive something based on that use rsp_export and connect your monitor analysis port.

What is not clear to me, have you an in-order behavior or a pipelined or out-of-order-behavior.
If you have an in-order behavior you do not need a fork/join.

Have to model in-order behavior. My main issue is, which methods to use in the driver to send a response to the sequencer. Should I use get() and put()?

Your driver code should look like this:
task run_phase(uvm_phase phase);

forever begin
      my_tx rsp = my_tx::type_id::create("rsp");
      seq_item_port.get_next_item(req);
      drive_tx(req);
  // assign tghe rsp data fields
   rsp.set_id_info(req);   // Copying the req id to the rsp id
      seq_item_port.item_done(rsp);  // sending back the rsp to
				 // the sequence

    end

endtask

1 Like