The Finer Points of UVM: Tasting Tips for the Connoisseur
John Aynsley, Doulos
The Finer Points of UVM
Sequences and sequencers
The arbitration queue
Virtual sequences
Request and response
Multiple sequencer stacks
The Big Picture
uvm_env
uvm_agent
Sequences and Sequencers
start_item(req); finish_item(req);
TLM export TLM port
seq_item_port.get(req);
A Simple Sequence
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
5
Nested Sequences
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")
Variable that points to sequencer
seq.start(p_sequencer, this); end endtask Sequencer Parent sequence ...
6
Concurrent Sequences
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 Transactions will be strictly interleaved endtask
7
The Finer Points of UVM
Sequences and sequencers
The arbitration queue
Virtual sequences
Request and response
Multiple sequencer stacks
The Arbitration Queue
Arbitration queue
fork start body start_item finish_item
priority sequence priority sequence
First in
priority sequence
start body start_item finish_item
Arbitration
FIFO
start body start_item finish_item join begin seq_item_port.get(req);
seq_item_port.get(req); seq_item_port.get(req); end
Setting the Arbritration Algorithm
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 Priority (default 100) endtask
10
Arbitration Algorithms
Arbitration mode SEQ_ARB_FIFO SEQ_ARB_RANDOM SEQ_ARB_STRICT_FIFO
Order in which requests granted FIFO order (default) Random order Highest priority first, then FIFO order
SEQ_ARB_STRICT_RANDOM
SEQ_ARB_WEIGHTED SEQ_ARB_USER
Highest priority first, then random order
Weighted by priority User-defined
11
User-Defined Arbitration Algorithm
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
12
Could 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
seqr0
Can be null
vseq.start(seqr0, null, priority) body
No transactions
fork
seqr3 seqr2 seqr1
priority seq1
seq1.start(seqr1, this)
body start_item ...
Blocks Inherits priority
seq2.start(seqr2, this, 50) body start_item
...
14
Sequencer Lock
seqr0
vseq.start(seqr0, null) body
No transactions
begin
Important!
seqr1
this.lock(seqr1);
seq1.start(seqr1, this); body
priority seqx priority seqy priority seq1
start_item
finish_item
this.unlock(seqr1); ...
15
Lock versus Grab
vseq1.start vseq2.start vseq3.start
body
begin lock seq1.start
body
begin lock seq2.start
body
begin grab seq3.start
unlock
unlock
ungrab
Head grab req vseq3 priority seqx priority seqy priority seq2 seq1 lock req vseq2 priority seq3
Tail
Grabs inserted here
Locks inserted here
16
The Finer Points of UVM
Sequences and sequencers
The arbitration queue
Virtual sequences
Request and response
Multiple sequencer stacks
Request and Response
start_item(req);
finish_item(req);
TLM export
get_response(rsp);
req
TLM port
rsp
seq_item_port.get(req); seq_item_port.put(rsp);
The paper describes in detail how to code pipelined req/rsp and out-of-order responses
18
Layered Sequencers
start_item(req);
Ptr to upper sequencer
finish_item(req); get_response(rsp);
req
Could be one:one or one:many or many:one or many:many
rsp
seqr_upper.get(req_up); start_item(req_lo); finish_item(req_lo);
get_response(rsp_lo);
req
req:rsp = 1:1
rsp
seqr_upper.put(rsp_up);
seq_item_port.get(req); seq_item_port.put(rsp);
The paper shows more detail
19
The Finer Points of UVM
Sequences and sequencers
The arbitration queue
Virtual sequences
Request and response
Multiple sequencer stacks
Multiple Agents / Sequencer Stacks
Communicate or synchronize?
Analysis ports Callbacks Events Barriers
get(req)
Driven by the DUT interface timing
Must not block!
21
Driver calls try_next_item
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 cycle
Must be called in same time step
Response can be pipelined
22
The Finer Points of UVM
Also in the paper
The UVM sequence library Pipelined requests and responses The response handler UVM events and event pools
The configuration database