Difficulty: Medium · Puzzle 2 of 6 · Topic: Analysis, Scoreboards and RAL
UVM 1.2. A scoreboard has an expected-stream imp and an actual-stream imp, both `uvm_analysis_imp #(bus_item, my_sb)`. It has one `write` function which pushes to the expected queue. Actual transactions are also being pushed into the expected queue. What is wrong and what is the standard fix?
class my_sb extends uvm_scoreboard;
`uvm_component_utils(my_sb)
uvm_analysis_imp #(bus_item, my_sb) exp_imp;
uvm_analysis_imp #(bus_item, my_sb) act_imp;
bus_item exp_q[$];
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
exp_imp = new("exp_imp", this);
act_imp = new("act_imp", this);
endfunction
function void write(bus_item t);
exp_q.push_back(t);
endfunction
endclassBoth imps forward to the same method of the same class. How can a component receive two streams?
1) An analysis imp calls `write()` of its parent class. Both imps are the same class, so both call the same write(); the scoreboard can not tell the streams apart.
2) Fix: declare per-stream imp classes with the macro `uvm_analysis_imp_decl(_exp)` and `uvm_analysis_imp_decl(_act)` (outside the class, at file or package scope, before use). They create `uvm_analysis_imp_exp` and `uvm_analysis_imp_act`, which call `write_exp()` and `write_act()`.
3) Then declare `uvm_analysis_imp_exp #(bus_item, my_sb) exp_imp;` and `uvm_analysis_imp_act #(bus_item, my_sb) act_imp;` and implement `write_exp` and `write_act` separately. Alternative: two `uvm_tlm_analysis_fifo`s read in run_phase.Answer: Both imps call the single write(): the two streams are mixed. Use `uvm_analysis_imp_decl(_exp)` / `(_act)` and implement write_exp / write_act (or use two analysis FIFOs).
Not run here: The UVM library is not installed here, so this cannot be executed; uvm_analysis_imp_decl is a UVM macro that generates classes.. The answer follows the language rules and the solution steps above.
It compiles and connects without any message, and the symptom (expected queue full of actual data, comparator mismatches or passes against itself) points at the DUT, not at the scoreboard wiring.
Where can the decl macros be placed and what happens if they are inside the class? Model answer: they define new classes, so they must be at file or package scope before the scoreboard class (and a given suffix can be declared only once per compilation scope); inside the class body it is a compile error.