virtual class uvm_sequence #(type REQ = uvm_sequence_item,
                             type RSP = REQ) extends uvm_sequence_base;
  .....
  REQ req;
  RSP rsp;
  .....
endclass: uvm_sequence

class uvm_driver #(type REQ=uvm_sequence_item,
                   type RSP=REQ) extends uvm_component;
  .....
  REQ req;
  RSP rsp;
  .....
endclass: uvm_driver

//Sequence, Sequencer and Driver parameterised with the different sequence_item for request & response
my_sequence extends uvm_sequence #(my_sequence_item1, (my_sequence_item2); // type of req = my_sequence_item1, type of rsp = my_sequence_item2
  .....
  task body();
    // Step 1 - Creation
    req = my_sequence_item1::type_id::create("req"); // type of req = my_sequence_item1
    // Step 2 - Ready - start_item()
    start_item(req);
    // Step 3 - Set
    if(!req.randomize() with {address inside {[0:32'h4FFF_FFFF]};})
    begin
      `uvm_error("body", "randomization failure for req")
    end
    // Step 4 - Go - finish_item()
    finish_item(req);
    // Step 5 - Response - get_response()
    get_response(rsp); // type of rsp = my_sequence_item2
  endtask: body
endclass: my_sequence

class my_driver extends uvm_driver #(my_sequence_item);
  my_interface vif;
  .....
  task run_phase(uvm_phase phase);
    forever
    begin
      seq_item_port.get_next_item(req); // Blocking call returning the next transaction
      @(posedge vif.clk);
      vif.addr = req.address; // vif is the drivers Virtual Interface
      //
      // etc
      //
      // End of bus cycle
      if(req.read_or_write == READ)
      begin // Assign response data to the req fields
        req.rdata = vif.rdata;
      end
      rsp = my_sequence_item2::type_id::create("rsp"); // type of rsp = my_sequence_item2
      req.resp = vif.error; // Assign response to the req_item response field
      seq_item_port.item_done(rsp); // Signal to the sequence that the driver has finished with the item
    end
  endtask: run
endclass: my_driver


class my_sequencer extends uvm_sequencer #(my_sequence_item1, my_sequence_item2);
.....
endclass: my_sequencer


// Agent containing a driver and a sequencer
class my_agent extends uvm_agent;
  my_driver    m_driver;
  my_sequencer m_sequencer;
  my_interface vif;
  my_agent_cfg m_cfg;
  .....
  // Sequencer-Driver connection:
  function void connect_phase(uvm_phase phase);
    if(m_cfg.active == UVM_ACTIVE) // The agent is actively driving stimulus
    begin
      m_driver.seq_item_port.connect(m_sequencer.seq_item_export); // TLM connection
      m_driver.vif = vif; // Virtual interface assignment
    end
  endfunction: connect_phase
endclass: my_agent