I have the below requirement with respect to RAL implementation
Say, i have a register with address 'h01
Module which has this register is instantiated “4” times and hence there are totally “4” physical register with the same address 'h01
To access the registers in different module instances, different interfaces are used.
Say, Reg_Addr_0, Reg_Addr_1, Reg_Addr_2, Reg_Addr3
If Reg_Addr_0 interface is driven then register in the 0th module instance will be updated and so on.
How to implement the RAL for this type of requirement?
The way you’d do it is to define a register block for the module registers:
class module_reg_block extends uvm_reg_block;
some_reg_type SOME_REG;
endclass
In your system, you since the module is instantiated 4 times you’ll need 4 instances of the register block:
class system_reg_block extends uvm_reg_block;
module_reg_block module_regs[4];
// ...
virtual function void build();
for (int i = 0; i < 4; i++) begin
module_regs[i] = module_reg_block::type_id::create("...");
module_regs[i].build();
module_regs[i].map(default_map, i * offset);
end
endfunction
endclass
The ‘i * offset’ factor allows you to control where the specific register block gets mapped. Indirectly this will affect where each instance of the containing regs gets mapped.
How do we redirect say the write(module_regs[2],…) to its specific physical interface?
I have a case where register module is instanced multiple times. RAL is autogenerated.
So there is top_reg_block for the RAL and lower level reg_block that has reg_0_0/reg_0[0] (instance_0), reg_0_1/reg_01 and so on.