The Universal Verification Methodology (UVM) provides a standardized framework for building robust, reusable testbenches in SystemVerilog.
UVM Architecture Basics
A typical UVM testbench consists of the following components:
- Sequencer: Generates stimulus (
uvm_sequence_item). - Driver: Converts transaction-level stimulus to pin-level toggles.
- Monitor: Observes pin-level activity and converts it back to transactions.
- Agent: Encapsulates the Sequencer, Driver, and Monitor.
- Scoreboard: Compares predicted behavior against actual design outputs.
- Environment: Groups agents, scoreboards, and coverage collectors.
The UVM Phases
UVM executes in a series of predefined phases to ensure components are built and connected before simulation starts:
build_phase: Instantiate components (top-down).connect_phase: Connect TLM ports and exports (bottom-up).run_phase: The main time-consuming simulation phase (task).report_phase: Summarize the results of the test.
Example UVM Class
class my_driver extends uvm_driver #(my_transaction);
`uvm_component_utils(my_driver)
virtual my_if vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
drive_item(req);
seq_item_port.item_done();
end
endtask
task drive_item(my_transaction tr);
// Pin wiggling logic here...
@(posedge vif.clk);
vif.data <= tr.data;
endtask
endclass
Learning UVM requires a shift in thinking from procedural testbenches to object-oriented, transaction-level methodologies.