Hi,
I’m working on validating an IP which has AXI as main interface. TB has two different sequencers one for AXI read channel and one for AXI write channel to drive txns independently.
So, i want reg model to select appropriate rd_sequencer or wr_sequencer based on whether its a read access or write access. is this possible ?
should i create two different reg maps one for read and one for write and do connections as below or is there a better way?
Hi,
I’m working on validating an IP which has AXI as main interface. TB has two different sequencers one for AXI read channel and one for AXI write channel to drive txns independently.
So, i want reg model to select appropriate rd_sequencer or wr_sequencer based on whether its a read access or write access. is this possible ?
should i create two different reg maps one for read and one for write and do connections as below or is there a better way?
My understanding is, for a single set of registers(instances), multiple reg_maps can exists.
reg_maps are used to calculate final adress (map_base_addr+reg_offset).Ex., if an IP has multiple interfaces, and base address of IP could be different through different interfaces. This requires two different reg_maps. You can write through one interface and read through other interface, read will reflect write value even though maps are different.
I realized in this scenario its better to use uvm_frontdoor_seq instead of ral adapter. Any ral access invocation will call user defined seq extended from uvm_frontdoor_seq, where we can perform the register access normally through frontdoor.
Only reason to separate out rd and wr sequencer is to maintain the independent nature of AXI Wr and Rd channels. I think this can be achieved through single sequencer by forking off(join_none) driver code for Wr and Rd tasks and using semaphores to block task reentry until previous Rd/Wr are done. In this case there wont be any issue with RAL.
If you have 2 separate interfaces for Write and Read then you would have 2 sequencer , one sequencer for each interface .
Generally the built-in sequencer is used as it is , how do you intend to add semaphore to it ? . Also this won’t duplicate the independent nature of the channels
In reply to srikanthvvs1: You ALWAYS need an adapter for Frontdoor Access
I think not necessary. Adapter is used by RAL to convert write/read calls to specific sequence item and execute that on the registered sequencer. This is one method to do it.
In second method(which i just came to know) you register the user defined frontdoor sequence with ral. When read/write task is invoked on a register, ral will directly execute frontdoor sequence. In this sequence you will explicitly do what adapter does(usign rw_info variable available in uvm_frontoor_seq). After that call uvm_do on the sequence items, if write select wr_sequencer if read select read_sequencer.
In reply to srikanthvvs1:
If you have 2 separate interfaces for Write and Read then you would have 2 sequencer , one sequencer for each interface .
Generally the built-in sequencer is used as it is , how do you intend to add semaphore to it ? . Also this won’t duplicate the independent nature of the channels
I mean in the driver task not in sequencer.
task drive_wr_txn(txn t);
wr_sema.get();
fork
begin
//driver code
wr_sema.put()
end
join_none //if a read pkt exists in driver tlm fifo this wont block that
endtask
…
Just a general idea. Should see if it really works.
I think not necessary. Adapter is used by RAL to convert write/read calls to specific sequence item and execute that on the registered sequencer. This is one method to do it.
ral_model.apb_map.set_sequencer(apb_vip.apb_seqr, apb_reg_adapter);
What’s the second argument to set_sequencer ? Isn’t that the adapter ?
Regarding the User-defined Frontdoor I am not aware on it’s internal working so won’t be able to comment on it .
Just a general idea. Should see if it really works.
Do update us once you have a complete working code .
Using 1 sequencer/driver pair supports the independent RD/WR channels.
Depending on the access type you can either execute the WR or the RD part in the driver. Tere ios no metaphore needed, because you cannot WR and RD at the same time.
Yes , I do agree with that . Since the Write and Read channel are independent , there should be 2 Driver - Sequencer pair ( one pair for each channel ) .
Oh sorry I didn’t read your previous reply correctly .
I was of the belief that via 2 driver-sequencer pair we could initiate Write and Read transfers in parallel .
Write could target a different register and read could target a different register at the same time thereby replicating the independent channel behavior.
The independence will be controlled by the sequences.
I didn’t get this . Do you intend to send read and write transactions in sequence via fork join ? The driver on receiving a sequence item would either send a write OR read transaction on the channel .
With a single pair how can we replicate a scenario where both accesses are initiated at same time
I believe this is incorrect ( Feel free to correct me ) .
The AXI Specification doesn’t restrict such concurrent accesses .
I discussed this with a few friends ( one of them used to work in VIP team for AXI ) and both of them agreed with concurrent write and read access being legal .
After all they are called independent channels in the specification .
The following is from AXI 3 Specification .
9.1 About the data buses
The AXI protocol has two independent data buses, one for read data and one for write data.
Because these data buses have their own individual handshake signals, it is possible for data
transfers to occur on both buses at the same time.
I’m not so familiar with the AXI. But I was asking earlier if a concurrent access is possible and did not get a clear answer.
Wrt to the spec you are showing here we need definitely 2 agents with independent sequencer/driver pairs.
While discussing with the friend with VIP experience he pointed to a few things ::
(1) If we go with multiple driver-sequencer pair approach ::
(a) There would be different sequence items for write and read .
So write channels driver-sequencer pair would use write sequence item .
(b) Write and read sequence would be different and they would be started in parallel from test .
(2) If we go with single driver-sequencer pair ::
(a) Single sequence_item would encapsulate all write and read properties
The single driver-sequencer pair would use it for parameterization .
(b) Single sequence would exist for write and read and it would be started in test ( unlike parallel sequences (1)(b) )
Post-discussion I agree that we can go with single driver-sequencer pair as well.