The creation of UV M is inseparable from the three core elements of factory: registration, creation and coverage
`uvm_{component,object}_utils() uvm_{component,object}::type_id::create() uvm_{type,inst}_override{,_by_type}()
Among them, override instance program: override method set by type_ type_ Override to illustrate.
module factory_override; import uvm_pkg::*; `include "uvm_macros.svh" class comp1 extends uvm_component; `uvm_component_utils(comp1) function new(string name="comp1", uvm_component parent=null); super.new(name, parent); $display($sformatf("comp1:: %s is created", name)); endfunction: new virtual function void hello(string name); $display($sformatf("comp1:: %s said hello!", name)); endfunction endclass class comp2 extends comp1; `uvm_component_utils(comp2) function new(string name="comp2", uvm_component parent=null); super.new(name, parent); $display($sformatf("comp2:: %s is created", name)); endfunction: new function void hello(string name); $display($sformatf("comp2:: %s said hello!", name)); endfunction endclass comp1 c1, c2; initial begin comp1::type_id::set_type_override(comp2::get_type()); //comp2 type overrides comp1 type c1 = new("c1"); c2 = comp1::type_id::create("c2", null); c1.hello("c1"); c2.hello("c2"); end endmodule
Output result:
comp1:: c1 is created comp1:: c2 is created comp2:: c2 is created comp1:: c1 said hello! comp2:: c2 said hello!
In the above example code, comp2 type overrides comp1 type
comp1::type_id::set_type_override(comp2::get_type());
Then the c1 and c2 objects are created. From the output result, we can see that the type of c1 is still comp1, and the type of c2 is changed to comp2. This shows that the coverage mechanism of factory will only affect the objects created through the factory method.
So, by type_ The type coverage of ID:: create() and factory can realize the flexible replacement of object types during instantiation. In the above example, there are several hidden key points that readers should pay attention to:
- Before instantiating c2, you should first replace the type of comp1 with comp2. Only after the type replacement is completed first can the factory select the correct type in the later instantiation.
- The above example code better reflects some actual situations. First, when declaring c2, the verifier does not know that there may be coverage in the future, so the type is comp1. After the type replacement occurs later, if the original code is not updated, the type of c2 handle is still comp1, but it points to the object of comp2 type. This requires that * * comp2 should be a subclass of comp1, * * only in this way can the handle point be legal and safe.
- When c2 calls the hello() method, because it is the comp1 type first, it will check the comp1::hello(). Because the method is specified as a virtual function at the time of definition, it passes the polymorphic method call and instead calls the comp2::hello() function. Therefore, the result displayed is also "comp2:: c2 said hello!".
Common errors:
Run the code directly with vcs:
vcs factory_override.sv
source file "uvm_macros.svh" connot be opened for reading due to 'No such file or dictionary'
Need to import UVM Library
Add - ntb_opts uvm parameter, i.e.:
vcs -sverilog -ntb_opts uvm my_file.sv
If simv is generated, the simulation results will be generated.
reference resources: https://blog.eetop.cn/blog-1561828-2331497.html
https://blog.csdn.net/qq_37960317/article/details/117046310
Please correct any mistakes, thank you.