Advanced UVM Coding Techniques Dr David Long,
Description: Advanced UVM Coding Techniques Dr David Long, Doulos Accellera Systems Initiative 1 Agenda Run-Time Phasing Sequencers Random Stability Accellera Systems Initiative 2 Motivation Accellera Systems Initiative 3 Verification IP
Related Topics
Download Presentation
"Advanced UVM Coding Techniques Dr David Long," is the property of its rightful owner. Permission is granted to download and print the materials on this website for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Presentation Transcript
slide1. Advanced UVM Coding Techniques Dr David Long, Doulos © Accellera Systems Initiative 1<br>
slide2. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 2<br>
slide3. Motivation © Accellera Systems Initiative 3 Verification IP<br>
slide4. Motivation © Accellera Systems Initiative 4 Env Agent Subsc'r Sequ'r Driver Monitor Virtual seq Seq Reset Configure Training Run Shutdown Env Virtual seq Seq Reset Configure Training Run Shutdown Verification IP Verification IP<br>
slide5. The Common Phases of UVM © Accellera Systems Initiative 5 build_phase connect_phase end_of_elaboration_phase start_of_simulation_phase run_phase extract_phase check_phase report_phase final_phase Components advance in lock step Only run_phase consumes time Fixed schedule<br>
slide6. Phase Methods & Objects © Accellera Systems Initiative 6 function void build_phase(uvm_phase phase);
assert ( phase.is( uvm_build_phase::get() ) );
...
endfunction task run_phase(uvm_phase phase);
phase.raise_objection(this);
...
phase.drop_objection(this);
endtask Method Class Reference to proxy object<br>
slide7. The UVM Run-Time Phases © Accellera Systems Initiative 7 pre_reset_phase reset_phase post_reset_phase pre_configure_phase configure_phase post_configure_phase pre_main_phase main_phase post_main_phase pre_shutdown_phase shutdown_phase post_shutdown_phase run_phase For stimulus generation Resetting the DUT Configuration / setup / training The main work of the test Orderly shutdown<br>
slide8. Default Synchronization © Accellera Systems Initiative 8 class env extends uvm_env;
...
task reset_phase(uvm_phase phase);
...
task configure_phase(uvm_phase phase);
...
task main_phase(uvm_phase phase);
...
task shutdown_phase(uvm_phase phase);
...
endclass class test extends uvm_test;
...
env m_env1;
env m_env2;
function void build_phase(uvm_phase phase);
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
...
task run_phase(uvm_phase phase);
...<br>
slide9. Default Synchronization © Accellera Systems Initiative 9 m_env1: reset configure main shutdown m_env2: test: run_phase reset configure main shutdown<br>
slide10. Phase Method Synch © Accellera Systems Initiative 10 task main_phase(uvm_phase phase);
phase.raise_objection(this);
...
phase.drop_objection(this);
endtask task main_phase(uvm_phase phase);
...
endtask Both methods called in the same time step The methods may return at different times The phase only ends when all objections are dropped<br>
slide11. Domains © Accellera Systems Initiative 11 function void test::build_phase(uvm_phase phase);
uvm_domain domain1;
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
domain1 = new("domain1");
m_env1.set_domain(domain1);
endfunction User-defined domain<br>
slide12. Unsynchronized Domains © Accellera Systems Initiative 12 domain1: “The
UVM domain” reset configure main shutdown run_phase reset configure main shutdown “The UVM domain” contains the “UVM Run-time Phases” The user-defined domain gets its own copy of those phases<br>
slide13. Explicit Synchronization © Accellera Systems Initiative 13 function void test::build_phase(uvm_phase phase);
uvm_domain domain1, domain2;
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
domain1 = new("domain1");
m_env1.set_domain(domain1);
domain2 = new("domain2");
m_env2.set_domain(domain2);
domain1.sync(domain2);
domain1.unsync(domain2);
domain1.sync(domain2, uvm_main_phase::get());
domain1.sync(domain2, uvm_reset_phase::get(),
uvm_configure_phase::get()); For illustration!<br>
slide14. Synchronized Phases © Accellera Systems Initiative 14 domain1: reset configure main shutdown reset configure main shutdown domain2:<br>
slide15. Sync with pre/post phases © Accellera Systems Initiative 15 domain2.sync(uvm_domain::get_uvm_domain(),
uvm_configure_phase::get(),
uvm_post_configure_phase::get());
domain2.sync(uvm_domain::get_uvm_domain(),
uvm_shutdown_phase::get(),
uvm_pre_shutdown_phase::get()); UVM domain: reset configure main shutdown reset configure main shutdown domain2: post_configure pre_shutdown Lets you order phases across domains!<br>
slide16. User-Defined Phases 1 © Accellera Systems Initiative 16 class extended_component extends uvm_component;
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual task training_phase(uvm_phase phase);
endtask
endclass Boilerplate User-defined phase task Base class<br>
slide17. User-Defined Phases 2 © Accellera Systems Initiative 17 class my_training_phase extends uvm_task_phase;
protected function new (string name = "");
super.new(name);
endfunction
static local my_training_phase m_singleton_inst;
static function my_training_phase get;
if (m_singleton_inst == null)
m_singleton_inst = new("my_training_phase");
return m_singleton_inst;
endfunction
task exec_task(uvm_component comp, uvm_phase phase);
extended_component c;
if ($cast(c, comp))
c.training_phase(phase);
endtask
endclass Calls the overridden user-defined phase task Phase class Returns proxy object<br>
slide18. User-Defined Phases 3 © Accellera Systems Initiative 18 function void build_phase(uvm_phase phase);
uvm_phase schedule;
m_env1 = env::type_id::create("m_env1", this);
schedule = uvm_domain::get_uvm_schedule();
schedule.add(my_training_phase::get(),
.after_phase(uvm_configure_phase::get()),
.before_phase(uvm_main_phase::get()));
... Insert the phase into the schedule Pre-defined schedule of “The UVM domain”<br>
slide19. Extended Schedule © Accellera Systems Initiative 19 reset configure main shutdown post_configure pre_main training “The UVM domain”<br>
slide20. User-Defined Phases 4 © Accellera Systems Initiative 20 class env extends extended_component;
...
task training_phase(uvm_phase phase);
phase.raise_objection(this);
// Consume time
phase.drop_objection(this);
endtask
... Override the phase task<br>
slide21. Phase Jumping © Accellera Systems Initiative 21 // Test or env
task run_phase(uvm_phase phase);
#(...)
domain1.jump(uvm_reset_phase::get());
#(...)
domain1.jump(uvm_extract_phase::get()); Wait until middle of main_phase Wait until middle of main_phase, 2nd time around Backward jumps restricted to run-time phases Forward jumps restricted to common phases Phase methods aborted, objections cleared, sequences killed, child objects deleted.No safeguards<br>
slide22. Recommendations © Accellera Systems Initiative 22 Sequences for reset, configuration, and so forth
Use the pre-defined reset, configure, main, and shutdown phase methods
Only for stimulus
Add user-defined phases where pre-defined phases are insufficient
Use domains and sync phases when integrating VIP
Only use the pre- and post- phases for synchronization
Do not use phase jumping casually. There are no built-in safeguards<br>
slide23. Examples © Accellera Systems Initiative 23 http://www.edaplayground.com/x/2YsH UVM: Phase synchronization across domains
http://www.edaplayground.com/x/3dR4 UVM: User-defined phases
http://www.edaplayground.com/x/4hyq UVM: Creating a phase schedule from scratch
http://www.edaplayground.com/x/5FkD UVM: Overriding define_domain
http://www.edaplayground.com/x/5nXb UVM: The start and the end of each phase
http://www.edaplayground.com/x/6LJz UVM: Phase jumping<br>
slide24. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 24<br>
slide25. Sequences and Sequencers © Accellera Systems Initiative 25 Sequencer Driver Sequence Sequence DUT TLM export TLM port start_item(req);
finish_item(req); seq_item_port.get(req); start_item returns when get is called
get returns when finish_item is called<br>
slide26. A Simple Sequence © Accellera Systems Initiative 26 class my_seq extends uvm_sequence #(my_tx);
`uvm_object_utils(my_seq)
function new(string name = "");
super.new(name);
endfunction
task body;
repeat(4)
begin
req = my_tx::type_id::create("req");
start_item(req);
if (!req.randomize())
`uvm_error("", "failed to randomize")
finish_item(req);
end
endtask
endclass<br>
slide27. Nested Sequences © Accellera Systems Initiative 27 class top_seq extends uvm_sequence #(my_tx);
...
`uvm_declare_p_sequencer(my_seqr)
...
task body;
repeat(3)
begin
my_seq seq;
seq = my_seq::type_id::create("seq");
if (!seq.randomize())
`uvm_error("", "failed to randomize")
seq.start(p_sequencer, this);
end
endtask
... Parent sequence Sequencer<br>
slide28. Concurrent Sequences © Accellera Systems Initiative 28 task body;
fork
begin
seq1 = my_seq::type_id::create("seq1");
if (!seq1.randomize())
`uvm_error("", "failed to randomize")
seq1.start(p_sequencer, this);
end
begin
seq2 = my_seq::type_id::create("seq2");
if (!seq2.randomize())
...
seq2.start(p_sequencer, this);
end
begin
...
seq3.start(p_sequencer, this);
end
join
endtask Transactions will be strictly interleaved<br>
slide29. The Arbitration Queue © Accellera Systems Initiative 29 Sequencer Driver Arbitration queue start body start_item seq_item_port.get(req); Arbitration start body start_item fork start body start_item seq_item_port.get(req); seq_item_port.get(req); begin finish_item finish_item finish_item FIFO join end<br>
slide30. Setting the Arbitration Algorithm © Accellera Systems Initiative 30 task body;
p_sequencer.set_arbitration(
UVM_SEQ_ARB_STRICT_RANDOM);
fork
begin
seq1 = my_seq::type_id::create("seq1");
if (!seq1.randomize())
`uvm_error("", "failed to randomize")
seq1.start(p_sequencer, this, 1);
end
begin
...
seq2.start(p_sequencer, this, 2);
end
begin
...
seq3.start(p_sequencer, this, 3);
end
join
endtask Priority (default 100) Selected first<br>
slide31. Arbitration Algorithms © Accellera Systems Initiative 31<br>
slide32. User-Defined Arbitration Algorithm © Accellera Systems Initiative 32 class my_sequencer extends uvm_sequencer #(my_tx);
`uvm_component_utils(my_sequencer)
...
function integer user_priority_arbitration(
integer avail_sequences[$]);
foreach (avail_sequences[i])
begin
integer index = avail_sequences[i];
uvm_sequence_request req = arb_sequence_q[index];
int pri = req.item_priority;
uvm_sequence_base seq = req.sequence_ptr;
if (pri > max_pri)
...
end
return max_index;
endfunction
endclass Could access properties of the sequence object User-defined sequencer class<br>
slide33. Virtual Sequences © Accellera Systems Initiative 33 Sequencer Driver Sequencer Driver Sequencer Driver Sequencer Virtual sequence vseq.start(seqr0, null, priority)
body
fork
seq1.start(seqr1, this)
body
start_item
...
seq2.start(seqr2, this, 50)
body
start_item
... seqr1 seqr2 seqr3 seqr0 No transactions<br>
slide34. Sequencer Lock © Accellera Systems Initiative 34 Sequencer Driver Sequencer Virtual sequence seqr1 seqr0 No transactions vseq.start(seqr0, null)
body
begin
this.lock(seqr1);
seq1.start(seqr1, this);
body
start_item
finish_item
this.unlock(seqr1);
... Background traffic? grab() is LIFO, lock() is FIFO grab/lock bypass arbitration<br>
slide35. Examples © Accellera Systems Initiative 35 http://www.edaplayground.com/x/3D76 UVM: Sequence priority and arbitration
http://www.edaplayground.com/x/4qSF UVM: Virtual sequence calling lock<br>
slide36. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 36<br>
slide37. SystemVerilog Hierarchical Seeding © Accellera Systems Initiative 37 Command line <simulator> –svseed 1432123553 ... Module, interface, program instances, packages Static initializers
Static processes T v = new; initial always Dynamic processes
Objects fork ... join class ... rand int v; Child processes<br>
slide38. Seeding and Random Stability © Accellera Systems Initiative 38 initial
begin: P1
repeat (N1)
v = $urandom;
end
initial
begin: P2
repeat (N2)
v = $urandom;
fork
begin: P3
repeat (N3)
v = $urandom;
end
begin: P4
repeat (N4)
v = $urandom;
end
... RNG P1 seeded from parent RNG P3 seeded from P2 RNG P4 seeded from P2 RNG P2 seeded from parent<br>
slide39. UVM Seeding © Accellera Systems Initiative 39 Command line <simulator> –svseed 1432123553 ... uvm_component (reseeded) uvm_component (reseeded) uvm_sequence uvm_sequence uvm_sequence_item (reseeded) task run_phase (reseeded)<br>
slide40. Seeding of UVM Objects © Accellera Systems Initiative uvm_component seed calculated from
Command line seed
Class name of component
Full hierarchical instance name of component
A 32-bit CRC-like hash function
uvm_sequence_item seed calculated from
Command line seed
Class name of the sequence item
Full hierarchical instance name of sequencer
Simple name of sequence and sequence item object
A 32-bit CRC-like hash function<br>
slide41. The UVM Object Hierarchy © Accellera Systems Initiative 41 "m_agent_1" "m_sequencer" "sequence_a" "sequence_1" "sequence_2" "transaction_1" "transaction_2" "m_env" "uvm_test_top" "transaction_1" "transaction_2" "sequence_x" "transaction_x" "transaction_x" "sequence_b" "transaction_y" "m_agent_2" "transaction_q" "m_agent_x" "m_sequencer" "sequence_c" "transaction_p"<br>
slide42. Transactions with Unique Names © Accellera Systems Initiative 42 task body;
req1 = tx_type::type_id::create("req1");
start_item(req1);
void'(req1.randomize());
finish_item(req1);
req2 = tx_type::type_id::create("req2");
start_item(req2);
void'(req2.randomize());
finish_item(req2);
req3 = tx_type::type_id::create("req3");
start_item(req3);
void'(req3.randomize());
finish_item(req3);
endtask Transaction seed based on name<br>
slide43. Transactions with Name Clash © Accellera Systems Initiative 43 task body;
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
endtask Transaction seed based on order<br>
slide44. Sequence Names © Accellera Systems Initiative 44 task run_phase(uvm_phase phase);
seq1 = seq_type::type_id::create("seq1");
seq1.start(m_agent.m_sequencer);
seq2 = seq_type::type_id::create("seq2");
seq2.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
endtask Can be moved around without disturbing random stability of transactions Order-dependent<br>
slide45. Seeding Sequence Objects © Accellera Systems Initiative 45 UVM does not seed sequence objects by default task run_phase(uvm_phase phase);
seq1 = seq_type::type_id::create("seq1");
seq1.set_item_context(null, m_agent.m_sequencer);
void'(seq1.randomize());
seq1.start(m_agent.m_sequencer);
endtask task body;
seq2 = ano_type::type_id::create("seq2");
seq2.set_item_context(this, get_sequencer());
void'(seq2.randomize());
seq2.start(get_sequencer());
endtask task body;
`uvm_do(seq2)
endtask<br>
slide46. Random Stability in UVM © Accellera Systems Initiative 46 Keep all component instance names fixed!
Make sequence & sequence item names locally unique
Explicitly seed sequence objects (set_item_context)<br>
slide47. Any Questions? © Accellera Systems Initiative 47<br>
slide2. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 2<br>
slide3. Motivation © Accellera Systems Initiative 3 Verification IP<br>
slide4. Motivation © Accellera Systems Initiative 4 Env Agent Subsc'r Sequ'r Driver Monitor Virtual seq Seq Reset Configure Training Run Shutdown Env Virtual seq Seq Reset Configure Training Run Shutdown Verification IP Verification IP<br>
slide5. The Common Phases of UVM © Accellera Systems Initiative 5 build_phase connect_phase end_of_elaboration_phase start_of_simulation_phase run_phase extract_phase check_phase report_phase final_phase Components advance in lock step Only run_phase consumes time Fixed schedule<br>
slide6. Phase Methods & Objects © Accellera Systems Initiative 6 function void build_phase(uvm_phase phase);
assert ( phase.is( uvm_build_phase::get() ) );
...
endfunction task run_phase(uvm_phase phase);
phase.raise_objection(this);
...
phase.drop_objection(this);
endtask Method Class Reference to proxy object<br>
slide7. The UVM Run-Time Phases © Accellera Systems Initiative 7 pre_reset_phase reset_phase post_reset_phase pre_configure_phase configure_phase post_configure_phase pre_main_phase main_phase post_main_phase pre_shutdown_phase shutdown_phase post_shutdown_phase run_phase For stimulus generation Resetting the DUT Configuration / setup / training The main work of the test Orderly shutdown<br>
slide8. Default Synchronization © Accellera Systems Initiative 8 class env extends uvm_env;
...
task reset_phase(uvm_phase phase);
...
task configure_phase(uvm_phase phase);
...
task main_phase(uvm_phase phase);
...
task shutdown_phase(uvm_phase phase);
...
endclass class test extends uvm_test;
...
env m_env1;
env m_env2;
function void build_phase(uvm_phase phase);
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
...
task run_phase(uvm_phase phase);
...<br>
slide9. Default Synchronization © Accellera Systems Initiative 9 m_env1: reset configure main shutdown m_env2: test: run_phase reset configure main shutdown<br>
slide10. Phase Method Synch © Accellera Systems Initiative 10 task main_phase(uvm_phase phase);
phase.raise_objection(this);
...
phase.drop_objection(this);
endtask task main_phase(uvm_phase phase);
...
endtask Both methods called in the same time step The methods may return at different times The phase only ends when all objections are dropped<br>
slide11. Domains © Accellera Systems Initiative 11 function void test::build_phase(uvm_phase phase);
uvm_domain domain1;
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
domain1 = new("domain1");
m_env1.set_domain(domain1);
endfunction User-defined domain<br>
slide12. Unsynchronized Domains © Accellera Systems Initiative 12 domain1: “The
UVM domain” reset configure main shutdown run_phase reset configure main shutdown “The UVM domain” contains the “UVM Run-time Phases” The user-defined domain gets its own copy of those phases<br>
slide13. Explicit Synchronization © Accellera Systems Initiative 13 function void test::build_phase(uvm_phase phase);
uvm_domain domain1, domain2;
m_env1 = env::type_id::create("m_env1", this);
m_env2 = env::type_id::create("m_env2", this);
domain1 = new("domain1");
m_env1.set_domain(domain1);
domain2 = new("domain2");
m_env2.set_domain(domain2);
domain1.sync(domain2);
domain1.unsync(domain2);
domain1.sync(domain2, uvm_main_phase::get());
domain1.sync(domain2, uvm_reset_phase::get(),
uvm_configure_phase::get()); For illustration!<br>
slide14. Synchronized Phases © Accellera Systems Initiative 14 domain1: reset configure main shutdown reset configure main shutdown domain2:<br>
slide15. Sync with pre/post phases © Accellera Systems Initiative 15 domain2.sync(uvm_domain::get_uvm_domain(),
uvm_configure_phase::get(),
uvm_post_configure_phase::get());
domain2.sync(uvm_domain::get_uvm_domain(),
uvm_shutdown_phase::get(),
uvm_pre_shutdown_phase::get()); UVM domain: reset configure main shutdown reset configure main shutdown domain2: post_configure pre_shutdown Lets you order phases across domains!<br>
slide16. User-Defined Phases 1 © Accellera Systems Initiative 16 class extended_component extends uvm_component;
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual task training_phase(uvm_phase phase);
endtask
endclass Boilerplate User-defined phase task Base class<br>
slide17. User-Defined Phases 2 © Accellera Systems Initiative 17 class my_training_phase extends uvm_task_phase;
protected function new (string name = "");
super.new(name);
endfunction
static local my_training_phase m_singleton_inst;
static function my_training_phase get;
if (m_singleton_inst == null)
m_singleton_inst = new("my_training_phase");
return m_singleton_inst;
endfunction
task exec_task(uvm_component comp, uvm_phase phase);
extended_component c;
if ($cast(c, comp))
c.training_phase(phase);
endtask
endclass Calls the overridden user-defined phase task Phase class Returns proxy object<br>
slide18. User-Defined Phases 3 © Accellera Systems Initiative 18 function void build_phase(uvm_phase phase);
uvm_phase schedule;
m_env1 = env::type_id::create("m_env1", this);
schedule = uvm_domain::get_uvm_schedule();
schedule.add(my_training_phase::get(),
.after_phase(uvm_configure_phase::get()),
.before_phase(uvm_main_phase::get()));
... Insert the phase into the schedule Pre-defined schedule of “The UVM domain”<br>
slide19. Extended Schedule © Accellera Systems Initiative 19 reset configure main shutdown post_configure pre_main training “The UVM domain”<br>
slide20. User-Defined Phases 4 © Accellera Systems Initiative 20 class env extends extended_component;
...
task training_phase(uvm_phase phase);
phase.raise_objection(this);
// Consume time
phase.drop_objection(this);
endtask
... Override the phase task<br>
slide21. Phase Jumping © Accellera Systems Initiative 21 // Test or env
task run_phase(uvm_phase phase);
#(...)
domain1.jump(uvm_reset_phase::get());
#(...)
domain1.jump(uvm_extract_phase::get()); Wait until middle of main_phase Wait until middle of main_phase, 2nd time around Backward jumps restricted to run-time phases Forward jumps restricted to common phases Phase methods aborted, objections cleared, sequences killed, child objects deleted.No safeguards<br>
slide22. Recommendations © Accellera Systems Initiative 22 Sequences for reset, configuration, and so forth
Use the pre-defined reset, configure, main, and shutdown phase methods
Only for stimulus
Add user-defined phases where pre-defined phases are insufficient
Use domains and sync phases when integrating VIP
Only use the pre- and post- phases for synchronization
Do not use phase jumping casually. There are no built-in safeguards<br>
slide23. Examples © Accellera Systems Initiative 23 http://www.edaplayground.com/x/2YsH UVM: Phase synchronization across domains
http://www.edaplayground.com/x/3dR4 UVM: User-defined phases
http://www.edaplayground.com/x/4hyq UVM: Creating a phase schedule from scratch
http://www.edaplayground.com/x/5FkD UVM: Overriding define_domain
http://www.edaplayground.com/x/5nXb UVM: The start and the end of each phase
http://www.edaplayground.com/x/6LJz UVM: Phase jumping<br>
slide24. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 24<br>
slide25. Sequences and Sequencers © Accellera Systems Initiative 25 Sequencer Driver Sequence Sequence DUT TLM export TLM port start_item(req);
finish_item(req); seq_item_port.get(req); start_item returns when get is called
get returns when finish_item is called<br>
slide26. A Simple Sequence © Accellera Systems Initiative 26 class my_seq extends uvm_sequence #(my_tx);
`uvm_object_utils(my_seq)
function new(string name = "");
super.new(name);
endfunction
task body;
repeat(4)
begin
req = my_tx::type_id::create("req");
start_item(req);
if (!req.randomize())
`uvm_error("", "failed to randomize")
finish_item(req);
end
endtask
endclass<br>
slide27. Nested Sequences © Accellera Systems Initiative 27 class top_seq extends uvm_sequence #(my_tx);
...
`uvm_declare_p_sequencer(my_seqr)
...
task body;
repeat(3)
begin
my_seq seq;
seq = my_seq::type_id::create("seq");
if (!seq.randomize())
`uvm_error("", "failed to randomize")
seq.start(p_sequencer, this);
end
endtask
... Parent sequence Sequencer<br>
slide28. Concurrent Sequences © Accellera Systems Initiative 28 task body;
fork
begin
seq1 = my_seq::type_id::create("seq1");
if (!seq1.randomize())
`uvm_error("", "failed to randomize")
seq1.start(p_sequencer, this);
end
begin
seq2 = my_seq::type_id::create("seq2");
if (!seq2.randomize())
...
seq2.start(p_sequencer, this);
end
begin
...
seq3.start(p_sequencer, this);
end
join
endtask Transactions will be strictly interleaved<br>
slide29. The Arbitration Queue © Accellera Systems Initiative 29 Sequencer Driver Arbitration queue start body start_item seq_item_port.get(req); Arbitration start body start_item fork start body start_item seq_item_port.get(req); seq_item_port.get(req); begin finish_item finish_item finish_item FIFO join end<br>
slide30. Setting the Arbitration Algorithm © Accellera Systems Initiative 30 task body;
p_sequencer.set_arbitration(
UVM_SEQ_ARB_STRICT_RANDOM);
fork
begin
seq1 = my_seq::type_id::create("seq1");
if (!seq1.randomize())
`uvm_error("", "failed to randomize")
seq1.start(p_sequencer, this, 1);
end
begin
...
seq2.start(p_sequencer, this, 2);
end
begin
...
seq3.start(p_sequencer, this, 3);
end
join
endtask Priority (default 100) Selected first<br>
slide31. Arbitration Algorithms © Accellera Systems Initiative 31<br>
slide32. User-Defined Arbitration Algorithm © Accellera Systems Initiative 32 class my_sequencer extends uvm_sequencer #(my_tx);
`uvm_component_utils(my_sequencer)
...
function integer user_priority_arbitration(
integer avail_sequences[$]);
foreach (avail_sequences[i])
begin
integer index = avail_sequences[i];
uvm_sequence_request req = arb_sequence_q[index];
int pri = req.item_priority;
uvm_sequence_base seq = req.sequence_ptr;
if (pri > max_pri)
...
end
return max_index;
endfunction
endclass Could access properties of the sequence object User-defined sequencer class<br>
slide33. Virtual Sequences © Accellera Systems Initiative 33 Sequencer Driver Sequencer Driver Sequencer Driver Sequencer Virtual sequence vseq.start(seqr0, null, priority)
body
fork
seq1.start(seqr1, this)
body
start_item
...
seq2.start(seqr2, this, 50)
body
start_item
... seqr1 seqr2 seqr3 seqr0 No transactions<br>
slide34. Sequencer Lock © Accellera Systems Initiative 34 Sequencer Driver Sequencer Virtual sequence seqr1 seqr0 No transactions vseq.start(seqr0, null)
body
begin
this.lock(seqr1);
seq1.start(seqr1, this);
body
start_item
finish_item
this.unlock(seqr1);
... Background traffic? grab() is LIFO, lock() is FIFO grab/lock bypass arbitration<br>
slide35. Examples © Accellera Systems Initiative 35 http://www.edaplayground.com/x/3D76 UVM: Sequence priority and arbitration
http://www.edaplayground.com/x/4qSF UVM: Virtual sequence calling lock<br>
slide36. Agenda Run-Time Phasing
Sequencers
Random Stability © Accellera Systems Initiative 36<br>
slide37. SystemVerilog Hierarchical Seeding © Accellera Systems Initiative 37 Command line <simulator> –svseed 1432123553 ... Module, interface, program instances, packages Static initializers
Static processes T v = new; initial always Dynamic processes
Objects fork ... join class ... rand int v; Child processes<br>
slide38. Seeding and Random Stability © Accellera Systems Initiative 38 initial
begin: P1
repeat (N1)
v = $urandom;
end
initial
begin: P2
repeat (N2)
v = $urandom;
fork
begin: P3
repeat (N3)
v = $urandom;
end
begin: P4
repeat (N4)
v = $urandom;
end
... RNG P1 seeded from parent RNG P3 seeded from P2 RNG P4 seeded from P2 RNG P2 seeded from parent<br>
slide39. UVM Seeding © Accellera Systems Initiative 39 Command line <simulator> –svseed 1432123553 ... uvm_component (reseeded) uvm_component (reseeded) uvm_sequence uvm_sequence uvm_sequence_item (reseeded) task run_phase (reseeded)<br>
slide40. Seeding of UVM Objects © Accellera Systems Initiative uvm_component seed calculated from
Command line seed
Class name of component
Full hierarchical instance name of component
A 32-bit CRC-like hash function
uvm_sequence_item seed calculated from
Command line seed
Class name of the sequence item
Full hierarchical instance name of sequencer
Simple name of sequence and sequence item object
A 32-bit CRC-like hash function<br>
slide41. The UVM Object Hierarchy © Accellera Systems Initiative 41 "m_agent_1" "m_sequencer" "sequence_a" "sequence_1" "sequence_2" "transaction_1" "transaction_2" "m_env" "uvm_test_top" "transaction_1" "transaction_2" "sequence_x" "transaction_x" "transaction_x" "sequence_b" "transaction_y" "m_agent_2" "transaction_q" "m_agent_x" "m_sequencer" "sequence_c" "transaction_p"<br>
slide42. Transactions with Unique Names © Accellera Systems Initiative 42 task body;
req1 = tx_type::type_id::create("req1");
start_item(req1);
void'(req1.randomize());
finish_item(req1);
req2 = tx_type::type_id::create("req2");
start_item(req2);
void'(req2.randomize());
finish_item(req2);
req3 = tx_type::type_id::create("req3");
start_item(req3);
void'(req3.randomize());
finish_item(req3);
endtask Transaction seed based on name<br>
slide43. Transactions with Name Clash © Accellera Systems Initiative 43 task body;
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
req = tx_type::type_id::create("req");
start_item(req);
void'(req.randomize());
finish_item(req);
endtask Transaction seed based on order<br>
slide44. Sequence Names © Accellera Systems Initiative 44 task run_phase(uvm_phase phase);
seq1 = seq_type::type_id::create("seq1");
seq1.start(m_agent.m_sequencer);
seq2 = seq_type::type_id::create("seq2");
seq2.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
seq3 = seq_type::type_id::create("seq3");
seq3.start(m_agent.m_sequencer);
endtask Can be moved around without disturbing random stability of transactions Order-dependent<br>
slide45. Seeding Sequence Objects © Accellera Systems Initiative 45 UVM does not seed sequence objects by default task run_phase(uvm_phase phase);
seq1 = seq_type::type_id::create("seq1");
seq1.set_item_context(null, m_agent.m_sequencer);
void'(seq1.randomize());
seq1.start(m_agent.m_sequencer);
endtask task body;
seq2 = ano_type::type_id::create("seq2");
seq2.set_item_context(this, get_sequencer());
void'(seq2.randomize());
seq2.start(get_sequencer());
endtask task body;
`uvm_do(seq2)
endtask<br>
slide46. Random Stability in UVM © Accellera Systems Initiative 46 Keep all component instance names fixed!
Make sequence & sequence item names locally unique
Explicitly seed sequence objects (set_item_context)<br>
slide47. Any Questions? © Accellera Systems Initiative 47<br>