You are on page 1of 19

Advanced UVM

Layered Sequences

Tom Fitzpatrick
Verification Evangelist

info@verificationacademy.com | www.verificationacademy.com
Sequences & Sequencers
• Most sequences run on sequencers
• One sequencer per agent
• Env may define default sequence
Test
• Can be overridden via factory
• Test defines other sequences
Env
• Sequences generate items
• Sequencer sends to driver Sequencer

Agent

Monitor Driver

DUT

© Mentor Graphics Corporation, all rights reserved.


Sequences & Sequencers
• Tests require coordinating multiple sequences on multiple
DUT interfaces
Test

Env

Sequencer Sequencer

Driver Driver

DUT

© Mentor Graphics Corporation, all rights reserved.


Virtual Sequences
typedef uvm_sequence #(uvm_sequence_item) uvm_virtual_sequence;

Useful typedef 2 1
tseq
B A
class myvseq_base extends uvm_virtual_sequence;
...
a_sequencer_t a_sequencer; Env
b_sequencer_t b_sequencer; Handles for target agent2 agent1
sequencers Sqr
task body(); Drvr Drvr
...
aseq.start( a_sequencer , this );
Start sequences on target
bseq.start( b_sequencer , this ); sequencers
endtask
endclass class my_test extends uvm_test;

my_seq vseq = my_seq::type_id::create("vseq");
Start vseq with null
sequencer vseq.a_sequencer = env.agent1.sequencer;
vseq.b_sequencer = env.agent2.sequencer;
Assign target sequencers
vseq.start( null );
endclass
© Mentor Graphics Corporation, all rights reserved.
Virtual Sequence Initialization
class test_base extends uvm_test;
`uvm_component_utils(test_top_base) 2 1
tseq
B A
env_top m_env;

function new(string name = "test_top_base", Env


uvm_component parent = null); agent2 agent1
super.new(name, parent); Sqr
endfunction Drvr Drvr

function void build_phase(uvm_phase phase);


m_env = env_top::type_id::create("m_env", this);
endfunction: build_phase

function void init_vseq(myvseq_base vseq);


vseq.a_sequencer = m_env.m_agent_1.m_sequencer; Method to initialize the
vseq.b_sequencer = m_env.m_agent_2.m_sequencer; virtual sequence handles
endfunction: init_vseq

endclass: test_base
© Mentor Graphics Corporation, all rights reserved.
Virtual Sequence in a Test
class init_vseq_test extends test_base;
`uvm_component_utils(init_vseq_test) 2 1
tseq
B A
function new(string name = "init_vseq_test",
uvm_component parent = null);
super.new(name, parent); Env
endfunction agent2 agent1
Sqr
task run_phase(uvm_phase phase); Drvr Drvr
vseq_A_B vseq = vseq_A_B::type_id::create("vseq");

phase.raise_objection(this);
init_vseq(vseq);
vseq.start(null);
phase.drop_objection(this);
endtask: run_phase

endclass: init_vseq_test

© Mentor Graphics Corporation, all rights reserved.


Virtual Sequence in a Test
class vseq_A_B extends myvseq_base;
`uvm_object_utils(vseq_A_B) 2 1
tseq
B A
function new(string name = "vseq_A_B");
super.new(name);
endfunction Env
agent2 agent1
task body(); Sqr
a_seq a = a_seq::type_id::create("a"); Drvr Drvr
b_seq b = b_seq::type_id::create("b");

fork
a.start(a_sequencer);
b.start(b_sequencer);
join
endtask: body

endclass: vseq_A_B

© Mentor Graphics Corporation, all rights reserved.


Layered Protocols
• Hierarchical Protocols (PCI Express, USB3.0, MIPI LLI…)
• Transaction Layer
• Transport Layer
• Physical Layer
• Protocol-Independent
• Generic Layer (e.g. TLM2.0 GP)
• Specific Protocol (e.g. AMBA AHB)
• All require Sequence Items to be deconstructed and
reconstructed
• One-to-many high

low
low

• Many-to-one high
low
high

© Mentor Graphics Corporation, all rights reserved.


Tests Start Sequences
• Want to execute sequences at the top layer
• Test starts sequence on sequencer
• Reuse as much as possible
• Protocol Agent on the bus
• Sequencers/monitors at higher layers

class prot_test extends uvm_test;


`uvm_component_utils(prot_test)

virtual task run_phase(uvm_phase phase);


my_seq = Agent
prot_seq::type_id::create(“my_seq”); Monitor
my_seq.start(dut_agent.sequencer);
Sequencer
… Driver
endtask prot DUT
endclass
© Mentor Graphics Corporation, all rights reserved.
Adding a Layer
• From “above,” the layer looks like a UVC
• Run sequence(s) on sequencer
• Monitor (analysis_port) to report activity
• Must be able to execute sequences on protocol layer
• But how do we reuse the Protocol Agent?
class myL1_test
prot_test extends uvm_test;
`uvm_component_utils(prot_test)
`uvm_component_utils(myL1_test) This connection is the key

virtual task run_phase(uvm_phase phase);


