Data items are obtained from the Sequencer and the driver drives them onto the interface conforming to a bus protocol. All driver classes should be extended from
uvm_driver, either directly or indirectly.
In order to create a driver, follow the steps outlined below :
- Derive a driver from
- Declare a virtual interface handle (to connect with DUT) and retrieve the interface object from database
- Obtain the next data item from sequencer
- Execute the item during
run_phase()or other parallel run-time phases detailed in Phases.
Now lets look at an example of a driver.
class my_driver extends uvm_driver #(my_data); `uvm_component_utils (my_driver) virtual dut_if vif; function new (string name, uvm_component parent); super.new (name, parent); endfunction virtual function void build_phase (uvm_phase phase); super.build_phase (phase); if (! uvm_config_db #(virtual dut_if) :: get (this, "", "vif", vif)) begin `uvm_fatal (get_type_name (), "Didn't get handle to virtual interface dut_if") end endfunction task run_phase (uvm_phase phase); super.run_phase (phase); forever begin `uvm_info (get_type_name (), $sformatf ("Waiting for data from sequencer"), UVM_MEDIUM) seq_item_port.get_next_item (data_obj); drive_item (data_obj); seq_item_port.item_done (); end endtask virtual task drive_item (my_data data_obj); // Drive based on bus protocol endtask endclass
Note the following from example shown above :
- Driver is extended from
- A virtual interface handle vif is declared and assigned later in the build_phase().
- Real interface object is retrieved from the database directly into a local variable using
- Get the next data item from sequencer using
- Call drive task to send data in accordance with a bus protocol
- Indicate to the sequencer that the data item has been driven using
The base driver class contains a
uvm_seq_item_pull_port through which it can request for new transactions from the export connected to it. The ports are typically connected to the exports of a sequencer component in the parent class where the two are instantiated.The RSP port needs connecting only if the driver will use it to write responses to the analysis export in the sequencer.
class uvm_driver #(type REQ = uvm_sequence_item, type RSP = REQ) extends uvm_component;
The driver's port and the sequencer's export are connected during the
connect_phase() of an environment/agent class.
virtual function void connect_phase (); m_drv0.seq_item_port.connect (m_seqr0.seq_item_export); endfunction
Refer to Class Definitions to know about method declarations.