vmm_data中的重要函數有allocate(), compare(), copy(), copy_data(), display(),psdisplay(),
在Packet.sv中添加vmm_log與隨機數據成員,log聲明爲static
定義Packet約束
使用allocate()代替new(),便於重用.
這是一種類似$cast()的處理方法:
例如Generator中
Xaction tr;
function new(...);
endfunction
task run();
tr = new();
assert(tr.randomize());
tr.send();
endtask
這種情況下,如果想在上層test中使用Xaction的派生類My_xaction就不能了,因爲Generator初始化之後,新對象無法賦給tr.一種思路是將tr的初始化放在new()中,但是這樣會導致每次run使用的tr都會指向同樣的tr對象,這並不是期望的結果。可以採用的解決辦法是:
Xaction blueprint;
function new(...);
blueprint = new();
endfunction
task run;
Xaction tr;
if(!$cast(tr, blueprint.allocate())) ...
endtask
這樣很容易使用派生類替換blueprint.
填充copy函數
$cast(dest_var, source_exp);
copy函數的兩種用法:
1. $cast(cbja, objb.copy()); 將obja的內存回收,賦予新內存,再將objb的內存中的內容複製到obja
2. objb.copy(obja); 這樣操作obja的內存仍然存在,將objb的內容複製到obja中。這在以同步/通信爲目的保留資源是會使用到。
通過channel在transaction中傳遞對象`vmm_channel(Packet),建立channel
添加`vmm_atomic_gen(Packet, "Packet Gen"),建立Generator
在build()中將Packet_atomic_gen對象gen中的屬性stop_after_n_insts置爲cfg中的run_for_n_packets
stop_after_n_insts的作用爲生產該值的對象,發送至channel後generator停止,發出vmm_notify::DONE
添加get.out_chan()的sink()方法,丟棄生成的數據,以免堵塞。注意使用該方法後channel常空,不要設法get()
在start()中添加gen.start_xactor();會自動調用main()方法。
在wait_for_end()中等待gen()的結束,在stop()中使用gen的stop_xactor()方法。當調用wait_if_stopped方法和wait_if_stopped_or_empty時,transactor會停止。
從Packet中派生出一個子類,約束其只產生長度爲2~4之間的payload,將對象賦給gen的randomize_obj
這個lab中值得注意的是:約束名一樣時,派生類的約束可以覆蓋基類的約束。這裏採用的是完全覆蓋方式,假如約束valid中約束了a,b兩個rand變量,而派生類的約束valid只約束了b變量,那麼派生類中對象裏的a變量就不會被約束了。