Sending data from monitor to sequence

Hi chr_sue,

I tried this logic in my passive monitor and my sequence. In my passive monitor, I kept a display message after triggering the data, and I’m getting that display message. I tried the same logic in my sequence too. But my simulation is blocking, after getting the display message from my passive monitor. Please help me.

I’ve a doubt. Do we need to use the same transaction class handle in both monitor and sequence (in this case, it’s “req”), while using this event_pool ??

// --------------------- monitor run phase method ------------------------ //

task run_phase(uvm_phase phase);
	//forever
		begin
			txn = rx_txn ::type_id::create("txn");
                            txn.array = {10,20,30,40,50}; //assigning some dummy data to my transaction class, as DUT is not yet ready!
		
	 `uvm_info("RX_MON_DATA", $sformatf("DATA sending from RX MONITOR is : [%p] \n", txn.array),UVM_LOW) // data {10,20,30,40,50} is printing
            ev = ev_pool.get("mon_ev");
            //uvm_event ev = ev_pool.get("mon_ev");
                ev.trigger(txn);
              `uvm_info("TRIGGER_DATA", $sformatf("DATA triggered in  RX Monitor"),UVM_LOW) //This display is printing , after that simulation is getting blocked/hanged!! 

		end
endtask : run_phase

// --------------------- sequence ------------------------ //

class rx_reset_seq extends rx_base_seq;
uvm_event_pool ev_pool = uvm_event_pool::get_global_pool();
uvm_event ev;

`uvm_object_utils(rx_reset_seq)

function new(string name = "rx_reset_seq");
	super.new(name);
            ev=new("ev");
endfunction

task body();
	req = rx_txn ::type_id::create("req");
            //uvm_event ev = ev_pool.get("mon_ev");
            ev = ev_pool.get("mon_ev");
           	start_item(req);
	assert(req.randomize());
	finish_item(req);
            ev.wait_trigger();
            $cast(req, ev.get_trigger_data());

// How to print my data here ?? ie., how can I print my sent data here ?? ie., {10,20,30,40,50}
endtask : body

endclass

Hi chr_sue,
Please see my code, and help me, if I’m doing wrong …
Do we need to create a separate class for uvm_event by extending from uvm_object ?? or not necessary ??
Anticipating a favourable reply from you at the earliest.

In reply to SV_UVM_Learner:

Please try this code. It is only slidely modified:

// --------------------- monitor run phase method ------------------------ //
class driver extends uvm_driver #(txn);

  ....
  uvm_event_pool ev_pool = uvm_event_pool::get_global_pool();

task run_phase(uvm_phase phase);
//forever
  begin
    txn = rx_txn ::type_id::create("txn");
    txn.array = {10,20,30,40,50}; //assigning some dummy data to my transaction class, as DUT is not yet ready!

    `uvm_info("RX_MON_DATA", $sformatf("DATA sending from RX MONITOR is : [%p] \n", txn.array),UVM_LOW) // data {10,20,30,40,50} is printing
    uvm_event ev = ev_pool.get("mon_ev");  //creates the event "mon_event" 
    ev.trigger(txn);
    `uvm_info("TRIGGER_DATA", $sformatf("DATA triggered in RX Monitor"),UVM_LOW) //This display is printing , after that simulation is getting blocked/hanged!!

  end
endtask : run_phase

// --------------------- sequence ------------------------ //

class rx_reset_seq extends rx_base_seq;
  uvm_event_pool ev_pool = uvm_event_pool::get_global_pool();
  uvm_event ev;

  `uvm_object_utils(rx_reset_seq)

  function new(string name = "rx_reset_seq");
    super.new(name);
  endfunction