my_seq = Agent
prot_seq::type_id::create(“my_seq”);
myL1_seq::type_id::create(“my_seq”); L1_mon Monitor
my_seq.start(dut_agent.sequencer);
my_seq.start(my_layer1_sequencer);
L1_seqr Sequencer
… Driver
endtask L1 bkgrd DUT
endclass
© Mentor Graphics Corporation, all rights reserved.
The Translation Sequence
class myXL_seq extends uvm_sequence #(dut_txn);
`uvm_object_utils(myXL_seq)
Generates downstream item
uvm_sequencer #(L1_item) up_sequencer;

virtual task body(); • Translation Sequence runs


L1_item l;
dut_txn d;
Note Syntax
on the lower sequencer
forever begin • Handles the layering connection
up_sequencer.get_next_item(l);
foreach(l.buf[i]) begin • Converts items between layers
d = dut_txn::type_id::create();
start_item(d);
d.data = l.buf[i]; Agent
finish_item(d);
end Monitor
up_sequencer.item_done(); L1_seqr Sequencer
end Sqr
L1
L1 Sqr xlD2
bkgrd
D3
D1 Driver
endtask DUT
endclass
© Mentor Graphics Corporation, all rights reserved.
The Analysis Path
class D2L_monitor extends uvm_subscriber #(dut_txn);
`uvm_component_utils(D2L_monitor)
Provides analysis_export
uvm_analysis_port#(L1_item) ap;
… • Eachlayer uses a
function new(string name, uvm_component parent); reconstruction monitor
super.new(name, parent); • The “inverse” of the translation
ap = new("ap",this); sequence
endfunction
• Assembles high-level items
function void write(dut_txn d);
from lower-level items
// reconstruction code omitted ...
ap.write( L1_out ); Agent
... L1_mon
L1
endfunction Monitor
D2
D1
D3

endclass Sequencer
Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


The Layered Agent
class L2P_layer extends uvm_subscriber #(dut_txn);
`uvm_component_utils(L2P_layer)

uvm_analysis_port#(L1_item) ap;
L1_monitor mon;
uvm_sequencer#(L1_item) seqr;
myXL_seq xlseq;
dut_agent d_agent;

function void build_phase(uvm_phase phase);
seqr = uvm_sequencer#(L1_item)::type_id::create(“L1_seqr”, this);
mon = L1_monitor::type_id::create(“L1_mon”, this);
ap = new(“ap”, this);
... L2P Agent
endfunction L1_mon Monitor
L1_seqr Sequencer
Driver
DUT
endclass
© Mentor Graphics Corporation, all rights reserved.
The Layered Agent
class L2P_layer extends uvm_subscriber #(dut_txn);
`uvm_component_utils(L2P_layer)

function void connect_phase(uvm_phase phase);


mon.ap.connect(ap);
analysis_export.connect(mon.analysis_export);
endfunction

virtual task run_phase(uvm_phase phase);


xlseq = myXL_seq::type_id::create(“xl_seq”);
xlseq.up_sequencer = seqr;
xlseq.start(d_agent.seqr);
endtask L2P Agent
endclass L1_mon Monitor
L1_seqr Sequencer
Sqr xl Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


The Layered Agent: The Environment
class layer_env extends uvm_env;
`uvm_component_utils(layer_env)
• Connect components as usual

L2P_layer layer_agent;
dut_agent d_agent;

function void connect_phase(uvm_phase phase);


layer_agent.d_agent = d_agent;
d_agent.ap.connect(layer_agent.analysis_export);
endfunction
endclass

B2L L2P Agent


L2_mon L1_mon Monitor
L2_seqr L1_seqr Sequencer
Sqr xl Sqr xl Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


The Multi-Layered Agent
• Encapsulate as many layers as needed
• Make intermediate analysis_ports available as needed
• From “above” it just looks like an Agent

B2L
B2P L2P Agent
L2_mon L1_mon Monitor
L2_seqr L1_seqr Sequencer
Sqr xl Sqr xl Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


Internal Protocol Agent
class B2D_agent extends uvm_component;
`uvm_component_utils(C2P_agent)


dut_agent d_agent;

function void build_phase(uvm_phase phase);

d_agent = dut_agent::type_id::create(“d_agent”, this);
...
endfunction
endclass
B2D
B2P Agent
L2_mon L1_mon Monitor
L2_seqr L1_seqr Sequencer
Sqr xl Sqr xl Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


Layering Architecture Summary
• Layering agent has a child sequencer for every non-leaf-level
• Creates and starts a translator sequence for every non-leaf-level
• Translator sequence started on lower-layer sequencer
• Translator sequence points back to higher-layer sequencer
• May include a reconstruction monitor for each non-leaf-level
• Must have a handle to the leaf-level protocol agent
• Agent may be a child of the UVC or external
• Should create and connect an analysis_port for each monitor
• Will usually have a configuration object associated with it
B2D
B2P Agent
L2_mon L1_mon Monitor
L2_seqr L1_seqr Sequencer
Sqr xl Sqr xl Driver
DUT

© Mentor Graphics Corporation, all rights reserved.


Advanced UVM
Layered Sequences

Tom Fitzpatrick
Verification Evangelist

info@verificationacademy.com | www.verificationacademy.com

You might also like