Upload
srigovindaduttadas
View
232
Download
8
Embed Size (px)
DESCRIPTION
Advanced Uvm Session5
Citation preview
[email protected] | www.verificationacademy.com
Advanced UVM The Proper Care and Feeding of Sequences
Tom Fitzpatrick
Verification Evangelist
Separating Stimulus from the Testbench • A key to reusability is to separate Behavior from Structure
VIP Testbench
DUT
Configuration & Factory
Behavior Structure
© 2013 Mentor Graphics Corporation, all rights reserved.
Review: Sequences • Decouple stimulus specification from
structural hierarchy • Add/remove/modify stimulus scenarios independent of testbench • Simplify test writer API
• Sequences define transaction streams • May start on any sequencer
• Sequences can call children • Sequences & transactions customizable
via the factory
u1 u1
u1
s5
s1
s4
s3 s2
s1
© 2013 Mentor Graphics Corporation, all rights reserved.
Create request Initiate Driver Handshake
Send transaction
Late Randomization
Note: begin-end around `uvm_<msg>
Transaction type
Review: Sequence Basics
© 2013 Mentor Graphics Corporation, all rights reserved.
class my_seq extends uvm_sequence #(req_t); `uvm_object_utils(uvm_seq) req_t req; int num = 10;
function new(string name = “my_seq”); super.new(name); endfunction
task body(); uvm_config_db#(int)::get(this, “”, “num”, num); req = req_t::type_id::create(“req”); for_int i = 0; i < num; i++) begin start_item(req); if(!req.randomize()) begin `uvm_error(“body”, “rand failure”) end finish_item(req); end endtask endclass
Default name in constructor
Review: Sequence/r/Driver Parameterization
© 2013 Mentor Graphics Corporation, all rights reserved.
class my_seq extends uvm_sequence #(type REQ=req_t, RSP=rsp_t); `uvm_object_utils(my_seq) … endclass class my_driver extends uvm_driver #(type REQ=req_t, RSP=rsp_t); `uvm_component_utils(my_driver) … endclass typedef uvm_sequencer #(type REQ=req_t, RSP=rsp_t) my_sequencer;
By default, RSP=REQ
Parameterization must match sequence
Don’t need to declare a new sequencer type
Review: Sequence/Driver Handshake
© 2013 Mentor Graphics Corporation, all rights reserved.
task body(); req = req_t::type_id::create(“req”); for_int i = 0; i < num; i++) begin start_item(req); if(!req.randomize()) begin `uvm_error(“body”, “rand failure”) end finish_item(req); `uvm_info(“my_seq1”,req.convert2string()); end endtask
my_seq1 driver get_next_item(req); start_item(req);
finish_item(req); item_done();
task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); drive_item2bus(req); seq_item_port.item_done(); end endtask
If driver updates req with response information
Review: Sequence/Driver Handshake
© 2013 Mentor Graphics Corporation, all rights reserved.
task body(); req = req_t::type_id::create(“req”); for_int i = 0; i < num; i++) begin start_item(req); if(!req.randomize()) begin `uvm_error(“body”, “rand failure”) end finish_item(req); get_response(rsp); end endtask
my_seq1 driver get_next_item(req); start_item(req);
finish_item(req); item_done();
task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); drive_item2bus(req,rsp); seq_item_port.item_done(); rsp.set_id_info(req); seq_item_port.put_response(rsp); end endtask
get_response(rsp); put_response(rsp);
If driver provides separate response object
Arbitration and Responses in the Sequencer
© 2013 Mentor Graphics Corporation, all rights reserved.
Sequencer
class myseq…; virtual task body(); … finish_item(req) get_response(rsp); endtask endclass
class myseq…; virtual task body(); … finish_item(req) get_response(rsp,id); endtask endclass
Driver
s1
s2
arbitrate requests
route responses
class req; seq_id = trans_id =
class req; seq_id = 1; trans_id = 1;
2,1
class req; seq_id = trans_id =
class req; seq_id = 2; trans_id = 1;
class driver…; task run(); … rsp.set_id_info(req); seq_item_port.put_response(rsp); endtask endclass
1,1 rsp seq_id = trans_id =
1,1
rsp seq_id = 1; trans_id = 1;
rsp seq_id = 1; trans_id = 1;
Sequence-specific
Unique within sequence
Both sequences now waiting for responses
set_id_info() copies id fields from req to rsp
Sequencer uses sequence_id to route response to originating sequence
Arbitration and Responses in the Sequencer
© 2013 Mentor Graphics Corporation, all rights reserved.
class myseq…; virtual task body(); use_response_handler(1); finish_item(req) get_response(rsp,id); endtask virtual function void response_handler(uvm_sequence_item response); … endfunction endclass
Customize the response handler as necessary
sequencer.set_arbitration(SEQ_ARB_USER); class my_sequencer extends uvm_sequencer(REQ); ‘uvm_component_utils(my_sequencer) virtual function integer user_priority_arbitration(integer avail_sequences[$]); … endfunction endclass
SEQ_ARB_FIFO SEQ_ARB_WEIGHTED SEQ_ARB_RANDOM SEQ_ARB_STRICT_FIFO SEQ_ARB_STRICT_RANDOM SEQ_ARB_USER
Review: Starting a Sequence
class test1 extends uvm_test; `uvm_component_utils(test1) my_env my_env_h; ... task run_phase(uvm_phase phase); read_modify_write seq; seq = read_modify_write::type_id::create(“seq”);
Create sequence via factory
© 2013 Mentor Graphics Corporation, all rights reserved.
Review: Starting a Sequence
class test1 extends uvm_test; `uvm_component_utils(test1) my_env my_env_h; ... 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_env_h.my_agent_h.my_sequencer_h );
Always use start() to execute a sequence
© 2013 Mentor Graphics Corporation, all rights reserved.
Review: Starting a Sequence
class test1 extends uvm_test; `uvm_component_utils(test1) my_env my_env_h; ... 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_env_h.my_agent_h.my_sequencer_h );
Path to sequencer
© 2013 Mentor Graphics Corporation, all rights reserved.
Can Start Sequence from Environment too
class my_env extends uvm_env; `uvm_component_utils(my_env) my_agent my_agent_h; ... 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
Factory enables test to choose what default
sequence to run
Path to sequencer
© 2013 Mentor Graphics Corporation, all rights reserved.
class my_test extends uvm_test; … init_seq iseq; exec_seq eseq; ... task run_phase(uvm_phase phase); iseq = init_seq::type_id::create(“iseq”); eseq = exec_seq::type_id::create(“eseq”); phase.raise_objection(this); iseq.start( my_env_h.my_agent_h.my_sequencer_h ); eseq.start( my_env_h.my_agent_h.my_sequencer_h ); … phase.drop_objection(this); endtask endclass
Sequential Sequences
init_seq
exec_seq
start() is blocking
© 2013 Mentor Graphics Corporation, all rights reserved.
class my_test extends uvm_test; … init_seq iseq; exec_seq eseq; ... task run_phase(uvm_phase phase); iseq = init_seq::type_id::create(“iseq”); eseq = exec_seq::type_id::create(“eseq”); phase.raise_objection(this); fork iseq.start( my_env_h.my_agent_h.my_sequencer_h ); eseq.start( my_env.h.my_agent_h.my_sequencer_h ); join … phase.drop_objection(this); endtask endclass
Parallel Sequences
init_seq exec_seq
Don’t use fork-join_none
© 2013 Mentor Graphics Corporation, all rights reserved.
class my_test extends uvm_test; … init_seq iseq; exec_seq eseq; ... task run_phase(uvm_phase phase); iseq = init_seq::type_id::create(“iseq”); eseq = exec_seq::type_id::create(“eseq”); phase.raise_objection(this); fork iseq.start( my_agent_h.my_sequencer_h, this, HIGH ); eseq.start( my_agent_h.my_sequencer_h, this, LOW ); join … phase.drop_objection(this); endtask endclass
Parallel Sequences
init_seq exec_seq
Optional priority
© 2013 Mentor Graphics Corporation, all rights reserved.
Hierarchical Sequences
init_seq
exec_seq
test_seq
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); … endtask endclass
Hierarchical Sequences
init_seq test_seq
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); iseq.start( m_sequencer, this ); … endtask endclass
Hierarchical Sequences
init_seq test_seq
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); iseq.start( m_sequencer, this ); … endtask endclass
Hierarchical Sequences
init_seq test_seq
Run on test_seq’s sequencer
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); iseq.start( m_sequencer, this ); … endtask endclass
Hierarchical Sequences
init_seq test_seq
Optional parent sequence specifier
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); eseq = exec_seq::type_id::create(“eseq”); iseq.start( m_sequencer, this ); … endtask endclass
Hierarchical Sequences
init_seq
exec_seq
test_seq
© 2013 Mentor Graphics Corporation, all rights reserved.
class test_seq extends uvm_sequence #(req,rsp); `uvm_object_utils(test_seq) init_seq iseq; exec_seq eseq; task body(); iseq = init_seq::type_id::create(“iseq”); eseq = exec_seq::type_id::create(“eseq”); iseq.start( m_sequencer, this ); eseq.start( m_sequencer, this ); … endtask endclass
Hierarchical Sequences
init_seq
exec_seq
test_seq
“top.env.agent.sequencer.test_seq.eseq”
© 2013 Mentor Graphics Corporation, all rights reserved.
Pipelined Driver
© 2013 Mentor Graphics Corporation, all rights reserved.
class mbus_pipelined_driver extends uvm_driver #(mbus_seq_item); `uvm_component_utils(mbus_pipelined_driver) virtual mbus_if MBUS; function new(string name = "mbus_pipelined_driver", uvm_component parent = null); super.new(name, parent); endfunction task run_phase(uvm_phase phase); @(posedge MBUS.MRESETN); @(posedge MBUS.MCLK); fork do_pipelined_transfer; do_pipelined_transfer; join endtask task do_pipelined_transfer; endtask endclass
Pipelined Driver
© 2013 Mentor Graphics Corporation, all rights reserved.
class mbus_pipelined_driver extends uvm_driver #(mbus_seq_item); `uvm_component_utils(mbus_pipelined_driver) virtual mbus_if MBUS; 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
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
© 2013 Mentor Graphics Corporation, all rights reserved.
[email protected] | www.verificationacademy.com
Advanced UVM The Proper Care and Feeding of Sequences
Tom Fitzpatrick
Verification Evangelist