For last 2 days I was busy making an understanding about
inheriting/handling and overriding parametrized classes. I have noted some
important things which we may overlook. I hope this will prove useful to us J
Following are the points to note while using parametrized
classes in uvm (Can also be useful in pure systemverilog).
1)
While defining a parametrized class make sure
to use either one of following macros
a. `uvm_component_param_utils
b. `uvm_object_param_utils
2)
While extending a parametrized class, make
sure that the extended class is also parametrized. For example there are
three classes, class fruit, class apple and class orange. Apple extends from
fruit and orange extends from apple. Then they should be extended as following.
class fruit#(int PRICE =
32) extends uvm_component
class apple#(int PRICE =
32) extends fruit#(PRICE)
class orange#(int PRICE =
32, int QNTTY=1) extends apple#(PRICE)
3)
Macros `uvm_component_param_utils are little
different from the `uvm_component_utils.
a. `uvm_component_utils
assigns ‘type_name’ to a class and also define a function get_type_name() for
that class. (get_type_name() function is the same function which we mostly used
while using `uvm_info macro)
b. `uvm_component_param_utils
does not define ‘type_name’ or get_type_name() function. It should be
defined manually else whenever we use get_type_name() it will not give
expected string.
c. ‘type_name’
and get_type_name() are also important while looking up factory using
get_name()
1 //file name : parametrized_class_uvm_example.sv 2 package my_pkg; 3 import uvm_pkg::*; 4 `include "uvm_macros.svh" 5 6 class fruit#(int PRICE = 32) extends uvm_component; 7 `uvm_component_param_utils(fruit#(PRICE)id) 8 const static string type_name = {"fruit #(",$psprintf("%0d",PRICE),")"}; 9 virtual function string get_type_name (); 10 return type_name; 11 endfunction 12 13 function new(string name, uvm_component parent); 14 super.new(name,parent); 15 endfunction : new 16 task run_phase (uvm_phase phase); 17 `uvm_info(get_type_name(),"run_phase: Executing. fruit run_phase<<<<",UVM_LOW) 18 `uvm_info(get_type_name(),$psprintf("run_phase: Executing. fruit run_phase<<<<, PRICE=%0d",PRICE),UVM_LOW) 19 endtask : run_phase 20 function print_val(); 21 `uvm_info(get_type_name(),$psprintf("print_val: Executing. print_val run_phase<<<<, PRICE=%0d",PRICE),UVM_LOW) 22 endfunction 23 endclass : fruit 24 25 class apple#(int PRICE = 32) extends fruit#(PRICE); 26 `uvm_component_param_utils(apple#(PRICE)) 27 const static string type_name = {"apple #(",$psprintf("%0d",PRICE),")"}; 28 virtual function string get_type_name (); 29 return type_name; 30 endfunction 31 function new(string name, uvm_component parent); 32 super.new(name,parent); 33 endfunction : new 34 task run_phase (uvm_phase phase); 35 `uvm_info("UVC","run_phase: Executing. Apple run_phase<<<",UVM_LOW) 36 `uvm_info("UVC",$psprintf("run_phase: Executing. Apple run_phase<<<<, PRICE=%0d",PRICE),UVM_LOW) 37 endtask : run_phase 38 endclass : apple 39 40 class orange#(int PRICE = 32, int QNTTY=1) extends apple#(PRICE); 41 42 `uvm_component_param_utils(orange#(PRICE,QNTTY)) 43 const static string type_name = {"orange #(",$psprintf("%0d",PRICE),")"}; 44 virtual function string get_type_name (); 45 return type_name; 46 endfunction 47 function new(string name, uvm_component parent); 48 super.new(name,parent); 49 endfunction : new 50 task run_phase (uvm_phase phase); 51 `uvm_info(get_type_name(),$psprintf("run_phase: Executing. Orange run_phase<<<<, PRICE=%0d, QNTTY=%0d",PRICE,QNTTY),UVM_LOW) 52 print_val(); 53 endtask : run_phase 54 endclass : orange 55 56 class my_testbench extends uvm_component; 57 `define FRUIT_PRICE 22 58 fruit#(`FRUIT_PRICE) my_uvc; 59 `uvm_component_utils(my_testbench) 60 61 function new(string name, uvm_component parent); 62 super.new(name, parent); 63 endfunction : new 64 function void build_phase(uvm_phase phase); 65 super.build_phase(phase); 66 fruit#(`FRUIT_PRICE)::type_id::set_type_override(orange#(`FRUIT_PRICE,2)::get_type()); //Replace fruit with pine 67 my_uvc=fruit#(`FRUIT_PRICE)::type_id::create("my_uvc",this); 68 endfunction : build_phase 69 70 task run_phase (uvm_phase phase); 71 `uvm_info("TESTBENCH","run_phase: Executing. Testbench run_phase<<<<",UVM_LOW) 72 endtask : run_phase 73 endclass : my_testbench 74 endpackage : my_pkg 75 76 module top; 77 import uvm_pkg::*; 78 `include "uvm_macros.svh" 79 import my_pkg::*; 80 81 my_testbench testbench; 82 83 initial begin 84 $display("******Start of Sim w/ the kids*******************"); 85 testbench = my_testbench::type_id::create("testbench",null); 86 run_test(); 87 end 88 endmodule : top
If you are using synopsys tool, your VCS_HOME, UVM_HOME and license file are pointing
to correct locations then you can also simulate this using following command :
vcs -sverilog +incdir+$UVM_HOME $UVM_HOME/uvm_pkg.sv
-ntb_opts uvm-1.1 -R +vcs+lic+wait parametrized_class_uvm_example.sv