对DUT中parameter参数与TB中参数化的类的理解
- DUT:V在定义module时通过parameter关键字定义参数。参数具有默认值,在定义parameter时指定。可以在模块实例化时,通过.parameter(appoint_value)的方式来为模块中的参数进行赋值。如果实例化时不通过此方式指定参数的数值,那么参数会使用默认值。parameter的作用域为整个模块(即module~endmodule)。
//define module and parameter
module adder
#(parameter ADD2=2'd1) //parameter ADD2 default value is 2'd1
(input clk,
input a,
output [3:0]sum
);
always@(*)
begin
sum <= a + ADD2;
end
endmodule
//instance module
module test;
wire [3:0] my_sum;
initial
begin
forever #10 clk = ~clk;
end
adder my_adder
#(.ADD2(2'd2)) //transmit parameter
(.clk(clk),
.a(1'b1)
.sum(my_sum)
);
endmodule
- TB:SV定义参数化的类时,在类声明时定义参数。同样的,参数具有默认值。在类实例化时,可以通过对类中的参数进行赋值(赋值的位置需对应)。在一个参数化的类A中,可以实例化另一个参数化的类B。类A中的参数可以传递给B,这样类B中的参数就引用了A中的类,和A中的参数相同。这种用法通常在具有层级关系的类中(嵌套参数化的类),如agent和driver/monitor/sequencer或者driver/monitor和item/interface组件。
class driver #(int ADDR_WIDTH_1=16) extends uvm_driver;
...
endclass
class agent #(int ADDR_WIDTH_2=16) extends uvm_agent;
driver #(int ADDR_WIDTH_1=16) my_driver;
void function build_phase(uvm_phase phase);
//parameter ADDR_WIDTH_1 equals to ADDR_WIDTH_2
my_driver = driver #(ADDR_WIDTH_2)::type_id::create("my_driver", this);
endfunction
...
endclass
- 两者异同:DUT的parameter和TB中参数化的类非常相似。定义时可以赋默认值,参数的赋值都是在实例化时进行赋值,赋值方式不同。参数的作用域相同,参数可以向包含的子模块/类向下传递。DUT的parameter和TB中参数化的类都是为了模块实例化时可以通过参数进行配置,使模块的实例化更加灵活。