Can the monitor communicate with the sequence directly?

Hi,

The sequence I should run next will depend on the signals being monitored on the interface.
Therefore I want to know if there is a way for the monitor to directly communicate with the sequence.

If the above is not possible, Is this option a good one?

Monitor will send info to the driver, with an analysis export in the driver and the driver will send the information using RSP.

Regards
ramuk

In reply to ramuk:

Hi Ramuk,

Use the Virtual sequencer concept.In the Virtual sequencer instantiate one common monitor(state monitor). From the UVC Monitor, pass the necessary signals to the state monitor.

Now in the Sequence use the virtual sequencer.
In sequence :

`uvm_declare_p_sequencer(v_sequencer)

if(p_sequencer.state_monitor.signal_name == 1’b1)
//trigger next sequence.

Thanks,
-Murali

In reply to muralikrishna229:

Hi Murali krishna,

Thank you for the reply. Could you please elaborate " From the UVC Monitor, pass the necessary signals to the state monitor."
How should the UVC monitor pass information to the state monitor.

Thanks in advance

Regards
Ramuk

Hi Ramuk,

Use the Virtual sequencer concept.In the Virtual sequencer instantiate one common monitor(state monitor). From the UVC Monitor, pass the necessary signals to the state monitor.

Now in the Sequence use the virtual sequencer.
In sequence :

`uvm_declare_p_sequencer(v_sequencer)

if(p_sequencer.state_monitor.signal_name == 1’b1)
//trigger next sequence.


Now to pass the signal name from the uvm monitor to the state monitor.

In UVC monitor:
class uvm_monitor();
uvm_analysis_port #() ap_uvm_monitor;

function new();
ap_uvm_monitor = new();
endfunction

task run_phase();
signal_requred_seq_item seq_item.
seq_item.signal_name_a = a;//(getting from interface)
seq_item.signal_name_b = b;//getting from interface


ap_uvm_monitor.write(seq_item);
endtask
endclass

IN UVC AGENT:

class uvm_agent;
uvc_monitor mon;
uvm_analysis_port ap_agent;//declare one local analysis port

in connect phase:
monitor.ap_uvc_monitor.connect(ap_agent)

endclass

IN STATE MONITOR:
class state monitor();
uvm_analysis_export ap_export;

bit signal_name_a;
bit signal_name_b;

function void write(signal t);
this.signal_name_a = t.signal_name_a;
this.signal_name_b = t.signal_name_b;


endfunction
endclass

IN TOP LEVEL ENV
//instantiate uvc_agent;
//instantiate state_monitor;

in connect phase;
connect uvc agent’s analysis port to state monitors analysis export

Thanks,
-Murali

Thanks,
-Murali

In reply to muralikrishna229:

Thanks for the detailed description.

Regards
Ramuk

I have some more suggestions exploiting the advantage of UVM_CONFIG_DB

Since you are talking of interface signal (an example given in the cookbook for your reference) you can make the functions that can sit on that signal as follow:

IN UVM AGENT CONFIG you have the pointer to interface through config_db and virtual interface:
This task is a convenience method for sequences waiting for the interrupt
*// signal
task spi_env_config::wait_for_interrupt;
@(posedge INTR.IRQ);
endtask: wait_for_interrupt

// Check that interrupt has cleared:
function bit spi_env_config::is_interrupt_cleared;
if(INTR.IRQ == 0)
return 1;
else
return 0;
endfunction: is_interrupt_cleared*

so in the virtual sequence since you get the config of the agent to map the sequencer to sequences so these functions are available there as well:

