Issuing concurrent READ/WRITE accesses to the same register on two physical interfaces using RAL.
Posted by S. Varun on 9th August 2010
Currently, RAL does not schedule multiple concurrent READ/WRITE accesses to the same register at the same time. RAL
assumes all physical transactions to be atomic, i.e. a transaction is completed before the next cycle is started.
Even if we try to do a parallel READ, RAL will block one of the two accesses and schedule it sequentially. This is
to ensure that the accesses are not corrupted and also because of the fact that the main idea behind RAL is in
abstracting accesses to the registers.
However, in specific cases, there might be a verification requirement to create specific corner cases on the buses.
A typical corner case to check parallel access to a shared register would be as shown in the code snippet below,
Sample code :
fork
/* READ the CONTROL_REG via the APB interface */
env.ral_model.blk_inst.CONTROL_REG.read(status, data , , "APB");
/* Read the CONTROL_REG via the AHB interface */
env.ral_model.blk_inst.CONTROL_REG.read(status, data , , "AHB");
join
Our intention here is to query the control register from two different domains "APB" & "AHB" in parallel or write
through one interface and do a read access through another. But as already mentioned, a controlling semaphore
mechanism tied to each register will sequentially schedule the above two accesses. To create such corner cases we
can use the RAL proxy transactor with "vmm_ral_access::read/write()" which is not going be blocked as the semaphore
resides in the register. The code below illustrates how we can do this.
Sample code :
fork
/* READ the CONTROL_REG via the APB interface */
env.ral.read(status, env.ral_model.blk_inst.CONTROL_REG.get_address_in_system("APB"), data, 32, "APB");
/* READ the CONTROL_REG via the AHB interface */
env.ral.read(status, env.ral_model.blk_inst.CONTROL_REG.get_address_in_system("AHB"), data, 32, "AHB");
join
The "vmm_ral_reg::get_address_in_system()" method can be used here to generate the correct address corresponding
to the domain of interest and the same can be passed with the "vmm_ral_access::read()/write()" task.
We can also do the following:
1) Read CONTROL_REG through one of the interfaces using "env.ral_model.blk_inst.CONTROL_REG.read()" &
2) Read the same register via vmm_ral_access::read() through the other interface as illustrated in the
sample code below.
Sample code :
fork
/* READ the CONTROL_REG via the APB interface */
env.ral_model.blk_inst.CONTROL_REG.read(status, data , , "APB");
/* READ the CONTROL_REG via the AHB interface */
env.ral.read(status, env.ral_model.blk_inst.CONTROL_REG.get_address_in_system("AHB"), data, 32, "AHB");
join
Because the semaphore is in the register, the access through the proxy transactor is not going to be blocked.
Also, if the DUT and physical transactor supports pipelined read/write accesses, the generic transactions can
also be executed concurrently. You must first enable this capability by defining the compile time macro,
VMM_RAL_PIPELINED_ACCESS.
Posted in Register Abstraction Model with RAL | No Comments »
Weihua Han, CAE, Synopsys