John Aynsley, Doulos
The Finer Points of UVM:
Tasting Tips
for the Connoisseur
The Finer Points of UVM
• Sequences and sequencers
• The arbitration queue
• Virtual sequences
• Request and response
• Multiple sequencer stacks
The Big Picture
3
uvm_envuvm_env
uvm_agentuvm_agent
Sequences and Sequencers
4
TLM exportTLM export
TLM portTLM port
start_item(req);
finish_item(req);
seq_item_port.get(req);
A Simple Sequence
5
class my_seq extends uvm_sequence #(my_tx);
`uvm_object_utils(my_seq)
function new(string name = "");
super.new(name);
endfunction: new
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
Nested Sequences
6
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 sequenceParent sequenceSequencerSequencer
Variable that points to sequencerVariable that points to sequencer
Concurrent Sequences
7
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 interleavedTransactions will be strictly interleaved
The Finer Points of UVM
• Sequences and sequencers
• The arbitration queue
• Virtual sequences
• Request and response
• Multiple sequencer stacks
The Arbitration Queue
9
priority
sequence
priority
sequence
priority
sequence
priority
sequence
priority
sequence
priority
sequence
Arbitration queueArbitration queue
First inFirst in
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
FIFOFIFO
join
end
Setting the Arbritration Algorithm
10
task body;
p_sequencer.set_arbitration(
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)Priority (default 100)
Arbitration Algorithms
11
Arbitration mode Order in which requests granted
SEQ_ARB_FIFO FIFO order (default)
SEQ_ARB_RANDOM Random order
SEQ_ARB_STRICT_FIFO Highest priority first, then FIFO order
SEQ_ARB_STRICT_RANDOM Highest priority first, then random order
SEQ_ARB_WEIGHTED Weighted by priority
SEQ_ARB_USER User-defined
User-Defined Arbitration Algorithm
12
class my_sequencer extends uvm_sequencer #(my_tx);
...
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 objectCould access properties of the sequence object
The Finer Points of UVM
• Sequences and sequencers
• The arbitration queue
• Virtual sequences
• Request and response
• Multiple sequencer stacks
Virtual Sequences
14
priority
seq1
priority
seq1
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
Blocks
Inherits priority
Blocks
Inherits priority
seqr0 Can be nullCan be null
No transactions
Sequencer Lock
15
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);
...
priority
seqx
priority
seqx
priority
seqy
priority
seqy
priority
seq1
priority
seq1
Important!Important!
Lock versus Grab
16
priority
seqx
priority
seqx
priority
seqy
priority
seqy
vseq1.start
body
begin
lock
seq1.start
unlock
vseq2.start
body
begin
lock
seq2.start
unlock
vseq3.start
body
begin
grab
seq3.start
ungrab
lock req
vseq2
lock req
vseq2
grab req
vseq3
grab req
vseq3
priority
seq3
priority
seq3
Locks
inserted
here
Locks
inserted
here
Grabs
inserted
here
Grabs
inserted
here
Head Tail
priority
seq1
priority
seq1
priority
seq2
priority
seq2
The Finer Points of UVM
• Sequences and sequencers
• The arbitration queue
• Virtual sequences
• Request and response
• Multiple sequencer stacks
Request and Response
18
TLM exportTLM export
TLM portTLM port
start_item(req);
finish_item(req);
get_response(rsp);
seq_item_port.get(req);
seq_item_port.put(rsp);
req rsp
The paper describes in detail
how to code pipelined req/rsp
and out-of-order responses
The paper describes in detail
how to code pipelined req/rsp
and out-of-order responses
Layered Sequencers
19
seq_item_port.get(req);
seq_item_port.put(rsp);
seqr_upper.get(req_up);
start_item(req_lo);
finish_item(req_lo);
get_response(rsp_lo);
seqr_upper.put(rsp_up);
start_item(req);
finish_item(req);
get_response(rsp);
req rsp
req rsp
Ptr to upper
sequencer
Ptr to upper
sequencer
Could be
one:one or
one:many or
many:one or
many:many
Could be
one:one or
one:many or
many:one or
many:many
The paper shows more detailThe paper shows more detail
req:rsp = 1:1req:rsp = 1:1
The Finer Points of UVM
• Sequences and sequencers
• The arbitration queue
• Virtual sequences
• Request and response
• Multiple sequencer stacks
Multiple Agents / Sequencer Stacks
21
Communicate or
synchronize?
Communicate or
synchronize?
get(req)
Must not
block!
Must not
block!Driven by the DUT interface timingDriven by the DUT interface timing
Analysis ports
Callbacks
Events
Barriers
Analysis ports
Callbacks
Events
Barriers
Driver calls try_next_item
22
seq_item_port.try_next_item(req);
if (req == null)
begin
dut_vi.idle <= 1;
...
@(posedge dut_vi.clock);
end
else
begin
seq_item_port.item_done();
dut_vi.idle <= 0;
...
@(posedge dut_vi.clock);
...
seq_item_port.put(rsp);
Wiggle pins for idle cycleWiggle pins for idle cycle
Must be called in same time stepMust be called in same time step
Response can be pipelinedResponse can be pipelined
The Finer Points of UVM
• The UVM sequence library
• Pipelined requests and responses
• The response handler
• UVM events and event pools
• The configuration database
Also in the paperAlso in the paper

Uvm dcon2013

  • 1.
    John Aynsley, Doulos TheFiner Points of UVM: Tasting Tips for the Connoisseur
  • 2.
    The Finer Pointsof UVM • Sequences and sequencers • The arbitration queue • Virtual sequences • Request and response • Multiple sequencer stacks
  • 3.
  • 4.
    Sequences and Sequencers 4 TLMexportTLM export TLM portTLM port start_item(req); finish_item(req); seq_item_port.get(req);
  • 5.
    A Simple Sequence 5 classmy_seq extends uvm_sequence #(my_tx); `uvm_object_utils(my_seq) function new(string name = ""); super.new(name); endfunction: new 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
  • 6.
    Nested Sequences 6 class top_seqextends 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 sequenceParent sequenceSequencerSequencer Variable that points to sequencerVariable that points to sequencer
  • 7.
    Concurrent Sequences 7 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 interleavedTransactions will be strictly interleaved
  • 8.
    The Finer Pointsof UVM • Sequences and sequencers • The arbitration queue • Virtual sequences • Request and response • Multiple sequencer stacks
  • 9.
    The Arbitration Queue 9 priority sequence priority sequence priority sequence priority sequence priority sequence priority sequence ArbitrationqueueArbitration queue First inFirst in 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 FIFOFIFO join end
  • 10.
    Setting the ArbritrationAlgorithm 10 task body; p_sequencer.set_arbitration( 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)Priority (default 100)
  • 11.
    Arbitration Algorithms 11 Arbitration modeOrder in which requests granted SEQ_ARB_FIFO FIFO order (default) SEQ_ARB_RANDOM Random order SEQ_ARB_STRICT_FIFO Highest priority first, then FIFO order SEQ_ARB_STRICT_RANDOM Highest priority first, then random order SEQ_ARB_WEIGHTED Weighted by priority SEQ_ARB_USER User-defined
  • 12.
    User-Defined Arbitration Algorithm 12 classmy_sequencer extends uvm_sequencer #(my_tx); ... 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 objectCould access properties of the sequence object
  • 13.
    The Finer Pointsof UVM • Sequences and sequencers • The arbitration queue • Virtual sequences • Request and response • Multiple sequencer stacks
  • 14.
    Virtual Sequences 14 priority seq1 priority seq1 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 Blocks Inherits priority Blocks Inherits priority seqr0 Can be nullCan be null No transactions
  • 15.
    Sequencer Lock 15 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); ... priority seqx priority seqx priority seqy priority seqy priority seq1 priority seq1 Important!Important!
  • 16.
    Lock versus Grab 16 priority seqx priority seqx priority seqy priority seqy vseq1.start body begin lock seq1.start unlock vseq2.start body begin lock seq2.start unlock vseq3.start body begin grab seq3.start ungrab lockreq vseq2 lock req vseq2 grab req vseq3 grab req vseq3 priority seq3 priority seq3 Locks inserted here Locks inserted here Grabs inserted here Grabs inserted here Head Tail priority seq1 priority seq1 priority seq2 priority seq2
  • 17.
    The Finer Pointsof UVM • Sequences and sequencers • The arbitration queue • Virtual sequences • Request and response • Multiple sequencer stacks
  • 18.
    Request and Response 18 TLMexportTLM export TLM portTLM port start_item(req); finish_item(req); get_response(rsp); seq_item_port.get(req); seq_item_port.put(rsp); req rsp The paper describes in detail how to code pipelined req/rsp and out-of-order responses The paper describes in detail how to code pipelined req/rsp and out-of-order responses
  • 19.
    Layered Sequencers 19 seq_item_port.get(req); seq_item_port.put(rsp); seqr_upper.get(req_up); start_item(req_lo); finish_item(req_lo); get_response(rsp_lo); seqr_upper.put(rsp_up); start_item(req); finish_item(req); get_response(rsp); req rsp reqrsp Ptr to upper sequencer Ptr to upper sequencer Could be one:one or one:many or many:one or many:many Could be one:one or one:many or many:one or many:many The paper shows more detailThe paper shows more detail req:rsp = 1:1req:rsp = 1:1
  • 20.
    The Finer Pointsof UVM • Sequences and sequencers • The arbitration queue • Virtual sequences • Request and response • Multiple sequencer stacks
  • 21.
    Multiple Agents /Sequencer Stacks 21 Communicate or synchronize? Communicate or synchronize? get(req) Must not block! Must not block!Driven by the DUT interface timingDriven by the DUT interface timing Analysis ports Callbacks Events Barriers Analysis ports Callbacks Events Barriers
  • 22.
    Driver calls try_next_item 22 seq_item_port.try_next_item(req); if(req == null) begin dut_vi.idle <= 1; ... @(posedge dut_vi.clock); end else begin seq_item_port.item_done(); dut_vi.idle <= 0; ... @(posedge dut_vi.clock); ... seq_item_port.put(rsp); Wiggle pins for idle cycleWiggle pins for idle cycle Must be called in same time stepMust be called in same time step Response can be pipelinedResponse can be pipelined
  • 23.
    The Finer Pointsof UVM • The UVM sequence library • Pipelined requests and responses • The response handler • UVM events and event pools • The configuration database Also in the paperAlso in the paper