🚗 UVM Driver Usage and Adder Example (Updated)#
🚀 Introduction#
The uvm_driver
is a key component in a UVM testbench. It serves as the bridge between the sequencer and the DUT (Design Under Test).
The driver fetches sequence items from the sequencer and applies them to the DUT’s input signals via a virtual interface.
🗂️ What is uvm_driver
?#
- The
uvm_driver
fetches transactions from the sequencer usingget_next_item()
. - It applies the transaction data to the DUT inputs.
- It signals the sequencer when the transaction is complete using
item_done()
. - It uses a virtual interface to connect to the DUT.
- It logs important simulation messages.
📝 Updated Adder Driver Example#
Below is the updated adder_driver
example. This driver fetches adder_transaction
sequence items from the sequencer and drives the DUT via a virtual interface.
class adder_driver extends uvm_driver #(adder_transaction);
virtual adder_if vif;
adder_config cfg;
`uvm_component_utils(adder_driver)
function new(string name = "adder_driver", 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 adder_if)::get(this, "", "vif", vif))
`uvm_fatal("DRIVER", "No virtual interface specified!");
if (!uvm_config_db #(adder_config)::get(this, "", "cfg", cfg))
`uvm_fatal("DRIVER", "No config specified!");
endfunction
virtual task run_phase(uvm_phase phase);
adder_transaction tr;
forever begin
seq_item_port.get_next_item(tr);
// Delay (use config)
repeat(cfg.delay_min + $urandom_range(0, cfg.delay_max - cfg.delay_min)) // wait random delat range define by configuration class
@(posedge vif.clk);
@(posedge vif.clk);
vif.num1 <= tr.num1;
vif.num2 <= tr.num2;
@(posedge vif.clk);
tr.result <= vif.out;
tr.print();
seq_item_port.item_done();
end
endtask
endclass
🔍 Key Points#
Virtual Interface (
vif
): Connects the driver to the DUT’s clock and data ports.build_phase()
: Retrieves and binds the virtual interface viauvm_config_db
.run_phase()
:- Uses
seq_item_port.get_next_item()
to get the next transaction. - Applies inputs (
num1
,num2
) to the DUT. - Waits one clock cycle for DUT computation.
- Captures the result (
vif.out
) and updates the transaction object. - Uses
item_done()
to signal transaction completion.
- Uses
💡 Summary#
🔹 The uvm_driver
applies stimulus from the sequencer to the DUT.
🔹 In this adder example, it sends operand values to the DUT and retrieves the result.
🔹 The virtual interface ensures easy signal access.
🔹 The driver is a core element of a UVM testbench, ensuring accurate stimulus delivery and result collection.