象下面用继承+factory实现callback的方法,导致unmanageable explosion of driver class
class driver extends uvm_driver #(packet);
`uvm_component_utils(driver)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction: new
task main_phase (uvm_phase phase);
forever begin
pre_send(); xxx; send(); xxx; post_send();
end
endtask
virtual task send(packet tr);
...
endtask: send
virtual task pre_send(packet tr);
...
endtask: pre_send
virtual task post_send(packet tr);
...
endtask
endclass
class driver_error extends driver ...
class driver_delay extends driver ...
class driver_delay_error extends driver_error...
其实,uvm callbacks的机制更加灵活,不需要创建大量的OOP hierarchy
1. 在major operation前面/后面插入embeded callback method
class driver extends uvm_driver #(packet);
`uvm_component_utils(driver)
function new(string name, uvm_component parent);
super.new(name, parent)
endfunction: new
`uvm_register_cb(driver, driver_callback);
virtual task main_phase(uvm_phase phase)
forever begin
seq_item_port.get_next_item(req);
...
`uvm_do_callbacks(driver, driver_callback, pre_send(this, req));
send(req)
`uvm_do_callbacks(driver, driver_callback, post_send(this, req));
end
endtask: main_phase
endclass
2. declare façade class
class driver_callback extends uvm_callback;
function new(string name = "driver_callback");
super.new(name);
endfunction: new
virtual task pre_send(driver drv, packet tr); ... endtask
virtual task post_send(driver drv, packet tr); ... endtask // driver: match types in `uvm_do_callbacks
3. Implement callback: Error
class driver_err_callback extends driver_callback;
...
virtual task pre_send(driver drv, packet tr);
...
endtask
endclass
4. create and register callback object in tests
class test extends test_base;
driver_err_callback drv_err_cb;
...
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv_err_cb = new();
uvm_callbacks#(driver, driver_callback)::add(env.agt.drv, drv_err_cb);
uvm_callbacks#(driver, driver_callback)::display() // visually verify the registeration (optional)
endfunction: connect_phase
...
endclass