シーケンサは、uvm_sequenceクラスを継承します。
テンプレートのREQとRSPに指定するクラスは、ドライバと同じモノにします。
そして、new関数とbodyタスクを実装するだけです。
テンプレートのREQとRSPに指定するクラスは、ドライバと同じモノにします。
そして、new関数とbodyタスクを実装するだけです。
`define num_loops 10
// シーケンスクラス
// REQにuvm_sequence_itemクラスを
// RSPにuvm_sequence_itemクラスをテンプレートに
class sequenceA #(type REQ = uvm_sequence_item,
type RSP = uvm_sequence_item)
extends uvm_sequence #(REQ, RSP);
static integer g_my_id = 1; // クラス変数として宣言する
integer my_id;
function new(string name);
super.new(name);
my_id = g_my_id++;
endfunction
// uvm_sequcenceクラスを継承したときは、このタスクを実装する
//
task body();
string prstring;
int ret_data;
REQ req;
RSP rsp;
`uvm_info("sequenceA", "Starting sequence", UVM_MEDIUM)
// `num_loops(10)回、繰り返す。
for(int unsigned i = 0; i < `num_loops; i++) begin
// REQシーケンスの生成
req = new();
// addr, data, op(ライト)を設定する
req.addr = (my_id * `num_loops) + i;
req.data = my_id + i + 55;
req.op = BUS_WRITE;
// 準備ができるまで待つ
wait_for_grant();
// REQシーケンスをドライバに送信する
send_request(req);
// RSPシーケンスをドライバから受信する
get_response(rsp);
// REQシーケンスの生成
req = new();
// addr, data, op(リード)を設定する
req = new();
req.addr = (my_id * `num_loops) + i;
req.data = 0;
req.op = BUS_READ;
// 準備ができるまで待つ
wait_for_grant();
// REQシーケンスをドライバに送信する
send_request(req);
// RSPシーケンスをドライバから受信する
get_response(rsp);
// 比較する
if (rsp.data != (my_id + i + 55)) begin
$sformat(prstring, "Error, addr: %0d, expected data: %0d, actual data: %0d",
req.addr, req.data, rsp.data);
`uvm_error("SequenceA", prstring)
end
end
`uvm_info("sequenceA", "Finishing sequence", UVM_MEDIUM)
endtask // body
endclass
ポイントは、次の3つの部分になります。 // 準備ができるまで待つ
wait_for_grant();
// REQシーケンスをドライバに送信する
send_request(req);
// RSPシーケンスをドライバから受信する
get_response(rsp);
検証、Verification、SystemVerilog、UVM、Unified Verification Methodology