Beruflich Dokumente
Kultur Dokumente
Tom Fitzpatrick
Verification Evangelist
info@verificationacademy.com | 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
info@verificationacademy.com | www.verificationacademy.com