my_randomizeを使う
1)、始めに
ModelSim AEでOVMを使うと、SystemVerilogのrandomize関数は使えません(ModelSim AEではサポートしていないので)。
randomize関数が使えないと、シーケンスの中で`ovm_doマクロが使えないのです。
2)、`ovm_doマクロ定義の変更
そこで、`ovm_doマクロの定義部分(src/macros/ovm_sequence_define.svhの242行~258行)を変更していきます。
// MACRO: `ovm_do
//
// This macro takes as an argument a ovm_sequence_item variable or object.
// ovm_sequence_item's are randomized _at the time_ the sequencer grants the
// do request. This is called late-randomization or late-generation.
// In the case of a sequence a sub-sequence is spawned. In the case of an item,
// the item is sent to the driver through the associated sequencer.
`define ovm_do(OVM_SEQUENCE_ITEM) \
begin \
`ovm_create(OVM_SEQUENCE_ITEM) \
start_item(OVM_SEQUENCE_ITEM); \
if(!OVM_SEQUENCE_ITEM.randomize()) begin \
ovm_report_warning("RNDFLD", "Randomization failed in ovm_do action"); \
end \
finish_item(OVM_SEQUENCE_ITEM); \
end
この中で OVM_SEQUENCE_ITEM.randomize() の部分がエラーになるので、次のように`ifdef/`else/`endifを使って変更します。
`ifdef QUESTA_SIM \
if(!OVM_SEQUENCE_ITEM.randomize()) begin \
`else \
if(!OVM_SEQUENCE_ITEM.my_randomize()) begin \
`endif \
これで`QUESTA_SIMマクロが定義されていれば、OVM_SEQUENCE_ITEM.my_randomize() が呼ばれるようになります。
3)、ovm_sequence_itemクラスにmy_randomize関数を追加
ovm_sequence_itemクラス(src/methodology/sequences/ovm_sequence_item.svh)にmy_randomize関数を追加します。
virtual function int my_randomize;
$display("ovm_sequence_item:my_randomize");
return 1;
endfunction : my_randomize
my_randomize関数は、戻り値がint型でvirtualな関数とします。
4)、例題で試してみる
では、例題(examples/sequence/simpleディレクトリ)で試してみましょう。
sim_itemクラス(sim_item.sv)にも my_randomize関数 を追加します。
function int my_randomize;
$display("simple_item : my_randomize");
return 1;
endfunction : my_randomize
シミュレーションを実行します。
% sh run_questa
添付(transcript)のようなログが生成されます。randomize関数ではなく、my_randomize関数なのでaddr, data等は初期値のままになっています。これらの値をランダムにしたい場合は、simple_itemクラスのmy_randomize関数の中でシステムタスク($random等)を使って値を設定するようにすれば、それなりにランダム生成ができるようになります。