通过调用start方法启动sequence,该方法接受指向sequencer的指针,sequence_item通过该sequencer发送给driveer。sequencer的指针也通常称为m_sequencer。start方法为m_sequencer分配一个sequencer指针,然后调用body()任务。完成与driver交互的主体任务后,start()方法返回。由于它需要与driver交互,因此start()是一种阻塞方法。
virtual task start ( uvm_sequencer_base sequencer,
uvm_sequence_base parent_sequence = null,
int this_priority = -1;
bit call_pre_post = 1;
对于名为child_seq的sequence,可以如下所示调用start方法:?
assert(child_seq.randomize());
child_seq.start(seqr, parent_seq, priority, call_pre_post);
在sequence执行期间,通过start方法调用以下方法:
?
注:
start方法调用遵循以下顺序:
sub_seq.pre_start()
sub_seq.pre_body() if call_pre_post==1
parent_seq.pre_do(0) if parent_sequence!=null
parent_seq.mid_do(this) if parent_sequence!=null
sub_seq.body YOUR STIMULUS CODE
parent_seq.post_do(this) if parent_sequence!=null
sub_seq.post_body() if call_pre_post==1
sub_seq.post_start()
为了清楚地理解它,base_seq及其派生序列child_seq是用定义的所有方法编写的。
下面仅显示base_seq和child_seq序列。完整的代码可以在可执行链接中找到。?
class base_seq extends uvm_sequence #(seq_item);
seq_item req;
`uvm_object_utils(base_seq)
function new (string name = "base_seq");
super.new(name);
endfunction
task pre_start();
`uvm_info(get_type_name(), "Base seq: Inside pre_start", UVM_LOW);
endtask
task pre_body();
`uvm_info(get_type_name(), "Base seq: Inside pre_body", UVM_LOW);
endtask
virtual task pre_do(bit is_item);
`uvm_info(get_type_name(), "Base seq: Inside pre_do", UVM_LOW);
endtask
virtual function void mid_do(uvm_sequence_item this_item);
`uvm_info(get_type_name(), "Base seq: Inside mid_do", UVM_LOW);
endfunction
task body();
`uvm_info(get_type_name(), "Base seq: Inside Body", UVM_LOW);
`uvm_do(req); // Calls all pre_do, mid_do and post_do methos.
/*
req = seq_item::type_id::create("req");
wait_for_grant();
assert(req.randomize());
send_request(req);
wait_for_item_done(); */
endtask
virtual function void post_do(uvm_sequence_item this_item);
`uvm_info(get_type_name(), "Base seq: Inside post_do", UVM_LOW);
endfunction
task post_body();
`uvm_info(get_type_name(), "Base seq: Inside post_body", UVM_LOW);
endtask
endclass
class child_seq extends base_seq;
`uvm_object_utils(child_seq)
function new (string name = "child_seq");
super.new(name);
endfunction
task pre_start();
`uvm_info(get_type_name(), "Child seq: Inside pre_start", UVM_LOW);
endtask
task pre_body();
`uvm_info(get_type_name(), "Child seq: Inside pre_body", UVM_LOW);
endtask
task pre_do(bit is_item);
`uvm_info(get_type_name(), "Child seq: Inside pre_do", UVM_LOW);
endtask
function void mid_do(uvm_sequence_item this_item);
`uvm_info(get_type_name(), "Child seq: Inside mid_do", UVM_LOW);
endfunction
task body();
`uvm_info(get_type_name(), "Child seq: Inside Body", UVM_LOW);
//`uvm_do(req); // Calls all pre_do, mid_do and post_do methos.
/*req = seq_item::type_id::create("req");
wait_for_grant();
assert(req.randomize());
send_request(req);
wait_for_item_done();*/
req = seq_item::type_id::create("req");
start_item(req);
assert(req.randomize());
finish_item(req);
endtask
function void post_do(uvm_sequence_item this_item);
`uvm_info(get_type_name(), "Child seq: Inside post_do", UVM_LOW);
endfunction
task post_body();
`uvm_info(get_type_name(), "Child seq: Inside post_body", UVM_LOW);
endtask
endclass
输出:
UVM_INFO testbench.sv(19) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside pre_start
UVM_INFO testbench.sv(23) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside pre_body
UVM_INFO testbench.sv(35) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside Body
UVM_INFO testbench.sv(27) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside pre_do
UVM_INFO testbench.sv(31) @ 0: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside mid_do
UVM_INFO driver.sv(16) @ 0: uvm_test_top.env_o.agt.drv [driver] Driving logic
UVM_INFO testbench.sv(46) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside post_do
UVM_INFO testbench.sv(50) @ 50: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside post_body
-----------------------------------------------------------------------------------
UVM_INFO testbench.sv(62) @ 50: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside pre_start
UVM_INFO testbench.sv(66) @ 50: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside pre_body
UVM_INFO testbench.sv(78) @ 50: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside Body
UVM_INFO testbench.sv(70) @ 50: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside pre_do
UVM_INFO testbench.sv(74) @ 50: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside mid_do
UVM_INFO driver.sv(16) @ 50: uvm_test_top.env_o.agt.drv [driver] Driving logic
UVM_INFO testbench.sv(94) @ 100: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside post_do
UVM_INFO testbench.sv(98) @ 100: uvm_test_top.env_o.agt.seqr@@cseq [child_seq] Child seq: Inside post_body
-----------------------------------------------------------------------------------
UVM_INFO testbench.sv(62) @ 100: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside pre_start
UVM_INFO testbench.sv(66) @ 100: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside pre_body
UVM_INFO testbench.sv(27) @ 100: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside pre_do
UVM_INFO testbench.sv(31) @ 100: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside mid_do
UVM_INFO testbench.sv(78) @ 100: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside Body
UVM_INFO testbench.sv(70) @ 100: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside pre_do
UVM_INFO testbench.sv(74) @ 100: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside mid_do
UVM_INFO driver.sv(16) @ 100: uvm_test_top.env_o.agt.drv [driver] Driving logic
UVM_INFO testbench.sv(94) @ 150: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside post_do
UVM_INFO testbench.sv(46) @ 150: uvm_test_top.env_o.agt.seqr@@bseq [base_seq] Base seq: Inside post_do
UVM_INFO testbench.sv(98) @ 150: uvm_test_top.env_o.agt.seqr@@bseq.cseq [child_seq] Child seq: Inside post_body