SystemVerilog OOP Mastery · All levels

Parameterized Components and Agents at Scale: Code Examples

Code Examples for Parameterized Components and Agents at Scale.

Code examples

Generic driver and agent parameterized by item type

systemverilog
class generic_driver #(type REQ_T = uvm_sequence_item) extends uvm_driver #(REQ_T);\n  `uvm_component_param_utils(generic_driver #(REQ_T))\n  virtual task run_phase(uvm_phase phase);\n    REQ_T req;\n    forever begin\n      seq_item_port.get_next_item(req);\n      drive_item(req);\n      seq_item_port.item_done();\n    end\n  endtask\nendclass\n\nclass generic_agent #(type REQ_T = uvm_sequence_item) extends uvm_agent;\n  `uvm_component_param_utils(generic_agent #(REQ_T))\n  uvm_sequencer #(REQ_T) seqr;\n  generic_driver #(REQ_T) drv;\n  function void build_phase(uvm_phase phase);\n    super.build_phase(phase);\n    seqr = uvm_sequencer#(REQ_T)::type_id::create("seqr", this);\n    drv  = generic_driver#(REQ_T)::type_id::create("drv", this);\n  endfunction\nendclass

One architecture supports many transaction types while preserving compile-time checks on TLM interfaces.

Protocol-specific typedef aliases for readability

systemverilog
typedef generic_driver #(axi_item) axi_driver_t;\ntypedef generic_agent  #(axi_item) axi_agent_t;\ntypedef generic_driver #(apb_item) apb_driver_t;\ntypedef generic_agent  #(apb_item) apb_agent_t;\n\nclass soc_env extends uvm_env;\n  `uvm_component_utils(soc_env)\n  axi_agent_t axi_agent;\n  apb_agent_t apb_agent;\nendclass

Aliases keep env code readable and make logs/debug messages easier to interpret than long parameterized class names.

Override exact specialization, not generic base template

systemverilog
class monitored_axi_driver extends generic_driver #(axi_item);\n  `uvm_component_utils(monitored_axi_driver)\nendclass\n\nclass axi_perf_test extends uvm_test;\n  `uvm_component_utils(axi_perf_test)\n  function void build_phase(uvm_phase phase);\n    super.build_phase(phase);\n    generic_driver#(axi_item)::type_id::set_type_override(\n      monitored_axi_driver::get_type()\n    );\n  endfunction\nendclass

The override must target `generic_driver#(axi_item)` specifically; `generic_driver#(uvm_sequence_item)` is a different factory type.

Related topics