In How to create and use a sequence, we saw that a sequence calls on the tasks start_item() and finish_item(). You can avoid putting all these statements in your code by simply calling UVM sequence macros `uvm_do or `uvm_do_with. At compile time, these macros will be substituted with calls to start_item() and finish_item(). There are primarily four types of UVM macros that can be executed on the default sequencer.


Macros `uvm_do_*

You have to provide a uvm_sequence_item object or a sequence and internally, it will do the following:

  1. create the item if necessary using `uvm_create. If you don't want it to create an item, use `uvm_send.
  2. randomize the item or sequence
  3. call the start_item() and finish_item() if its a uvm_sequence_item object
  4. call the start() task if its a sequence

  • `uvm_do : execute this sequence on default sequencer with the item provided
  • `uvm_do_with : override any default constraints with inline values.
  • `uvm_do_pri : execute based on the priority value, used when running multiple sequences simultaneously.
  • `uvm_do_pri_with: execute based on priority and override default constraints with inline values

`uvm_do_* macros will identify if the argument provided is a sequence or a sequence item and will call start() or start_item() accordingly.


Example

The sequence below will generate four items, randomize them and send to driver - See simulation results !


class base_sequence extends uvm_sequence #(my_data);
	`uvm_object_utils (base_sequence)
	
	...
	virtual task body ();
      `uvm_info ("BASE_SEQ", $sformatf ("Starting body of %s", this.get_name()), UVM_MEDIUM)
      `uvm_do (req)
      `uvm_do_with (req, { data == 8'h4e;
                           addr == 8'ha1; })
      `uvm_do_pri (req, 9)
      `uvm_do_pri_with (req, 3, { data == 8'hc5; })
      `uvm_info ("BASE_SEQ", $sformatf ("Sequence %s is over", this.get_name()), UVM_MEDIUM)
   endtask
	...
endclass

The variable req is already declared and defined in the parameter for the sequence class. So, req is of the type my_data. The `uvm_do_* macros will utilize a default in-built sequencer called m_sequencer. If you want the sequence to be executed on some other user-defined sequencer, you have to call `uvm_do_on_* macros as shown below :


`uvm_do_on          (SEQ_OR_ITEM, SEQR)
`uvm_do_on_pri      (SEQ_OR_ITEM, SEQR, PRIORITY)
`uvm_do_on_with     (SEQ_OR_ITEM, SEQR, CONSTRAINTS)
`uvm_do_on_pri_with (SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS)

Structure

uvm_do macros ultimately call uvm_do_on_pri_with

Note : All the macros are coded using `define within UVM, and each of them calls `uvm_do_on_pri_with with appropriate arguments. For example,


`define uvm_do (SEQ_OR_ITEM) 
	`uvm_do_on_pri_with (SEQ_OR_ITEM, m_sequencer, -1 {})
	
`define uvm_do_on_with (SEQ_OR_ITEM, SEQR, CONSTRAINTS) 
	`uvm_do_on_pri_with (SEQ_OR_ITEM, SEQR, -1, CONSTRAINTS)

Simulation Results

 CDNS-UVM-1.1d (14.10-s013)
(C) 2007-2013 Mentor Graphics Corporation
(C) 2007-2013 Cadence Design Systems, Inc.
(C) 2006-2013 Synopsys, Inc.
(C) 2011-2013 Cypress Semiconductor Corp.
----------------------------------------------------------------
UVM_INFO @ 0: reporter [RNTST] Running test base_test...
UVM_INFO @ 0: reporter [UVMTOP] UVM testbench topology:
------------------------------------------------------------
Name                     Type                    Size  Value
------------------------------------------------------------
uvm_test_top             base_test               -     @2636
 m_top_env              my_env                  -     @210
 m_drv0               my_driver               -     @204
 rsp_port           uvm_analysis_port       -     @2840
 seq_item_port      uvm_seq_item_pull_port  -     @2789
 m_seqr0              my_sequencer            -     @2739
 rsp_export         uvm_analysis_export     -     @2930
 seq_item_export    uvm_seq_item_pull_imp   -     @3478
 arbitration_queue  array                   0     -
 lock_queue         array                   0     -
 num_last_reqs      integral                32    'd1
 num_last_rsps      integral                32    'd1
 m_seqr1              uvm_sequencer           -     @2871
 rsp_export         uvm_analysis_export     -     @3565
 seq_item_export    uvm_seq_item_pull_imp   -     @4105
 arbitration_queue  array                   0     -
 lock_queue         array                   0     -
 num_last_reqs      integral                32    'd1
 num_last_rsps      integral                32    'd1
------------------------------------------------------------  UVM_INFO ./tb/my_pkg.sv(96) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Applying initial reset
UVM_INFO ./tb/my_pkg.sv(100) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] DUT is now out of reset
UVM_INFO ./tb/my_pkg.sv(107) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(173) @ 390000: uvm_test_top.m_top_env.m_seqr1@@seq1 [seq1] Starting body of seq1
UVM_INFO ./tb/my_pkg.sv(120) @ 410000: uvm_test_top.m_top_env.m_drv0 [DRV] Driving data item across DUT interface
req: (my_data@4206) {
 data: 'hfb
 addr: 'h38
 begin_time: 390000
 depth: 'd2
 parent sequence (name): seq1
 parent sequence (full name): uvm_test_top.m_top_env.m_seqr1.seq1
 sequencer: uvm_test_top.m_top_env.m_seqr1
}
UVM_INFO ./tb/my_pkg.sv(107) @ 410000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(120) @ 430000: uvm_test_top.m_top_env.m_drv0 [DRV] Driving data item across DUT interface
req: (my_data@4256) {
 data: 'h4e
 addr: 'ha1
 begin_time: 410000
 depth: 'd2
 parent sequence (name): seq1
 parent sequence (full name): uvm_test_top.m_top_env.m_seqr1.seq1
 sequencer: uvm_test_top.m_top_env.m_seqr1
}
UVM_INFO ./tb/my_pkg.sv(107) @ 430000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(120) @ 450000: uvm_test_top.m_top_env.m_drv0 [DRV] Driving data item across DUT interface
req: (my_data@4187) {
 data: 'hd8
 addr: 'h2d
 begin_time: 430000
 depth: 'd2
 parent sequence (name): seq1
 parent sequence (full name): uvm_test_top.m_top_env.m_seqr1.seq1
 sequencer: uvm_test_top.m_top_env.m_seqr1
}
UVM_INFO ./tb/my_pkg.sv(107) @ 450000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(120) @ 470000: uvm_test_top.m_top_env.m_drv0 [DRV] Driving data item across DUT interface
req: (my_data@4339) {
 data: 'hc5
 addr: 'h8
 begin_time: 450000
 depth: 'd2
 parent sequence (name): seq1
 parent sequence (full name): uvm_test_top.m_top_env.m_seqr1.seq1
 sequencer: uvm_test_top.m_top_env.m_seqr1
}
UVM_INFO ./tb/my_pkg.sv(107) @ 470000: uvm_test_top.m_top_env.m_drv0 [my_driver] Waiting for data from sequencer
UVM_INFO ./tb/my_pkg.sv(179) @ 470000: uvm_test_top.m_top_env.m_seqr1@@seq1 [seq1] Sequence seq1 is over
UVM_INFO ./tb/my_pkg.sv(126) @ 470000: uvm_test_top.m_top_env.m_drv0 [my_driver] Finished DUT simulation  --- UVM Report catcher Summary ---
[/pre]