UVM Driver

The muscular arm of the testbench. It pulls transactions from the sequencer and drives them to the DUT signals.

Structure

Inherits from uvm_driver #(ITEM_TYPE). It connects to the sequencer via seq_item_port.

class my_driver extends uvm_driver #(my_transaction);
    `uvm_component_utils(my_driver)
    virtual my_if vif; // Virtual Interface

    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_if)::get(this, "", "vif", vif))
            `uvm_fatal("NO_VIF", "Virtual interface not found!")
    endfunction

    task run_phase(uvm_phase phase);
        forever begin
            seq_item_port.get_next_item(req); // Get transaction
            drive(req);                       // Drive signals
            seq_item_port.item_done();        // Acknowledge completion
        end
    endtask

    task drive(my_transaction tr);
        @(posedge vif.clk);
        vif.data <= tr.data;
        vif.valid <= 1'b1;
    endtask
endclass

Key Handshake

  • get_next_item(req): Blocks until the sequencer provides a transaction.
  • item_done(): Tells the sequencer "I finished this item". This unblocks the sequence to send the next one.