The Proper Care and Feeding of UVM Sequences PDF
The Proper Care and Feeding of UVM Sequences PDF
The Proper Care and Feeding of UVM Sequences PDF
Tom Fitzpatrick
Verification Evangelist
[email protected] | www.verificationacademy.com
Separating Stimulus from the Testbench
• A key to reusability is to separate Behavior from Structure
Behavior
Structure
Testbench VIP
DUT
transaction streams
• May start on any sequencer
s3 s5
• Sequences can call children s2
task body();
uvm_config_db#(int)::get(this, “”, “num”, num);
req = req_t::type_id::create(“req”); Create request
for_int i = 0; i < num; i++) begin Initiate Driver Handshake
start_item(req);
Late Randomization
if(!req.randomize()) begin
`uvm_error(“body”, “rand failure”) Note: begin-end around
end `uvm_<msg>
finish_item(req);
end Send transaction
endtask
endclass
© 2013 Mentor Graphics Corporation, all rights reserved.
Review: Sequence/r/Driver Parameterization
class my_seq extends uvm_sequence #(type REQ=req_t, RSP=rsp_t);
`uvm_object_utils(my_seq)
… By default, RSP=REQ
endclass
finish_item(req);
item_done();
task body();
req = req_t::type_id::create(“req”); task run_phase(uvm_phase phase);
for_int i = 0; i < num; i++) begin forever begin
start_item(req); seq_item_port.get_next_item(req);
if(!req.randomize()) begin drive_item2bus(req);
`uvm_error(“body”, “rand failure”) seq_item_port.item_done();
end end
finish_item(req); endtask
`uvm_info(“my_seq1”,req.convert2string()); If driver updates req with
end response information
endtask
© 2013 Mentor Graphics Corporation, all rights reserved.
Review: Sequence/Driver Handshake
my_seq1 driver
start_item(req); get_next_item(req);
finish_item(req);
item_done();
get_response(rsp);
put_response(rsp);
task body();
req = req_t::type_id::create(“req”); task run_phase(uvm_phase phase);
for_int i = 0; i < num; i++) begin forever begin
start_item(req); seq_item_port.get_next_item(req);
if(!req.randomize()) begin drive_item2bus(req,rsp);
`uvm_error(“body”, “rand failure”) seq_item_port.item_done();
end rsp.set_id_info(req);
finish_item(req); seq_item_port.put_response(rsp);
get_response(rsp); end
If driver provides separate
end endtask
response object
endtask
© 2013 Mentor Graphics Corporation, all rights reserved.
Arbitration and Responses in the Sequencer
class myseq…; Sequence-specific
virtual task body();
Sequencer Unique within sequence
…
finish_item(req)
class req;
get_response(rsp);
get_response(rsp,id);
seq_id = 1;
2;
endtask s1
trans_id = 1;
endclass
arbitrate Driver
requests 1,1
Both 2,1
sequences s2
`uvm_component_utils(test1)
my_env my_env_h;
...
Create sequence
via factory
`uvm_component_utils(test1)
my_env my_env_h;
...
`uvm_component_utils(test1)
my_env my_env_h;
...
Path to sequencer
`uvm_component_utils(my_env)
Factory enables test to
my_agent my_agent_h;
choose what default
...
sequence to run
task run_phase(uvm_phase phase);
read_modify_write seq;
seq = read_modify_write::type_id::create(“seq”);
phase.raise_objection(this);
seq.start( my_agent_h.my_sequencer_h );
phase.drop_objection(this);
endtask Path to sequencer
test_seq
init_seq
exec_seq
task body();
iseq = init_seq::type_id::create(“iseq”);
…
endtask
endclass
task body();
iseq = init_seq::type_id::create(“iseq”);
…
endtask
endclass
task body();
iseq = init_seq::type_id::create(“iseq”);
…
endtask Run on test_seq’s
endclass sequencer
task body();
iseq = init_seq::type_id::create(“iseq”);
…
endtask Optional parent
endclass sequence specifier
task body();
iseq = init_seq::type_id::create(“iseq”);
exec_seq
eseq = exec_seq::type_id::create(“eseq”);
iseq.start( m_sequencer, this );
…
endtask
endclass
task body();
iseq = init_seq::type_id::create(“iseq”);
exec_seq
eseq = exec_seq::type_id::create(“eseq”);
iseq.start( m_sequencer, this );
eseq.start( m_sequencer, this );
…
endtask
endclass
“top.env.agent.sequencer.test_seq.eseq”
task do_pipelined_transfer;
mbus_seq_item req,rsp;
forever begin
pipeline_lock.get();
seq_item_port.get(req);
do_command_phase(req);
pipeline_lock.put();
do_data_phase(req,rsp);
seq_item_port.put(rsp);
end
endtask
endclass
© 2013 Mentor Graphics Corporation, all rights reserved.
Summary: General Rules
• Make sure to parameterize sequence/sequencer/driver with
the same request and response types
• Start sequences using seq.start(sequencer)
• Use seq_item_port.get_next_item/item_done in the driver
• Use try_next_item/item_done if driver must perform idle cycles
• Use get/put for pipelined drivers
• Use uvm_config_db#()::get() to configure sequences
• Sequence and Driver must agree on response path, if any
Tom Fitzpatrick
Verification Evangelist
[email protected] | www.verificationacademy.com