Can a register model be connected to 2 different adapters/agents ? One agent for write and another for read?

I have a register model and I would like to use the register adapter in my environment. Looking at examples, I see that I can connected the register model with a register adapter to a single agent for read and writes. But, what if one agent can before the writes, while another agent performs reads. How would I set this up in my environment?

In reply to VerifEx:

I have a register model and I would like to use the register adapter in my environment. Looking at examples, I see that I can connected the register model with a register adapter to a single agent for read and writes. But, what if one agent can before the writes, while another agent performs reads. How would I set this up in my environment?

I’m not exactly sure that you need two adapters (or if that is possible), I’d say you can use a virtual sequencer that has handles to both agents’ sequencer (this would execute the specific sequencer depending on the operation to be performed), and you could use the set_sequencer() function from the API, which according to the documentation

set_sequencer() Set the sequencer and adapter associated with this map. This method must be called before starting any sequences based on uvm_reg_sequence.”

HTH

-R

In reply to rgarcia07:

Are you sure you want to access the register model from 2 different agents.
I do not know who is teaching this, but I see in several examples people do differentiate between RD and WR agent, but they are connected to the same interface. But finally they do not need this, because you can read and write from 1 agent.
Dou have different agents connected to different Interfaces?

In reply to VerifEx:

Yeah you can do it.Provided you should define two memory maps in the ral model and in the environment with two adapters.Using set_sequencer,you set that particular adapter,sequencer and that particular memory map for each adapter.It will work.While writing virtual sequence,you can take care such that write sequence will run on one sequencer a x the read sequence on the other.

In reply to chr_sue:

In reply to rgarcia07:
Are you sure you want to access the register model from 2 different agents.
I do not know who is teaching this, but I see in several examples people do differentiate between RD and WR agent, but they are connected to the same interface. But finally they do not need this, because you can read and write from 1 agent.
Dou have different agents connected to different Interfaces?

Yes, there are two different agents and two different interfaces.

In reply to VerifEx:

If you have 2 seperate Interfaces and want to perfrom RAL operations with both,
then all you need to have 

1. A adaptor for each interface 

2. A register_map for each interface  
	uvm_reg_map map1, map2; 

   //Create both the maps
   map1 = create_map(.name("map1"), .base_addr('h0), .n_bytes(4), .endian(UVM_LITTLE_ENDIAN));
   map2 = create_map(.name("map2"), .base_addr('h0), .n_bytes(4), .endian(UVM_LITTLE_ENDIAN));

   //Add the register/s to both the maps
   map1.add_reg( .rg(REG1), .offset(8'h0), .rights("RW"));
   map2.add_reg( .rg(REG1), .offset(8'h0), .rights("RW"));
	
3. Provide connetion of each reg_map to its own adapter & sequencer
    h_env.h_reg_block.map1.set_sequencer(.sequencer(h_agt_1.h_seqr),.adapter(h_agt_1.h_adapter));
    h_env.h_reg_block.map2.set_sequencer(.sequencer(h_agt_2.h_seqr),.adapter(h_agt_2.h_adapter));
	
    //also you need to set predictor's map,adapter,ap 
	
4. Specify the needed map while performaing write/read 

   h_env.h_reg_block.REG1.write( op_status, 'hAB,  .path(UVM_FRONTDOOR), .map(map1), .parent(null));   
   h_env.h_reg_block.REG1.read ( op_status, rd_data,  .path(UVM_FRONTDOOR), .map(map2), .parent(null));

In reply to tejastv:

I just wanted to thank you all for the discussion and the good ideas!

I want to contribute with my two cents.
I find that this option discussed here is of big importance in the scenario of vertical reusability. I want to make it clear for those who haven´t seen it. It is a little bit different to the case exposed here.

Now, think about a scenario where you have verified a sub-module A which has e.g. protocol VC AHB to access its registers. You have written your scoreboard and your custom/quirky register classes for that AHB protocol and HDL level.
Then, you have at top module which is a wrapper of this sub-module A which has the same registers (and maybe more for other subblocks), but it uses a different VC protocol e.g. AXI. to access those registers. In other words, internally it will be converted from AXI to AHB.

In that scenario and for vertical reusability, you would like to just reuse your scoreboard and quirky register predictions.
You would like to just write/read your registers using AXI VC in your master sequence and use the predictions you already coded for AHB.
You know that inside the DUT you have the AHB interface for your subblock and you can reuse your scoreboard and the predictions of your registers.
Well, what you can do is to bind a module and interface (spy/backdoor the interface) inside the DUT and get the intern AHB monitor interface in the configdatabase.
Then, in your environment you can connect an AHB VC to that spied interface and use the scoreboard or the AHB adapter to predict correctly the AXI access to the registers. You can do this by following the indications of tejastv on the previous post.
In this case, your use one map and one AXI adapter for the master sequence (this AXI VC should not update the registermodel but just use the adapter to do reg2bus conversions-explicit prediction conf), and the second map and the second AHB adapter to connect the register predictor (which will do the real update and prediction of the register values from the AHB bus using explicit prediction).

Therefore, i think this post has touched a good point and it makes sense to do this.

See UVM Cookbook for More information

In reply to tejastv:

Hi,

In this case consider h_agt_1 as AHB and h_ag2 as SPI.

h_env.h_reg_block.map1.set_sequencer(.sequencer(h_agt_1.h_seqr),.adapter(h_agt_1.h_adapter)); h_env.h_reg_block.map2.set_sequencer(.sequencer(h_agt_2.h_seqr),.adapter(h_agt_2.h_adapter));

Assume that offsets to access REG1 is different.

h_env.h_reg_block.REG1.write( op_status, 'hAB, .path(UVM_FRONTDOOR), .map(map1), .parent(null)); // AHB Write
h_env.h_reg_block.REG1.read ( op_status, rd_data, .path(UVM_FRONTDOOR), .map(map2), .parent(null)); //SPI Write

Will REG1 mirrored value will be same?
Is that mean there in only REG1 in model physically but we can access the register with different interfaces. Because in real SoC there will be only 1 physical register but different interfaces access register with different offsets.

Please suggest.