SystemVerilog OOP Mastery · All levels
Callbacks and Policy Classes for Open Extension: Code Examples
Code Examples for Callbacks and Policy Classes for Open Extension.
Code examples
Driver callback hook around pin-driving logic
systemverilog
class drv_cb extends uvm_callback;\n virtual task pre_drive(my_item t); endtask\n virtual task post_drive(my_item t); endtask\nendclass\n\nclass my_driver extends uvm_driver #(my_item);\n `uvm_component_utils(my_driver)\n `uvm_register_cb(my_driver, drv_cb)\n\n virtual task run_phase(uvm_phase phase);\n my_item req;\n forever begin\n seq_item_port.get_next_item(req);\n `uvm_do_callbacks(my_driver, drv_cb, pre_drive(req))\n drive_item(req);\n `uvm_do_callbacks(my_driver, drv_cb, post_drive(req))\n seq_item_port.item_done();\n end\n endtask\nendclassThe driver owns protocol timing; callbacks layer extra actions without creating another driver subclass for each variation.
Policy class used by scoreboard comparison
systemverilog
virtual class compare_policy;\n pure virtual function bit match(my_item exp, my_item got);\nendclass\n\nclass strict_compare_policy extends compare_policy;\n virtual function bit match(my_item exp, my_item got);\n return (exp.addr == got.addr) && (exp.data == got.data);\n endfunction\nendclass\n\nclass masked_compare_policy extends compare_policy;\n bit [31:0] data_mask = 32'hFFFF_FF00;\n virtual function bit match(my_item exp, my_item got);\n return (exp.addr == got.addr) &&\n ((exp.data & data_mask) == (got.data & data_mask));\n endfunction\nendclassThe scoreboard can switch between strict and masked semantics without changing class hierarchy.
Inject policy through config_db in build_phase
systemverilog
class my_scoreboard extends uvm_component;\n `uvm_component_utils(my_scoreboard)\n compare_policy policy;\n\n function void build_phase(uvm_phase phase);\n super.build_phase(phase);\n if (!uvm_config_db#(compare_policy)::get(this, "", "policy", policy))\n policy = strict_compare_policy::type_id::create("policy");\n endfunction\nendclass\n\nclass debug_test extends uvm_test;\n `uvm_component_utils(debug_test)\n function void build_phase(uvm_phase phase);\n compare_policy p;\n super.build_phase(phase);\n p = masked_compare_policy::type_id::create("p");\n uvm_config_db#(compare_policy)::set(this, "env.scb", "policy", p);\n endfunction\nendclassPolicy injection is explicit in hierarchy and can vary per test path, which improves debuggability compared with hidden globals.