UVM Back-door Access HDL Paths

Hierarchical HDL Paths

To directly access a register or memory in a design, you need to understand its hierarchical path. The UVM register library allows you to define unique paths for blocks, register files, registers, and memories by combining their hierarchical components.

For instance, if a register has a path component X, which is inside a block with a path component Y, and that block is inside another block with a path component Z, the full path to the register is Z.Y.X.

Key Points About Path Components:

Structure:

  • Path components are based on the language used to model the DUT (Device Under Test) and its design structure.
  • They can be:
      • Individual names (e.g., decoder)
      • Partial paths with dot separators (e.g., bus_if.decoder)
      • Empty, meaning they don’t contribute to the overall path.

Constraints:

  • Path components must be valid strings at runtime, but their value must be constant (not an expression).
  • They cannot start or end with a dot (e.g., .decoder. is invalid).

Cross-Language Use:

  • These paths don’t need to follow SystemVerilog conventions since they may refer to paths that span across different languages.
  • Paths stop at registers and memories.

Duplicates:

  • A register, block, or memory can have multiple hierarchical paths, indicating it is duplicated in the DUT model.
  • When this happens, all copies must be kept consistent in value.

Example:

If you have a design with a memory X inside block Y, which is nested in block Z, its hierarchical path is Z.Y.X. Using this path, you can directly reference the memory or register in the simulation environment.

HDL path components are specified using the following methods:

  • uvm_reg_block::configure() and uvm_reg_block::add_hdl_path()
  • uvm_reg_file::configure() and uvm_reg_file::add_hdl_path()
  • uvm_reg::configure() and uvm_reg::add_hdl_path_slice()
  • uvm_mem::configure() and uvm_mem::add_hdl_path_slice()