uvm_primer ch13 uvm_env
不要把一段代碼在工程中copy多處
random_test() 和add_test()三種實現方式的對比
最差的結構
好一點的結構
將兩個tester的共用的run_phase()寫到base_tester;這樣run_phase()在base_tester中複用;
然後定義get_op get_data兩個純虛函數,純虛函數會強制在子類重寫
virtual base_tester 是一個虛類 ,只能繼承,不能實例化;
最優結構
add_tester重寫random_tester的get_op函數;並複用random_tester的的get_data函數,因爲兩者是一樣的;
將激勵從component中獨立出來;
separate structure from stimulus;
使用factory來構造component
<variable>=<class_name>::type_id::create("",this);
這個工廠方法有兩個好處,相對於鏈接: uvm_primer ch9.
- 如果要給工廠增加新的類型的話,直接使用
`uvm_component_utils()
和`uvm_object_utils()
- 這個工廠返回對象的類型就是該類型,不需要$cast, ch9 返回的類型是其父類;
tester_h = base_tester::type_id::create("tester_h",this);
base_tester
是一個虛類,但是這裏構造了一個對象;
這裏base_tester是一個佔位符,factory會返回一個base_tester子類的對象;
存在疑問???
class env extends uvm_env;
`uvm_component_utils(env);
base_tester tester_h;
coverage coverage_h;
scoreboard scoreboard_h;
function void build_phase(uvm_phase phase);
tester_h = base_tester::type_id::create("tester_h",this);
coverage_h = coverage::type_id::create ("coverage_h",this);
scoreboard_h = scoreboard::type_id::create("scoreboard_h",this);
endfunction : build_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass
這樣 env中代碼就一樣了,利用多態的特性,如果創建不同的case,在case中指定tester_h 裏邊具體的類型,這樣就不用不同的case有不同的env; 實現了env的複用;
override factory
<base_class_name>::type_id::set_type_override(<child_class_name>::get_type())
static方法set_type_override告訴工廠,當有一個構造base_class_name的申請時,返回一個child_class_name的對象;
random_test就相當於my_case0; 是uvm_test_top;
class random_test extends uvm_test;
`uvm_component_utils(random_test);
env env_h;
function void build_phase(uvm_phase phase);
base_tester::type_id::set_type_override(random_tester::get_type());
env_h = env::type_id::create("env_h",this);
endfunction : build_phase
function new (string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass
在接下來的4個章節中,當在一個複雜的testbench中,各個object之間要進行通信將怎麼處理,會對此進行詳細的描述.