UVM way of passing information from the monitor to a sequence of an agent

Hi All,

is there a UVM way to pass information from a monitor to a sequence running on a sequencer
inside of the same agent?

I was thinking about adding a “uvm_analysis_export” to my sequencer and connecting it to
a “uvm_analysis_port” of my monitor.
But I’ve seen an implementation which is using a uvm_event in order to get the transaction
from the monitor into a sequence.

So my question is which way should I go from here?
What is the difference between a uvm_analysis_port implementation in opposite to a
uvm_event based implementation?

Thanks for any advice,

Frodus

  1. define a uvm_tlm_analysis_fifo in your sequence

uvm_tlm_analysis_fifo #(requence_item) item_collected_fifo;

  1. define a uvm_tlm_analysis_fifo and a uvm_analysis_export in some component such as config or test, then build and connect them

uvm_analysis_export #(sequence_item) item_collected_port;
uvm_tlm_analysis_fifo #(sequence_item) item_collected_fifo;

function void build_phase(uvm_phase phase);
super.build_phase(phase);
item_collected_port = new(“item_collected_port”,this);
item_collected_fifo = new(“item_collected_fifo”,this);
endfunction

function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
item_collected_port.connect(item_collected_fifo.analysis_export);
endfunction

  1. connect your component’s uvm_analysis_export(step 2) and monitor’s uvm_analysis_port in agent

function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
monitor.item_collected_port.connect(your_component.item_collected_port);
endfunction

  1. connect your seq’s item_collected_fifo(step 1) and component’s item_collected_fifo(step) in test or top

function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
your_seq.item_collected_fifo = your_component.item_collected_fifo;
endfunction

  1. now you can use “item_collected_fifo” define in sequence to get items from monitor

item_collected_fifo.get(req);

In reply to frodus:

Here is the sequence …

class rb_mem_response_seq extends uvm_sequence #(rb_seq_item);

function new(string name=“rb_mem_response_seq”);
super.new(name);
endfunction

rand logic [`DMA_FIELD_RANGE] rb_mem_data;

uvm_object_utils(rb_mem_response_seq) uvm_declare_p_sequencer(rb_slave_seqr)

rb_seq_item util_transfer;

virtual task body();
uvm_info(get_type_name(), "Starting...", UVM_MEDIUM) forever begin *p_sequencer.addr_trans_port.peek(util_transfer);* uvm_info(“RB_SEQ_EVENT_WATCHER”, $psprintf(“Starting wait_trigger: %m \n%s”,
util_transfer.sprint()), UVM_HIGH)
if(util_transfer.direction == DMA_READ)

Here is the code for the monitor
// Allows the sequencer to look at monitored data for responses
uvm_blocking_peek_imp#(rb_seq_item, rb_mntr) addr_trans_export;

// collect_transactions
task rb_mntr::run_phase(uvm_phase phase);

//-> trans_addr_grabbed;
trans_addr_grabbed.trigger();
`uvm_info("RB_MNTR_EVENT_WATCHER", $psprintf("Starting trigger : %m "), UVM_DEBUG);

// You need to implement this peek method to pass information from the monitor to a sequence of an agent
task rb_mntr::peek(output rb_seq_item trans);
//@trans_addr_grabbed;
trans_addr_grabbed.wait_trigger();
`uvm_info(“RB_MNTR_EVENT_WATCHER”, $psprintf("Starting wait_trigger : %m "), UVM_DEBUG);
trans = rb_item;
endtask : peek

In reply to liuchao:

Hi. I see that this is how the transaction goes:

From monitor → (some other component) → then to the sequence class

Why not just from monitor directly to the sequence class since a monitor is also a component?

In reply to Reuben:

Hi,

Can someone help me with this one? I’m trying to do the sugestion of liuchao but I’m only passing the transaction directly from the monitor to the sequence, without using any other component.
This is what I did:


// In monitor class
uvm_analysis_export #(packet) to_fifo; 
uvm_tlm_analysis_fifo #(packet) item_collected_fifo; 

// In build_phase
to_fifo = new("to_fifo", this);
uvm_tlm_analysis_fifo #(packet) item_collected_fifo;

// In connect phase
to_fifo.connect(item_collected_fifo.analysis_export);

// In run_phase
item_collected_fifo.write(spi_tr);


// In sequence class
uvm_tlm_analysis_fifo #(packet) item_collected_fifo;


// In test class
// In connect phase
seq.item_collected_fifo = env.sentEnv.e_agent.sent_mon.item_collected_fifo;

It is compiling but I’m not getting the data. Actually I tried to do the item_collected_port.size in the monitor to see if the size increments after doing the to_fifo.write(spi_tr), but it remains 0.
What’s the problem with this one?

In reply to liuchao:

Hi,

What is the use of doing this?
I mean I never use this concept before but please let me know where I can use this in my project.

Thanks,
Sayam

In reply to Reuben:

Looks a little bit confusing.
What is the reason of the analysis export in the monitor?
The sequence is atransient object it will be created at any time and disappears when it has been executed.

See this post for a working example:

https://verificationacademy.com/forums/uvm/sending-data-monitor-sequence#reply-74938

In reply to Reuben:

I don’t think this is the good way to send data from monitor to sequence. However, it seems your approach will work. In fact, you collect the transactions to analysis fifo in monitor and your sequence will refer this fifo (points the object to monitor). Your problem happened maybe because of the timing.
Please check again your sequence to make sure it will not be finished before the transactiom is captured in your monitor.

  1. Your sequence sends trans to driver to drive dut signals. It will be finished as soon as the transaction is being drived completely in driver.

  2. It will take time for your monitor to capture the transaction in interface signals after transaction is being drived in driver.