日常记录(74)其它
约束重载
- 约束的定义:constraint name{},如果是想分布的,用dist就可以。
- 约束的重载是把类继承一下,被继承了然后覆盖约束,用子类完成功能调用。
module taa ();
class con_base;
rand int a;
rand int b;
constraint a_b{
a dist{0:=4, 1:= 1};
b dist{0:=2, 1:= 2};
}
function void print();
$display("a is %d, b is %d", a, b);
endfunction: print
endclass
class con_custom extends con_base;
constraint a_b{
a ==1;
b ==2;
}
function void print();
super.print();
endfunction: print
endclass: con_custom
initial begin
con_base cons_inst = new();
con_custom cust_inst = new();
cust_inst.randomize();
cust_inst.print();
cust_inst.randomize();
cust_inst.print();
cust_inst.randomize();
cust_inst.print();
cust_inst.randomize();
cust_inst.print();
cust_inst.randomize();
cust_inst.print();
end
endmodule
输出结果:
a is 1, b is 2
a is 1, b is 2
a is 1, b is 2
a is 1, b is 2
a is 1, b is 2
工厂类的重载
- set_type_override等的方法,是继承父类实现子类,然后重载最终以父类形式调用了子类。约束本身也可以被重载(soft)
- 一般的uvm方法是有virtual的,但是没有就一定要加,都加也更保险一些,否则无法完成重载。
- set_type_override等的方法,需要在实例化以前被调用,才能实现重载功能,否则uvm_top.print_topology();看不到效果,虽然print_override_info可以看到效果。
module tbb ();
import uvm_pkg::*;
class source extends uvm_component;
`uvm_component_utils(source)
function new(string name="source", uvm_component parent);
super.new(name, parent);
endfunction: new
virtual function void print();
`uvm_info("SOURCE", $sformatf("source print"), UVM_LOW)
endfunction: print
endclass: source
class target extends source;
`uvm_component_utils(target)
function new(string name="target", uvm_component parent);
super.new(name, parent);
endfunction: new
function void print();
`uvm_info("TARGET", $sformatf("target print"), UVM_LOW)
endfunction: print
endclass: target
class my_test extends uvm_test;
`uvm_component_utils(my_test)
source s;
target t;
function new(string name="my_test", uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
set_type_override_by_type(source::get_type(), target::get_type());
s = source::type_id::create("s", this);
t = target::type_id::create("t", this);
uvm_top.print_topology();
print_override_info("source");
endfunction: build_phase
function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
s.print();
t.print();
endfunction:start_of_simulation_phase
task run_phase(uvm_phase phase);
s.print();
t.print();
endtask: run_phase
endclass: my_test
initial begin
run_test("my_test");
end
endmodule
输出结果:
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
----------------------------------
Name Type Size Value
----------------------------------
uvm_test_top my_test - @335
s target - @348
t target - @357
----------------------------------
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_factory.svh(1786) @ 0: reporter [UVM/FACTORY/DUMP]
#### Factory Override Information (*)
Given a request for an object of type 'source' with an instance
path of 'uvm_test_top' the factory encountered
the following relevant overrides. An 'x' next to a match indicates a
match that was ignored.
Original Type Instance Path Override Type
------------- ------------- -------------
source
* target <type override>
Result:
The factory will produce an object of type 'target'
(*) Types with no associated type name will be printed as <unknown>
####
UVM_INFO tbb.sv(22) @ 0: uvm_test_top.s [TARGET] target print
UVM_INFO tbb.sv(22) @ 0: uvm_test_top.t [TARGET] target print
UVM_INFO tbb.sv(22) @ 0: uvm_test_top.s [TARGET] target print
UVM_INFO tbb.sv(22) @ 0: uvm_test_top.t [TARGET] target print
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 8
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[RNTST] 1
[TARGET] 4
[UVM/FACTORY/DUMP] 1
[UVM/RELNOTES] 1
[UVMTOP] 1
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time 0
uvm的create_object_by_name
在定义该class以后,编译的阶段(程序还没开始运行,没有发生任何调用),my_driver对应的get函数就被调用了,由于刚调用的时候,me还是空的,就进入到分支中,创建了me。这个me只是一个registry类的实例,里面有一个指针inst和一个名称Tname。该类被放置到global_tab中。使用的时候,取出来工厂类的inst的部分,然后给它new出来,得到了对象。
因此:在uvm的实现中,任何component既然注册,意思就是创建了一个工厂类的实例,但是里面的class类型T,虽然被指定,但是没有实例,是在运行时调用对应的方法实现的实例。
uvm的factory机制:
class registry#(type T=uvm_object, string Tname="");
T inst;
string name = Tname;
endclass
class my_driver
typedef registry#(my_driver, "my_driver") this_type;
local static this_type me = get();
static function this_type get();
if(me == null) begin
me = new();
global_tab[me.name] = me;
end
return me;
enfunction
endclass
function uvm_component create_component_by_name(string name)
registry#(uvm_object, "") me_ptr;
me_ptr = global_tab[name];
me_ptr.inst = new("uvm_test_top", null);
return me_ptr.inst;
endfunction
定义和使用:
function uvm_object uvm_factory::create_object_by_name (string
requested_type_name,
string parent_inst_path="",
string name="");
一般只使用第一个参数:
my_transaction tr;
void'($cast(tr, factory.create_object_by_name("my_transaction")));
回调函数
我这个只能在uvm1.1上用
开发者
- 定义A(回调类),定义A_pool(回调池)、定义组件如my_comp(调用回调的组件)。
- 其中的A包括了回调函数,A_pool中有组件和回调类,组件中注册了回调类,然后使用uvm_do_callback宏,完成回调功能。
使用者 - 从回调类A中继承,定义子类,实现方法即可。使用者在使用组件的时候,顺便实例化回调的子类,加入到池子中(带入组件和回调类),就可以完成回调的实现。
module tcc ();
import uvm_pkg::*;
typedef struct {
string a;
int b;
} my_trans;
typedef class my_comp;
class A extends uvm_callback;
`uvm_object_utils(A);
virtual task pre_trans(my_comp comp, ref my_trans tr);
endtask
endclass: A
typedef uvm_callbacks#(my_comp, A) A_pool;
class my_comp extends uvm_component;
`uvm_component_utils(my_comp)
`uvm_register_cb(my_comp, A)
function new(string name="my_comp", uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction: build_phase
task run_phase(uvm_phase phase);
my_trans tr= '{"hahaha", 345};
repeat (3) begin
`uvm_do_callbacks(my_comp, A, pre_trans(this, tr));
`uvm_info("COMP_TR", $sformatf("%s, %d", tr.a, tr.b), UVM_LOW)
end
endtask: run_phase
endclass: my_comp
//-------------------------------------------------------------------------------
class my_callback extends A;
`uvm_object_utils(my_callback)
task pre_trans(my_comp comp, ref my_trans tr);
tr.a = "123";
tr.b = 12;
`uvm_info("CB", $sformatf("callback is here."), UVM_LOW)
endtask: pre_trans
endclass: my_callback
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_callback my_cb;
my_comp comp;
function new(string name="my_test", uvm_component parent);
super.new(name, parent);
endfunction: new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
my_cb = my_callback::type_id::create("my_cb");
comp = my_comp::type_id::create("comp", this);
A_pool::add(comp, my_cb);
endfunction: build_phase
endclass: my_test
initial begin
run_test("my_test");
end
endmodule
输出结果:
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tcc.sv(44) @ 0: reporter [CB] callback is here.
UVM_INFO tcc.sv(31) @ 0: uvm_test_top.comp [COMP_TR] 123, 12
UVM_INFO tcc.sv(44) @ 0: reporter [CB] callback is here.
UVM_INFO tcc.sv(31) @ 0: uvm_test_top.comp [COMP_TR] 123, 12
UVM_INFO tcc.sv(44) @ 0: reporter [CB] callback is here.
UVM_INFO tcc.sv(31) @ 0: uvm_test_top.comp [COMP_TR] 123, 12
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 7
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[CB] 3
[COMP_TR] 3
[RNTST] 1
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_root.svh", line 439.
$finish at simulation time 0
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!