Shared Register Access in RAL though multiple physical interfaces
Posted by Amit Sharma on 19th September 2010
Amit Sharma, Synopsys
Usually, designs have a single interface but some designs may have more than one physical interface, each with accessible registers or memories. RAL supports designs with multiple physical interfaces, as well as registers and memories shared across multiple interfaces.
In RAL, a physical interface is called a domain. Only blocks and systems can have domains. Domains can contain registers and memories.
Now, how do you enable a register or a memory to be shared across multiple physical interfaces or ‘domains’ in RAL? This is done by declaring the register/memory as ‘shared’ in the RALF file and instantiating it in more than one domain. Once this is done, the functionality will be enabled in the generated RAL model.
Let us take an example. Suppose the design block has two domains or interfaces (say pci/ahb) which can have a shared access to the register STATUS. This can be specified through the ‘shared’ keyword in the register description in RALF file, generating a RAL block model, as follows.
In the example above, the text box on the left shows a snippet of the generated code. You can see that ‘domain’s do not create an additional level of hierarchy. The different registers belonging to the two domains in the block are available in the flat namespace in the block and can be accessed directly without specifying the domain name in the access hierarchy.
Once a register is defined as ‘shared’, I can go ahead and access that register through different domains. A typical usage scenario for a ‘shared’ register is that it can be read from one interface and written from another interface. The two different physical BFMs are mapped to the corresponding domains easily in the SV environment.
The following snippet of code how this is done:
this.ahb = new(…); // AHB BFM instantiation
this.ral.add_xactor(this.ahb, "ahb"); //tying the AHB BFM to the “ahb” domain
this.pci = new(…); // PCI BFM instantiation
this.ral.add_xactor(this.pci, "pci"); //tying the PCI BFM to the “pci” domain
Once the mapping is done, the way you access a specific ‘shared’ register is quite simple. You need to additionally specify the ‘domain’ name in your read/write task
When you make the writes/reads as described above, the accesses would be routed through the different BFMs corresponding to the different domains as specified through the ‘domain’ argument in the read/write access tasks as seen in the code specified in the textbox above.
In the test environment, if simulation is run with ‘trace’ or ‘debug’ verbosity , details of the access to the shared register through different domains can be observed.
The following lines shows a snippet of messages going to STDOUT
//———
Trace[DEBUG] on RVM RAL Access(Main) at 135:
Writing ‘h00000000000000aa at ‘h0000000000000A004 via domain "pci"…
Trace[DEBUG] on RAL(register) at 245:
Wrote register "ral_model.INT_MASK" via frontdoor with: ‘h00000000000000aa
Trace[DEBUG] on RVM RAL Access(Main) at 355:
Read ‘h00000000000000aa from ‘h0000000000000002 via domain "ahb"…
Trace[DEBUG] on RAL(register) at 355:
Read register "ral_model.INT_MASK" via frontdoor: ‘h00000000000000aa
//———
By the way, one of the pre-defined tests that ship with the VMM RAL is the "shared_access" test. It exercises all shared registers and memories using the following process for each domain (requires at least one domain with READ capability or backdoor access).
- Write a random value via one domain
- Check the content via all other domains.
Hence, without writing a single line of test code, you can verify the basic functionality of all shared registers/memories of your DUT through this test.
Posted in Register Abstraction Model with RAL, Uncategorized, vmm_xactor | 1 Comment »