task body();
  req = rx_txn ::type_id::create("req");
  //uvm_event ev = ev_pool.get("mon_ev");
  ev = ev_pool.get("mon_ev");
  start_item(req);
  assert(req.randomize());
  finish_item(req);
  ev.wait_trigger();
  $cast(req, ev.get_trigger_data());
  `uvm_info("DATA FROM MON", $sformatf("DATA received from RX MONITOR is : [%p] \n", req.array),UVM_LOW) 
endtask : body

endclass

Thanks a lot for your quick response.
Can we use different transaction class handles in monitor and sequence?? Like here, txn in monitor and req in sequence??

In reply to SV_UVM_Learner:

txn and req are only the names. We have to use the same types.

Hi chr_sue,

I’ve used the above code. Still the simulation is getting blocked. After getting the display message from passive monitor, simulation is getting blocked.

Is there any alternate method to pass data from my passive monitor my active agent’s sequence ?? Can we use TLM ports in this scenario ??

In reply to SV_UVM_Learner:

You should find out why the simulation is blocked. Did you receive the expected data in the sequence?

No, I haven’t received the expected data in my sequence.

In reply to SV_UVM_Learner:

Looks like you did not see the event. This might be the reason. Could you check for this, displaying the event in your waves window.

OK. I’ll check it and update you.

Is there any alternate method to pass data from my passive monitor my active agent’s sequence ?? Can we use TLM ports in this scenario ??

In reply to SV_UVM_Learner:

Of course you can use a port/export TLM mechanism. But this is not a good solution. Events and barriers are dedicated for synchronisation across several agents.

In reply to SV_UVM_Learner:

OK. I’ll check it and update you.
Is there any alternate method to pass data from my passive monitor my active agent’s sequence ?? Can we use TLM ports in this scenario ??

I can give you a working example for your problem. Please give me an email address.

Hi chr_sue,

Thanks a lot for your continuous support. I’ve achieved my task of sending data from my RX Passive monitor to TX sequence and also to TX Monitor by using uvm_event_pool.

In reply to SV_UVM_Learner:

can you please send your testbench , or code itself ?? . I also want to achieve same thing , but failed to understand , how to do it ?
YOUR testbench might be of great help

In reply to DV@Engineer :

Could you please explain what your problem is? I think you have seen my contributions above. This works.

In reply to SV_UVM_Learner:

Another solution:

In passive agent there is a monitor, which has analysis port.
So from your active agent, subscribe to to that analysis port and get the data from that port.

you can keep and analysis port reference in config db.

In reply to haykp:

There are always several solutions for a problem. But I do not believe it is a good solution to have a permanent horizontal connection between different agents. Additionally this limits the reusability of your agents.
Putting the data to the config_db generates another problem: you do not know when the data are in the config_db.

In reply to chr_sue:

Thakn chr_sue for comments

In reply to srikanth.verification:

whenever there will be change in interrupt, monitor needs to send the data to sequence and then i can perform register operations from the monitor status
Please look this code and share your valuable feedback

//////////////transaction class
class interrupt_transaction extends uvm_sequence_item;

  `uvm_object_utils(interrupt_transaction)
    rand bit [3:0] interrupt;

extern function new (string name = "interrupt_transaction");

endclass

function interrupt_transaction::new(string name = "interrupt_transaction");
   super.new(name);
endfunction


class interrupt_mon extends uvm_monitor;
//////////////////////factory registration/////////////////////
  `uvm_component_utils(interrupt_mon)

  //////////////////////virtual interface //////////////////////

  virtual mcu_status_if intr_vif;
  interrupt_transaction intr_txn;
  function new(string name="interrupt_mon", uvm_component parent);
    super.new(name, parent);
  endfunction : new

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    intr_txn = interrupt_transaction::type_id::create("intr_txn");

  endfunction : build_phase


  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
  endfunction : connect_phase

  task run_phase(uvm_phase phase);
   forever 
      @(posedge intr_vif.McuClk);
      begin
        intr_txn.interrupt = intr_vif.Interrupt;
`uvm_info("DATA FROM MON", $sformatf("DATA received from Interrupt MONITOR is : [%p] \n", intr_txn.interrupt),UVM_LOW)
      end
   endtask : run_phase
  function void report_phase(uvm_phase phase);
     `uvm_info(get_type_name(), "Interrupt Entering into Monitor", UVM_LOW)
  endfunction
endclass


//////////////////////////Sequence////////////////////////////////////////
class interrupt_sequence extends base_seq;
   
  `uvm_object_utils (interrupt_sequence)
 
  interrupt_transaction intr_item;

  function new(string name = "interrupt_sequence");
    super.new(name);
  endfunction

  task body();
    intr_item = interrupt_transaction::type_id::create("intr_item");
    start_item(intr_item);
    assert(intr_item.randomize());
    finish_item(intr_item);
    
    `uvm_info("DATA FROM MON", $sformatf("DATA received from Interrupt MONITOR is : [%p] \n", intr_item.interrupt),UVM_LOW)
   if i get the status from monior then i can perform the register operations, please help me to achieve this
/////////////////////////read interrupt controller status 
///////////////////////// check intialization is completed or not MCUINITDONE in MCUCL_Reg spec/////
//////////////////////// if it is set mask the init_mask_parm by setting it to 1

    
   
  endtask
endclass

The driver doesn’t get a transaction using the event methodology discussed here .

Get_next_item - gets a req in the driver which is initialized and doesn’t get the value that we expect . This is using the uvm_do_on .