Special register(s) with fields based on a mode

Hi,

I’ve been tasked with modeling a register block for a semi-legacy module that includes a register scheme that I have not come across in RAL literature.

The basic idea is that there exists a register called MODE, say at address 0x0. There are (for example) two registers that “share” the same address, say 0x1, each of which define their own set of fields, some of whom have bit offsets that overlap other “shared” register fields. Depending on how the MODE register is configured, only one interpretation of the SHARED registers is considered “valid”.

e.g.:

MODE: controls how to interpret address 0x1

  • address = 0x0
  • access = RW
  • fields =
    • mode
      • bitOffset = 0
      • bitLength = 1
      • values = 0: cfg_mode, 1: ctrl_mode


        CFG_MODE: configure the module when MODE.mode = 0
  • address = 0x1
  • access = RW
  • fields =
    • cfg1
      • bitOffset = 0
      • bitLength = 4
    • cfg2
      • bitOffset = 4
      • bitLength = 2


        CTRL_MODE: control the module when MODE.mode = 1
  • address = 0x1
  • access = RW
  • fields =
    • ctrl1
      • bitOffset = 0
      • bitLength = 2

        Since it is something that has been used in the past and has a stable SW API, there is no interest in modifying the register mapping or the module itself.

I suppose the “easy” part would be to have a handle or callback in the shared registers to the mode register, but the addressing/offsets remains an issue.

The naive approach of simply writing several shared uvm_reg registers (CFG_MODE, CTRL_MODE) that are mapped to the same address does not make the UVM regmodel happy.

The other naive approach of using a single uvm_reg with the fields for all registers defined and overlap in bit offsets (cfg1=0, cfg2=4, ctrl1=0) does not make the UVM regmodel any more happy.

Has anyone run into special registers like this? Is there a semi-elegant way of handling them to that the resulting register API is not overly complex?

Thanks!