Custom UVM Factory
Overview
A Custom UVM Factory is a performance-oriented replacement for the standard UVM Factory in contexts where many object types must be registered and created frequently. In the RISCV-DV implementation described in the DVCon paper Crafting a Million Instructions/Sec RISCV-DV, the technique is used to accelerate instruction generation by bypassing the standard UVM Factory path. [C1]
Motivation
The standard UVM Factory provides advanced object-creation features, including type overrides and instance overrides. However, it maintains complex internal data structures to support those features. According to the cited RISCV-DV discussion, even a seemingly simple <class_name>::type_id::create call requires matching the requested class name against registered factory class names. As the number of registered types grows, this matching becomes significantly slow. [C2]
RISCV-DV models each instruction in the RISC-V ISA as a separate class. This means hundreds of instruction classes may need to be registered, which would make use of the standard UVM Factory extremely slow for instruction generation. [C3]
Technique
RISCV-DV implements its own custom factory for instruction creation. The cited listing shows a registry keyed by riscv_instr_name_t, with a register function that maps an instruction enum value to a qualified class name. A create_instr_list routine iterates through the instruction registry, skips unsupported instructions, creates instruction instances, and stores them in an instr_template map keyed by instruction name. [C4]
The key optimization is that RISCV-DV uses the riscv_instr_name_t enumeration to tag each instruction numerically. The custom factory therefore hashes factory objects using the enumeration rather than performing class-name matching through the standard UVM Factory mechanism. This results in faster matching when an instruction object is created. [C5]
Simplified structure
The cited implementation includes the following conceptual elements:
instr_registry: maps an instruction enum value to a qualified class name.register(instr_name, qualified_name): records the association between an instruction enum and its class name.create_instr_list(): walks the registry, filters unsupported instructions, creates instruction instances, and stores them ininstr_template.instr_template: stores created instruction template objects keyed byriscv_instr_name_t. [C4]
Applicability
This technique is useful when the standard UVM Factory's advanced features are not required on the hot path and the design has a large number of registered types. In the cited RISCV-DV case, the custom factory is specifically applied to instruction generation, where many RISC-V instruction classes would otherwise be registered with the UVM Factory. [C2][C3]