// Get config
if(!uvm_config_db #(spi_env_config)::get(null, {“uvm_test_top.”, get_full_name()}, “spi_env_config”, m_cfg)) begin
`uvm_error(“body”, “Cannot find spi_env_config”)
end

// Sequence body:
*fork
begin
m_cfg.wait_for_interrupt;
wait_unload.start(apb);
if(!m_cfg.is_interrupt_cleared()) begin
`uvm_error(“INT_ERROR”, “Interrupt not cleared by register read/write”);
end
end
*

P.S: Refer cookbook example for its details**

Other way can be since you set the pointer of your interface in the uvm_config_db in your tb_top so you can get the same from uvm_config and access any signal you want.

Note: This is non recommended way but I am writing here to explain the way flexibility of use.

//---------- TB Top--------------------//
// UVM initial block:
// Put virtual interfaces into the resource db & run_test()
*initial begin
uvm_config_db #(virtual apb_if)::set(null, “uvm_test_top”, “APB_vif”, APB);
uvm_config_db #(virtual spi_if)::set(null, “uvm_test_top”, “SPI_vif”, SPI);
*

// -------- Sequence ----------//
// Interrupt Virtual Interface - used in the wait for interrupt task
//
virtual intr_if INTR;
if(!uvm_config_db #(virtual spi_if)::get(this, “”, “SPI_vif”, m_spi_cfg.SPI)) begin
`uvm_error(“RESOURCE_ERROR”, “SPI virtual interface not found”)
end

Hi Murali,

Can we use a normal sequencer, not a ‘virtual sequencer’?
A monitor can be instantiated in a normal sequencer. Am I right?

Regards,
Reuben

You should NEVER have any interface or other type of monitor connected to a sequencer or virtual sequencer. A sequence should only generate stimulus based on random generation or a response received from the connected driver.

In reply to cgales:

You should NEVER have any interface or other type of monitor connected to a sequencer or virtual sequencer. A sequence should only generate stimulus based on random generation or a response received from the connected driver.

Hi cgales,

Does this mean that a response should only be received from the driver?
Can you explain further what are the disadvantages of having interface or monitor connected to a sequencer? I have that kind of architecture before, and it works fine. I don’t know maybe it only works in my situation but not in general situations. So that’s why I want to know what could be the disadvantages of that.

Regarding using a driver to pass the response to a sequencer, the disadvantage I see here is that the code to sample the response should be present on both the driver and the monitor… For example, let’s say the protocol is SPI. For a read command, the monitor needs to sample the read data, while the driver also needs to sample the read data. So you need to write two codes for sampling the read data… Managing two sets of codes can be time consuming. Usually these two codes are not identical since the driver and the monitor operates differently. So you cannot create one function for the sampling of read data then use it in both the driver and the monitor.

Kindly advice what could be the disadvantages of using a monitor to pass the response to the sequencer.

Regards,
Reuben

In reply to Reuben:

The reason for using the standard UVM topology of sequencer-driver connection and standalone monitor has to due to ensuring that component reuse is maintained.

The sequencer-driver part of the UVC should be able to operate independently of any other component. If the sequence is generating a read transaction, the driver should generate a response to the sequencer with the read value so that the sequencer can use the response data to potentially influence the next sequence item. Since everything is transaction based, there is the potential that your monitor items aren’t synchronized properly.

While there is some duplication of code between the driver and monitor, this is required to ensure UVC reuse.

In reply to cgales:

In reply to Reuben:
The reason for using the standard UVM topology of sequencer-driver connection and standalone monitor has to due to ensuring that component reuse is maintained.
The sequencer-driver part of the UVC should be able to operate independently of any other component. If the sequence is generating a read transaction, the driver should generate a response to the sequencer with the read value so that the sequencer can use the response data to potentially influence the next sequence item. Since everything is transaction based, there is the potential that your monitor items aren’t synchronized properly.
While there is some duplication of code between the driver and monitor, this is required to ensure UVC reuse.

I see. Thanks for the info.

In reply to cgales:

I have a question on this. What would be the recommended approach for a virtual sequence that uses slave sequences when the agent is in passive mode? An example of this would be if we want to send a sequence item to the driver on Agent A, based on a received sequence item on Agent B’s bus. If Agent B is in passive mode i.e. we are at subsystem level and there is no longer a driver-sequencer, how can we possibly receive a sequence item from this agent in order to drive the other agent?

For Agent B at block level, the driver would have to send transactions and response data, so that would work fine. When we then connect up another component, the driver can no longer send transactions and it’s up to the monitor to report on what’s going on for this Agent’s bus. So how can we possibly have Agent A’s sequencer knowing about Agent B’s bus activity without a connection between monitor and sequence? Is it advised that we create a new driver instead for subsystem level?

In reply to sdexter:

If you have a passive agent you can connect your monitor through a port with the rsp_export of your sequencer. Via this connection you can pass back transactions from the monitor to your sequencer.

In reply to chr_sue:

Since I posted my question I came up with a solution that does not break the “monitor is for analysis only” mentality, which is to essentially create a second driver called “slave_driver”. This will listen to the bus and communicate with a slave sequence, which can then be used to driver other sequences on a different bus. The original driver is then (preferably) renamed “master_driver”.

Therefore there are now two sequencers created in the agent of the same type, one for master transactions and one for slave transactions. The master can be disabled in passive mode, and another bit can be used in configuration to enable or disable the slave driver.

Let me know what you think of this approach. It seemed preferable to me, since it draws from the same thinking behind the example described in Sequences/Slave

In reply to sdexter:

Whar are you doing is one solution. I’d prefer another one.
My solution is to use 2 differennt agents, 1 master agent and 1 slave agent working on the same interface. Then you do not have to make your master agent passive.

BTW this does not mean your solution is bad. And there are no UVM compliant rules, i.e. you have all the freedom.

In reply to chr_sue:

I suppose in my case the “slave driver” is actually more of a monitor that communicates with a sequence. The master driver is the only component/interface that can actually drive signals, so when the agent is in passive mode i.e. subsystem level, the master driver and sequencer are off and the “slave driver/responder” or monitor-for-the-sequence and sequencer are on along with the monitor. The slave driver then has the sole purpose of communicating with sequences, and the monitor has the sole purpose of sending to an analysis export to coverage collector/scoreboard etc.

It’s essentially the same as your first suggestion with the monitor connected to the sequencer, but splitting out the two functionalities into two components. In retrospect, it does seem preferable to only have to use two BFM interfaces per agent rather than three in my case.

In reply to chr_sue:

Sorry if passive agent than there should not supposed to be sequecer.

In reply to haykp:

I did not say you can send the rsp to the passive sequences. You can send it anywhere.