Part 11 · Senior Prep · Intermediate
Env & Test Structure Interview Q&A
Model answers on test base classes, env composition, config_db distribution, top-module wiring, and regression-friendly test taxonomy.
Test and env hierarchy questions
Q: How do you structure test base vs concrete tests?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Test base pattern?
A:
MECHANISM: base_test builds env, sets default cfg, runs smoke seq in run_phase.
Concrete tests extend base — override cfg, factory, or main sequence.
MOTIVATION: Regression suite needs consistent env topology; tests differ in
stimulus and knobs, not in rebuild-the-world per test.
WHEN: Every project with 20+ tests — base owns build/connect template.
PITFALL: Each test recreates env with copy-paste build_phase — drift bugs.
EXAMPLE: base_test creates env + sets cfg; axi_stress_test overrides
max_outstanding and starts axi_stress_seq.Q: What belongs in env vs test?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Env vs test responsibilities?
A:
MECHANISM: Env = reusable topology (agents, SB, cov, v_sqr). Test = scenario
selection, factory overrides, plusarg interpretation, end-of-test policy.
MOTIVATION: Env is integration asset; test is regression entry point.
ENV: build/connect all agents; publish v_sqr; enable checkers from cfg.
TEST: pick sequence, set drain_time, raise/drop top objection, report_phase hooks.
PITFALL: Test building ad-hoc agents — bypasses env reuse at chip.
EXAMPLE: env owns three passive monitors; dma_random_test only starts vseq.class base_test extends uvm_test;
`uvm_component_utils(base_test)
chip_env env;
chip_cfg cfg;
function void build_phase(uvm_phase phase);
cfg = chip_cfg::type_id::create("cfg");
cfg.apply_plusargs(); // parse +NUM_TXNS etc.
uvm_config_db#(chip_cfg)::set(this, "env", "cfg", cfg);
env = chip_env::type_id::create("env", this);
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
smoke_vseq seq = smoke_vseq::type_id::create("seq");
seq.start(env.v_sqr);
phase.drop_objection(this);
endtask
endclassKey takeaways
Base test = topology template; concrete tests = scenario + knobs.
Env owns structure; test owns stimulus and end-of-test policy.
Never duplicate env build across tests — extend base.
Common pitfalls
Test-level agent creation — breaks chip/block env reuse.
Cfg scattered across plusargs without central cfg object.
Config distribution and top module
Q: Where do you set virtual interfaces — top or test?
[INT][SENIOR][UVM] MODEL ANSWER
Q: vif in top module vs test?
A:
MECHANISM: Top module binds SV interfaces to DUT, pushes vif via config_db
before run_test(). Test/env/agents get by path.
MOTIVATION: Interfaces are elaboration-time artifacts — only top knows hierarchy.
WHEN: Always set vif from top (or tb_pkg init) with uvm_config_db::set(null,...).
PITFALL: Test creating virtual interface — elaboration order nightmares.
EXAMPLE: top sets null,"*","axi_vif",axi_if; agent gets in build_phase.Q: How do you distribute cfg to multiple agents?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Multi-agent config_db?
A:
MECHANISM: Test sets env cfg; env slices per-agent cfg objects in build_phase.
MOTIVATION: Wildcard set(null,"*") for all knobs causes collisions — scope paths.
PATTERN: test → set(env,"cfg",top_cfg); env → set(agt[i],"cfg",agt_cfg[i]).
PITFALL: Single global cfg mutated by agents — race in parallel tests.
EXAMPLE: env sets "env.axi_agt" and "env.apb_agt" with distinct cfg instances.// top.sv — vif push before UVM starts
initial begin
uvm_config_db#(virtual axi_if)::set(null, "*", "axi_vif", axi_if0);
uvm_config_db#(virtual apb_if)::set(null, "*", "apb_vif", apb_if0);
run_test("chip_base_test");
end
// env distributes sliced cfg
function void chip_env::build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(chip_cfg)::get(this, "", "cfg", cfg);
axi_cfg axi_c = cfg.axi_cfg.clone();
axi_c.is_active = UVM_PASSIVE;
uvm_config_db#(axi_cfg)::set(this, "axi_agt", "cfg", axi_c);
agt = axi_agent::type_id::create("axi_agt", this);
endfunctionQ: Regression taxonomy — how do you name and organize tests?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Test naming for regression?
A:
MECHANISM: smoke / random / directed / closure / negative buckets with manifest.
MOTIVATION: Farm schedulers and triage owners map test name → component.
NAMING: <block>_<scenario>_<intent>_test — e.g. axi_outstanding_stress_random_test.
PITFALL: Cryptic names (test_17) — triage cannot assign owner.
EXAMPLE: Manifest groups: P0_smoke (every commit), nightly_random (500 seeds),
closure_directed (plan hole IDs in test name).# regression manifest excerpt
SMOKE_TESTS=(chip_smoke_test block_axi_smoke_test)
NIGHTLY_TESTS=(chip_random_test dma_stress_test)
CLOSURE_TESTS=(hole_FP_12_directed_test hole_FP_09_cross_test)
for t in "${NIGHTLY_TESTS[@]}"; do
./run_regression.sh "${t}" --seeds 50
doneKey takeaways
vif from top; cfg sliced env → agent with scoped paths.
Test taxonomy maps to triage owners and regression tiers.
Clone cfg per agent — avoid shared mutable global cfg.
Common pitfalls
config_db get path mismatch — silent null vif at run_phase.
Plusargs parsed in three places — inconsistent knob semantics.