Difficulty: Easy · Puzzle 4 of 6 · Topic: Factory and config_db
UVM 1.2. The test sets `num_trans` for the agent in its connect_phase. The agent reads it in build_phase with a default of 5. What value does the agent run with, and where must the set move so the agent sees 20?
// uvm_test_top.connect_phase
uvm_config_db#(int)::set(this, "env.agent", "num_trans", 20);
// uvm_test_top.env.agent.build_phase
int num_trans = 5;
void'(uvm_config_db#(int)::get(this, "", "num_trans", num_trans));Compare when the agent's build_phase runs with when the test's connect_phase runs.
1) All build_phase calls (the agent's included) are finished before any connect_phase starts.
2) At the agent's build_phase the entry does not exist yet, so get() returns 0 and num_trans keeps the default 5. The value 20 is set later and nobody reads it again.
3) Fix: do the set in the test's build_phase, anywhere before the agent's build_phase runs. That is true both before and after the `env` create call, because creating a child does not build it; its build_phase runs after the parent's build_phase returns.Answer: The agent runs with 5; move the set into the test's build_phase (before or after creating env, either works).
Checked by running the code in Verilator 5; the printed output supports the answer above. Hand-written model of the documented UVM 1.2 behaviour in plain SystemVerilog (Verilator), not the UVM library: the child's read happens at its build time; a set made afterwards is not seen by a read that already ran.
`create()` does not run the child's build_phase, so a set placed after the create call in the parent's build_phase is still in time, while a set in connect_phase is too late even though it is still 'before the simulation'.
How would you read a value that can change mid-run, e.g. a knob toggled by the test in run_phase? Model answer: get it again where it is used (or call `uvm_config_db#(T)::wait_modified(this, "", "knob")` in a run_phase thread and re-read after it returns); config_db is not a push mechanism, a one-time get in build_phase only sees what was set before it.