uvm_reg_frontdoor – Register access for more complex frontdoors

In UVM there are two ways of connecting the register model to UVM agents that operate on the design under test. One is using the register adapter, uvm_reg_adapter. What that class does is to convert from a register model sequence item to a sequence item that can be used by our UVM agent’s sequencer. That works well if there is a one-to-one relationship between the register access and the transactions of the UVM agent. When we need a more complex use of the UVM agent to facilitate the register access, the register adapter falls short. This might be in cases when the source of the register access is not the UVM agent we are using, but it originates from somewhere inside the design under test which we only have indirect access to. Think about a DMA inside a larger system, where we use the UVM agent to configure the DMA to do the access we want. To do this we would need to map the register access to a series of transactions from the UVM agent. In those cases, the UVM register frontdoor sequence, uvm_reg_frontdoor, is the king.
The uvm_register_frontdoor looks like a normal uvm_sequence apart from having the uvm_reg_item rw_info that holds information about the register access. Like if the access is read or write, what the address offset of the access is and a handle to the reqister or memory the access was made to. 
In the picture above you will see how recognizable the uvm_reg_frontood sequence is, with the body task where the work is done. This is where you will assemble the sequence items and send them to the driver using the send_request function. You also see that in my example the kind variable of the rw_info element is used to decide whether the transaction is a read transaction or not. 

What is next is that we need to connect the frontdoor sequence to the register model and to the sequencer of the UVM agent it is using. As opposed to the register adapter there is not any shortcut to connect the front door to all memories and registers in the register model. So, the user have to do it manually. I recommend this method for doing it:
Connecting it to the sequencer can simply be done by running set_sequencer on the map you want the register map to be frontdoor to be associated with. Like this:

2 responses to “uvm_reg_frontdoor – Register access for more complex frontdoors”

  1. Carter Avatar
    Carter

    Thank you for great posting about uvm_reg_frontdoor.

    I think uvm_reg_frontdoor is used to the massive memory burst transaction.
    But what if I need to control a pipelined driver like the AHB, then the adapter also needs to be pipelined to connect with register to check the register value directly, but the adapter can’t be pipelined.

    I’m not sure whether the uvm_reg_frontdoor also can be used in my case or not.

    Like

  2. eivindf Avatar
    eivindf

    Hi Carter.

    Most handling of the pipeline will usually be handled by the driver. This requires the driver to be able to get uvm_sequence_item 2 before uvm_sequence_item 1 is done. So if you are in the position where you are not able to provide the driver with the second sequence item in a timely manner as your sequence waiting for 2 to finish, there are several ways to do that. I will present one:

    Say you want interface to the register model in a way that allows you to have a single read or write map to multiple burst of the transaction on the bus. I.E you have a 32-bit transaction and do a 128 bit write using the register model. The rw_info item in the will contain the information needed for the operation. This is related to the burst_write and burst_read method of uvm_mem. After that your task would be to arrange and schedule the sequence items that are forwarded to the driver. I suggest you to look up the start_item(), finish_item() and get_response() methods to see how the interaction between the sequence and the driver is. If you are able to structure the driver so that the get_next_item() and item_done() tasks are done in the address phase of the burst, while put(rsp) is done in the data phase, you will be able to arrange multiple start_item() calls in the sequence before the data phase has finished.

    Does this answer your question?

    Eivind

    Like

Leave a reply to Carter Cancel reply