We have already seen how to use `uvm_do
set of macros. They automatically create a new object via calls to `uvm_create
, randomize the item and send it to a sequencer. If we already have a data object that we simply want to send to a sequencer, we can use `uvm_send
. There are different variations to this macro, just like `uvm_do_*
.

First, let's look into an example to see how `uvm_send
is different from `uvm_do
. Testbench environment is already in place, and we'll simply use a sequence to contain the calls to `uvm_send
and `uvm_do
. The main difference is that `uvm_send
will NOT create or randomize while `uvm_do
will do both.
class seq1 extends base_sequence;
`uvm_object_utils (seq1)
seq2 m_seq2;
my_data m_data0; // This data object will be created by us
my_data m_data1; // This data object will be left to uvm_create to create
my_data m_data2; // Will be used with `uvm_send
virtual task pre_start ();
`uvm_info (get_type_name (), "Executing pre_start()", UVM_MEDIUM)
endtask
function new (string name = "seq1");
super.new (name);
m_data0 = my_data::type_id::create ("m_data0");
endfunction
virtual task body ();
starting_phase.raise_objection (this);
`uvm_info ("SEQ1", "Starting seq1", UVM_MEDIUM)
// req already exists, but is not instantiated/new()'d. Calling uvm_do will internally
// call `uvm_create and generate the object, randomize it and send to sequencer
`uvm_info ("SEQ1", "uvm_do (req) - Create, randomize and send req", UVM_MEDIUM)
`uvm_do (req)
// If uvm_do is called again, then the same object will be randomized again and sent
`uvm_info ("SEQ1", "uvm_do (req) - Randomize again, and send", UVM_MEDIUM)
`uvm_do (req)
// m_data0 is already created above; so its randomized and sent
`uvm_info ("SEQ1", "uvm_do (m_data0) - Data already exists, simply randomize and send", UVM_MEDIUM)
`uvm_do (m_data0)
// m_data1 was not created above, so it will be created, randomized and sent
`uvm_info ("SEQ1", "uvm_do (m_data1) - Data was not created, so create it, randomize and send", UVM_MEDIUM)
`uvm_do (m_data1)
// req already exists, but will not be randomized
`uvm_info ("SEQ1", "uvm_send (req) - req already exists from previous create, Send it without randomization", UVM_MEDIUM)
`uvm_send (req)
`ifdef RUNTIME_ERR
// m_data2 was not created, and will not be created - Runtime Error !
`uvm_send (m_data2)
`enddif
`uvm_info ("SEQ1", "uvm_send (req) - Manually create, randomize and send", UVM_MEDIUM)
// Create the object, randomize it and send to sequencer
`uvm_create (m_data2)
void'(m_data2.randomize ());
`uvm_send (m_data2)
`uvm_info ("SEQ1", "uvm_send_pri (req) - Send with priority", UVM_MEDIUM)
`uvm_send_pri (m_data2, 72)
`uvm_info ("SEQ1", "Ending seq1", UVM_MEDIUM)
// Start the next sequence - will be discussed later
`uvm_do (m_seq2)
starting_phase.drop_objection (this);
endtask
endclass
---------------------------------------------------------------- CDNS-UVM-1.1d (14.22-s009) (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 - @2644 m_top_env my_env - @2709 m_drv0 my_driver - @2754 rsp_port uvm_analysis_port - @2854 seq_item_port uvm_seq_item_pull_port - @2803 m_seqr0 my_sequencer - @2885 rsp_export uvm_analysis_export - @2944 seq_item_export uvm_seq_item_pull_imp - @3492 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(90) @ 0: uvm_test_top.m_top_env.m_drv0 [my_driver] Applying initial reset UVM_INFO ./tb/my_pkg.sv(94) @ 390000: uvm_test_top.m_top_env.m_drv0 [my_driver] DUT is now out of reset UVM_INFO ./tb/my_pkg.sv(155) @ 390000: uvm_test_top.m_top_env.m_seqr0@@seq1 [seq1] Executing pre_start() UVM_INFO ./tb/my_pkg.sv(165) @ 390000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] Starting seq1 UVM_INFO ./tb/my_pkg.sv(169) @ 390000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_do (req) - Create, randomize and send req ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- req my_data - @3648 data integral 8 'he2 addr integral 8 'hde begin_time time 64 390000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(173) @ 410000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_do (req) - Randomize again, and send ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- req my_data - @3700 data integral 8 'hc addr integral 8 'hc0 begin_time time 64 410000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(177) @ 430000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_do (m_data0) - Data already exists, simply randomize and send ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- m_data0 my_data - @3711 data integral 8 'h74 addr integral 8 'h50 begin_time time 64 430000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(180) @ 450000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_do (m_data1) - Data was not created, so create it, randomize and send ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- m_data1 my_data - @3721 data integral 8 'h43 addr integral 8 'h88 begin_time time 64 450000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(184) @ 470000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_send (req) - req already exists from previous create, Simply send it without randomization ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- req my_data - @3700 data integral 8 'hc addr integral 8 'hc0 begin_time time 64 470000 end_time time 64 430000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(192) @ 490000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_send (req) - Manually create, randomize and send ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- m_data2 my_data - @3749 data integral 8 'hd5 addr integral 8 'h46 begin_time time 64 490000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(198) @ 510000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] uvm_send_pri (req) - Send with priority ---------------------------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------------------------- m_data2 my_data - @3749 data integral 8 'hd5 addr integral 8 'h46 begin_time time 64 510000 end_time time 64 510000 depth int 32 'd2 parent sequence (name) string 4 seq1 parent sequence (full name) string 35 uvm_test_top.m_top_env.m_seqr0.seq1 sequencer string 30 uvm_test_top.m_top_env.m_seqr0 ---------------------------------------------------------------------------------- UVM_INFO ./tb/my_pkg.sv(200) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1 [SEQ1] Ending seq1

