Accessing Registers With UVM-RAL

Directly access registers by name from the testbench, without having to know where and what they are.


As a digital design or verification engineer you know that certain features or configurations of the device can be achieved by programming some registers to set values. For example, a 32-bit register can have several fields within it and each field can represent a particular feature that can be configured. The device then reads that register and uses that information to change settings or modes.

However, this proves to be easier said than done. For instance, when I worked as a digital designer, I worked on a design where several modes could be defined in software. So, when I needed to change a control register, I would figure out where in the memory the register resided, and then use CPU operations to read high level commands (to control the DMA controller) to access and write to that memory. This approach worked back in the day and remains valid today for small projects. But what if there are several hundreds of such registers? Here is such an arrangement of registers, called the register block.

A normal SoC has one or more cores, peripherals, and bus interfaces. Each module will have its own register block. So now you can see how, with just with a few modules, you are looking at thousands of registers you may need to access. The combination of such register blocks is called a memory map. Now imagine trying to write instructions from a higher level to access these registers. The first problem is the sheer number of registers. Second, not all the registers are the same length. Thirdly, and a particularly challenging problem, is that not all registers can be accessed with the same protocol. Each peripheral has its own protocol for accessing such registers.

This is why we have a UVM Register Abstraction Layer (UVM-RAL). It attempts to mirror the values of the design registers in the testbench, so you can easily use the register model to access those registers. The RAL, being at a higher level of abstraction, does not need to know what protocol or type of register you are trying to access. So, from the testbench, you can directly access the registers by name, without having to know where and what they are. All of that information is stored in the Register Model, which contains details of all the registers and the type and the location of the registers. If you want to learn more about the RAL you can read this blog: UVM Register Layer: The Structure.

Now, if you have not heard of the UVM-RAL before you might be thinking: “Hey, wait a minute; you just said that there are thousands of registers that can be part of a design. How am I going to write the model for that many registers?”

This is where the Register Model generator feature in Riviera-PRO comes in handy. Using the latest 2018.02 version of Riviera-PRO now you can generate register models from csv or IPXACT-based xml files.

The register_generator commands takes such csv files and generates a register model that you can use as part of your RAL testbench.

As you can see, the generator will generate the Register model files that you can incorporate into your UVM environment to use the RAL of UVM. This eliminates the redundant work required to create these register models and creates a well formatted code that you can easily import into your testbench. If you haven’t tried it out, go ahead and try out the register_generator command in the 2018.02 version of Riviera-PRO and let us know what you think of it.

Leave a Reply

(Note: This name will be displayed publicly)