UVM Register Model array of dissimilar blocks

Hi,
I’m fairly new to UVM, so not sure if I can achieve what I want.

I’m trying to create a register model of my design. The design has many repeated blocks, where each block will have a common set of base registers, and then some blocks have unique registers. It’s all done with VHDL for…generate and if…generate statements.

What I’m trying to achieve in UVM is basically an array with a single index, but each item in the array might be a different type.

Here’s a simplified example.

Let’s say my design may have 4 different registers, called RegA, RegB, RegC, and RegD.

Then, I have 3 different blocks.

Block 1 has Registers RegA and RegB
Block 2 has Registers RegA, RegB, and RegD
Block 3 has Registers RegA, RegB, and RegC

The address map for each block is the same, that means:

RegA is always at adress 0x0 (+ the repeating offset)
RegB is always at address 0x4 (+ the repeating offset)
RegC, if present, is at address 0x8 (+ the repeating offset)
RegD, if present, is at address 0xC (+ the repeating offset)

Now, say in my design, I have 3 blocks of Block 1, 3 blocks of Block 2, and 3 blocks of Block 3. So I have 9 blocks in total.

The question I have is: Is there a way in UVM to make a single toplevel block that is an array with indexes from 0 to 8, where index 0,1,2 are Block 1, index 3,4,5 are Block 2, and index 6,7,8 are Block 3?

My thoughts are to:

  1. Make a Block1 base class
  2. Make Block2 extend Block1 and add RegD
  3. Make Block3 extend Block1 and add RegC
  4. Make a top level block that has a 9 element array of Block1
  5. When building the array, for the first 3 elements use the Block1 base class “create”, for the next 3 elements, use Block2 “create”, and for the last 3 use Block3 “create”

The goal would be in the testbench side to use the register model as follows:

top_block regs;

regs.my_blocks[0].RegA.write(… ← This should work okay, RegA is always present
regs.my_blocks[3].RegD.write(… ← This should work because the 4th block is of type 2 and has RegD
regs.my_blocks[3].RegC.write(… ← shouldn’t work, there is no RegC in the 4th block as it’s type 2.

My first cut at this didn’t work (the register model compiled okay, it was the testbench code that complained). The complaint was along the lines of:

Could not find field/method name (RegD) in ‘my_blocks’ of ‘regs.my_blocks[3].RegD.write’.

So I’m looking for some help, is this just some UVM syntax issue and I’m on the right path, or is what I’m trying not going to be possible with the register model?

Thanks,

Dave