In the example above, we have seen how sequence items are sent via `uvm_send
. Note that you had spawned seq2 towards the end of seq1. Below is the definition for seq2, which inturn calls seq3 multiple times using the different variations of `uvm_send_*
. Note that we also have the option to randomize and send an item or sequence using `uvm_rand_send_*
.
class seq2 extends base_sequence;
`uvm_object_utils (seq2)
seq3 m_seq3;
function new (string name = "seq2");
super.new (name);
m_seq3 = seq3::type_id::create ("m_seq3");
endfunction
virtual task pre_body ();
`uvm_info (get_type_name(), "Executing pre_body", UVM_MEDIUM)
endtask
virtual task body ();
`uvm_info ("SEQ2", "Starting seq2", UVM_MEDIUM)
// Send a sequence via uvm_send
`uvm_info ("SEQ2", "uvm_send (m_seq3) - Send sequence", UVM_MEDIUM)
`uvm_send (m_seq3)
// Add priority to uvm_send
`uvm_info ("SEQ2", "uvm_send_pri (m_seq3, 9) - Send with Priority", UVM_MEDIUM)
`uvm_send_pri (m_seq3, 9)
`uvm_info ("SEQ2", "uvm_rand_send (m_seq3) - Send after randomization", UVM_MEDIUM)
`uvm_rand_send (m_seq3)
`uvm_info ("SEQ2", "uvm_rand_send_pri (m_seq3, 8) - Send with priority after randomization", UVM_MEDIUM)
`uvm_rand_send_pri (m_seq3, 8)
`uvm_info ("SEQ2", "uvm_rand_send_with (m_seq3, {data == 4; addr == 23;) - Send with randomization constraints", UVM_MEDIUM)
`uvm_rand_send_with (m_seq3, { m_data3.data == 8'h4;
m_data3.addr == 8'h23;})
`uvm_info ("SEQ2", "Ending seq2", UVM_MEDIUM)
endtask
virtual task post_body ();
`uvm_info (get_type_name(), "Executing post_body", UVM_MEDIUM)
endtask
endclass
To show that a sequence can also be randomized via macros, we have seq3 containing a data item declared as rand. So, calling `uvm_rand_send_*
should randomize m_data3 within seq3, while `uvm_send
will not randomize it.
class seq3 extends base_sequence;
`uvm_object_utils (seq3)
rand my_data m_data3;
function new (string name = "seq3");
super.new (name);
m_data3 = my_data::type_id::create ("m_data3");
endfunction
virtual task body ();
`uvm_info ("SEQ3", "Starting seq3", UVM_MEDIUM)
m_data3.print (uvm_default_table_printer);
`uvm_info ("SEQ3", "Ending seq3", UVM_MEDIUM)
endtask
endclass
UVM_INFO ./tb/my_pkg.sv(227) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] Starting seq2 UVM_INFO ./tb/my_pkg.sv(230) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] uvm_send (m_seq3) - Send sequence UVM_INFO ./tb/my_pkg.sv(270) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Starting seq3 ------------------------------ Name Type Size Value ------------------------------ m_data3 my_data - @3777 data integral 8 'h0 addr integral 8 'h0 ------------------------------ UVM_INFO ./tb/my_pkg.sv(272) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Ending seq3 UVM_INFO ./tb/my_pkg.sv(234) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] uvm_send_pri (m_seq3, 9) - Send with Priority UVM_INFO ./tb/my_pkg.sv(270) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Starting seq3 ------------------------------ Name Type Size Value ------------------------------ m_data3 my_data - @3777 data integral 8 'h0 addr integral 8 'h0 ------------------------------ UVM_INFO ./tb/my_pkg.sv(272) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Ending seq3 UVM_INFO ./tb/my_pkg.sv(237) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] uvm_rand_send (m_seq3) - Send after randomization UVM_INFO ./tb/my_pkg.sv(270) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Starting seq3 ------------------------------ Name Type Size Value ------------------------------ m_data3 my_data - @3777 data integral 8 'h61 addr integral 8 'h31 ------------------------------ UVM_INFO ./tb/my_pkg.sv(272) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Ending seq3 UVM_INFO ./tb/my_pkg.sv(240) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] uvm_rand_send_pri (m_seq3, 8) - Send with priority after randomization UVM_INFO ./tb/my_pkg.sv(270) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Starting seq3 ------------------------------ Name Type Size Value ------------------------------ m_data3 my_data - @3777 data integral 8 'ha2 addr integral 8 'h9f ------------------------------ UVM_INFO ./tb/my_pkg.sv(272) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Ending seq3 UVM_INFO ./tb/my_pkg.sv(243) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] uvm_rand_send_with (m_seq3, {data == 4; addr == 23;) - Send with randomization constraints UVM_INFO ./tb/my_pkg.sv(270) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Starting seq3 ------------------------------ Name Type Size Value ------------------------------ m_data3 my_data - @3777 data integral 8 'h4 addr integral 8 'h23 ------------------------------ UVM_INFO ./tb/my_pkg.sv(272) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2.m_seq3 [SEQ3] Ending seq3 UVM_INFO ./tb/my_pkg.sv(247) @ 530000: uvm_test_top.m_top_env.m_seqr0@@seq1.m_seq2 [SEQ2] Ending seq2 UVM_INFO ./tb/my_pkg.sv(118) @ 530000: uvm_test_top.m_top_env.m_drv0 [my_driver] Finished DUT simulation --- UVM Report catcher Summary ---