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 ---