Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here4
  • UVM Foundations14
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
    • UVM Factory: Registration, Overrides and Debug
    • config_db and Resources
      • The set/get Contract: Four Arguments That Must Agree
      • Instance Paths and Wildcards: Who Can See a Setting
      • config_db Resolution: Who Wins at Build and After
      • Config Objects: One Typed Handle Instead of Twenty Knobs
      • config_db Performance and Anti-Patterns
      • Auto-Config and Field Macros on Components
      • Configuring Sequences
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
  • Senior Prep: Architecture, Leadership and Interviews32
Loading lesson

‹config_db and Resources
  1. Topics
  2. UVM Verification
  3. Factory & Configuration
  4. config_db and Resources
  5. Instance Paths and Wildcards: Who Can See a Setting

Part 3/Factory & ConfigurationIntermediate

Instance Paths and Wildcards: Who Can See a Setting

Glob and regular-expression scopes, why a pattern like agt.* does not match agt itself, the env* trap, and choosing the narrowest reach that works.

On this page

    The APB agent needs a timeout knob, so you add uvm_config_db#(int)::get(this, "", "timeout", timeout) to apb_agent and, to keep things together, set it next to the interface in the top: set(null, "uvm_test_top.env.apb.*", "timeout", 100). The driver and the monitor both pick it up. The agent does not. Same path, same name, same type. The pattern itself is the problem.

    The idea: "all residents" does not include the building

    A scope pattern is an address on an envelope. uvm_test_top.env.apb.* means "everyone whose address starts with uvm_test_top.env.apb.", dot included. The driver (...apb.drv) and the monitor (...apb.mon) live there. The agent's own address is uvm_test_top.env.apb, which has no trailing dot, so it is not a resident of its own building. A wildcard pattern must match the getter's entire full name, character for character.

    A pattern decides reach: which components can see a setting. It does not decide precedence: when two settings both reach a component, a narrow exact path does not beat a broad wildcard. That is decided by the setter's depth and the order of the sets, taught in Resolution order.

    The picture

    Tree of the bench hierarchy marking which components match the pattern uvm_test_top.env.apb.*: the APB driver, monitor and sequencer, not the agent.
    Reach of the top's scope uvm_test_top.env.apb.*: every component below the APB agent, but not the agent itself and nothing in the other agents.

    Build it: patterns and their reach

    Glob syntax

    By default a scope is a glob: * matches any run of characters, including dots, and ? matches exactly one character. A scope written between slashes, such as /^uvm_test_top\.env\.(in|out)_agt\..*$/, is a regular expression; regex scopes need the UVM DPI library, so globs are the portable choice.

    Scope (set from null)

    Reaches

    Watch out for

    uvm_test_top.env.apb.drv

    Only the APB driver.

    Breaks if the driver is renamed.

    uvm_test_top.env.apb.*

    Everything below the APB agent.

    Not the agent itself (the opening bug).

    uvm_test_top.env.apb*

    The agent and everything below it.

    Also apb2, apb_bridge... any name starting with apb.

    uvm_test_top.env.*

    Everything below the env.

    Not the env itself.

    *

    Every component, and every sequence that reads config.

    Costs every lookup of that field name; see performance.

    *.drv

    Every component named drv, anywhere.

    Silently grows as the bench grows.

    The bench's choices

    The top's three agent-interface sets each use agent.*, which is exactly right: the agents themselves do not need the interface, their drivers and monitors do. The env sets is_active with the exact relative path out_agt, because that setting is for one agent and nobody else:

    design.sv
    1
    2
    3
    4
    5
    // snippet: the bench's two styles of scope
    // top module: absolute, wildcard below one agent
    uvm_config_db#(virtual apb_if)::set(null, "uvm_test_top.env.apb.*", "vif", apb);
    // dma_env::build_phase: relative to the env, exact
    uvm_config_db#(uvm_active_passive_enum)::set(this, "out_agt", "is_active", UVM_PASSIVE);

    Absolute paths from the top module all start with uvm_test_top, the name run_test always gives the test instance. That is safe to rely on. What is not safe is everything after it: env, apb, in_agt are names chosen inside the env, so a top-module path that spells them out depends on code two levels away. Keep absolute paths short (down to the env), and let the env, which owns its children's names, set the rest relative to itself.

    Absolute or relative: which context to set from

    The same scope string can be written two ways. From the test, set(this, "env.apb.*", ...) and set(null, "uvm_test_top.env.apb.*", ...) produce the identical scope uvm_test_top.env.apb.*, so they reach exactly the same components. They are not equivalent, though: the context is also the setter, and the setter's depth decides precedence during build. The first is a depth-1 set (precedence 999), the second a depth-0 set (1000). Use this from inside components, so precedence reflects who really made the decision, and null only from the top module, which has no component context. A test that sets from null to "win harder" also outranks every other test-level setting, which is rarely what the next engineer expects.

    Fixing the opening bug

    To reach both the agent and its children, either make two sets, or use the apb* form and accept its reach. Two sets are clearer and never surprise you when someone adds an apb2 agent:

    design.sv
    // snippet: reach the agent and everything below it
    uvm_config_db#(int)::set(null, "uvm_test_top.env.apb",   "timeout", 100);
    uvm_config_db#(int)::set(null, "uvm_test_top.env.apb.*", "timeout", 100);

    Field names can also be globs, but keep them exact: a wildcard field name makes a set match labels nobody intended.

    Watch it run

    The bench's narrow scopes are visible in its topology and its passing log. Each agent's driver and monitor found an interface, out_agt built only a monitor, and the run checked every word:

    Diagram
    +UVM_TESTNAME=dma_smoke_test
    UVM_INFO dma_tb.sv(411) @ 655000: uvm_test_top.env.sb [SB] 8 words matched, 0 mismatched
    UVM_FATAL :    0

    To see reach directly, print_config(1) on any component lists every setting visible to it and its children, with the scope each one came from. Calling it on the APB agent before and after the two-set fix shows timeout appear on the agent's own line.

    What breaks: the wildcard that reached a new neighbour

    A block bench had one APB agent called apb, and the test set uvm_test_top.env.apb* to configure it. A year later the block went into a subsystem env that also had apb_bridge, an agent for a different bus with a field of the same name, timeout. The bridge picked up the block's value, meant for a different protocol, and started timing out real transfers. Nothing in the log mentioned config; the symptom was a protocol error two levels away.

    The fix was to stop using prefix globs on component names. Exact paths, or name.* plus an exact set for the component itself, have a reach you can read. When a setting must reach "all agents of one kind", put it in that agent's config object instead of matching names, so the type, not the spelling, decides who receives it.

    *"Does `env.agt.` configure the agent?"**

    A weak answer: "Yes, the star covers the agent and everything inside it."

    A strong answer: "No. The glob must match the getter's whole full name, and env.agt has no trailing dot, so only its children match. To include the agent I add an exact set on env.agt, or use env.agt* and accept that it also matches env.agt2. And the pattern only decides reach, not precedence: an exact path doesn't beat a matching wildcard; setter depth during build, then the last set, decides."

    Follow-ups: Can a field name be a wildcard? (yes, but keep it exact) and How do you see what a component can see? (print_config, or +UVM_CONFIG_DB_TRACE).

    Check yourself The test sets uvm_config_db#(int)::set(this, "env.*", "verbose", 1). Which of these read it with get(this, "", ...): the env, the APB driver, the test?

    Only the APB driver (and every other component below the env). The scope is uvm_test_top.env.*; the env's full name uvm_test_top.env has no trailing dot, and the test's name is shorter still.

    Check yourself Both sets come from the test's build_phase: first set(this, "env.apb.drv", "gap", 1), then set(this, "env.*", "gap", 5). What does the APB driver read?

    5. Both sets reach the driver and both come from the same setter, so they have the same precedence, and between equal precedence the last set wins. The exact path does not make the first set stronger; path form decides reach only.

    Check yourself Why is *.drv a risky scope in a bench that will be reused in a subsystem?

    It reaches every component named drv anywhere in the hierarchy, including drivers in agents that do not exist yet. When the block is reused, other teams' drivers start receiving the setting if they read the same field name and type.

    Next: when two settings both reach a component, which one does it read? Resolution order is the one place the course answers that.

    Related topics

    • The set/get contract

    • Resolution order: who wins

    • config_db performance

    Previous

    54 / 280

    Next: config_db Resolution: Who Wins at Build and After

    Up next

    Up nextconfig_db Resolution: Who Wins at Build and After

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Config Objects: One Typed Handle Instead of Twenty Knobs
    • config_db Performance and Anti-Patterns
    • Auto-Config and Field Macros on Components