Difficulty: Medium · Puzzle 2 of 6 · Topic: Factory and config_db
UVM 1.2. The test's build_phase sets `mode`=1 for the agent. Afterwards the env's build_phase (which runs later) sets `mode`=2 for the same agent. The agent's build_phase then reads it. What does it read? Then: if the test itself later set 4 over an earlier 3 for the same agent, what would the agent read?
// uvm_test_top.build_phase (depth 1), runs first
uvm_config_db#(int)::set(this, "env.agent", "mode", 1);
// uvm_test_top.env.build_phase (depth 2), runs later
uvm_config_db#(int)::set(this, "agent", "mode", 2);
// uvm_test_top.env.agent.build_phase
int mode;
if (!uvm_config_db#(int)::get(this, "", "mode", mode)) mode = 99;
`uvm_info("CFG", $sformatf("mode=%0d", mode), UVM_LOW)The documented rule is about where the set came from in the hierarchy first, and only then about time.
1) Both sets match the agent's full name, so both are candidates.
2) uvm_config_db gives a set from a context higher in the hierarchy precedence over one from a lower context, regardless of the order in time. The test (depth 1) beats the env (depth 2).
3) So the agent reads mode = 1, although 2 was written later.
4) Only when two sets come from the same level does the later write win: test sets 3 then 4, the agent reads 4 (specificity of the pattern does not matter).Answer: The agent reads 1 (the test, higher in the hierarchy, wins over the later env set); in the same-level case it reads 4.
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: settings stored with the depth of the setting component; the lookup picks the shallowest depth and, for equal depth, the latest write (the rule documented for uvm_config_db).
'Last write wins' is only the tie-break between sets from the same hierarchy level; between different levels the one nearer the top wins, so a child can not override its parent's setting, and a set with a null context (from a module) is above everything.
How should an env supply a default for the agent while still letting the test change it? Model answer: the env must not set the value at all (or the test must set it): a set made by the env can never beat the test's set, so the env should only get() with a local default, and the test, being higher, sets the value when it wants something else.