← Design Verification Interviews
Interview Question · Code Reading
One Item, Two Subscribers
The Question
The interviewer asks
A monitor's analysis port feeds a coverage subscriber and a scoreboard. What does the scoreboard see, and why?
class nibble_cov extends uvm_subscriber #(bus_item); // coverage needs the low nibble
function void write(bus_item t);
t.data &= 8'h0f;
endfunction
endclass
// In the env:
mon.ap.connect(sb.analysis_export); // scoreboard expects 3c, a5, f0
mon.ap.connect(cov.analysis_export);
// The monitor writes three items: 3c, a5, f0. What does the scoreboard see?You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
It sees 0c, 05 and 00, so every compare fails. write() passes the same handle to each subscriber in turn, in zero time. The coverage subscriber masks the data in place. In uvm-core it runs before the scoreboard, because subscribers are called in name order. Subscribers must treat the item as read-only. One that needs to change it edits a clone().
write calls, numbered in the order uvm-core makes them. Arrows into the object are handles: nothing is copied.Read the diagram as text
- mon.ap.write(t): Writes 3c, then a5, then f0
- cov: nibble_cov: Called first: t.data &= 8'h0f
- sb: scoreboard: Called second: sees 0c, expects 3c
- One bus_item object: data 3c becomes 0c before the scoreboard reads it
- mon.ap.write(t) → cov: nibble_cov: 1: write(t)
- mon.ap.write(t) → sb: scoreboard: 2: write(t)
- cov: nibble_cov → One bus_item object: edits in place
- sb: scoreboard → One bus_item object: reads the edited data
Connect order does not decide who runs first. Any subscriber that changes the item must change a clone() instead.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer says "same handle" before running anything. It spots the place where the coverage subscriber changes the item.
What Interviewers Listen For (Mid-Level)
A good mid-level answer explains that the result depends on the call order, which nobody should rely on. It fixes the bug by cloning before any change.
What Interviewers Listen For (Senior)
A good senior answer makes read-only analysis items a bench rule, checked in review. It notes that cloning for every subscriber has a cost.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfProve ItCompareScale It
- One Item, Two Subscribers
-
What IfA Rename That Hid the BugL2 Mid-Level
Asked if they mention call order
What if someone renames
covtozcov, and the mismatches disappear?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
The bug is still there; only the order changed. Subscribers run in name order in this library, so the scoreboard now reads the item before coverage edits it. Any later subscriber still sees corrupted data. Treat a fix that depends on names or order as a symptom, and remove the in-place edit.
Self-Check
Tick each key point you covered in your answer.
Misconception
"The rename fixed it."
The edit still happens on the shared object. Only the scoreboard stopped seeing it, by luck of ordering.
Source uvm-core 2020.3.1 (IEEE 1800.2 library) source, base/uvm_port_base.svh, m_imp_list[string]: connections keyed by name
-
WhyWhy Analysis Write Is a FunctionL1 Junior
Why is the analysis
write()a function and not a task?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
A monitor must never be held up by its listeners, or it would miss the next transfer on the bus. A function cannot wait, so every subscriber finishes in zero time. A subscriber that needs time puts the item in an analysis FIFO and works on it in its own thread.
One Write, Three ListenersArrows leaving in_monare calls ofwrite, numbered in the order this library makes them. The FIFO's arrow to the checker is a returned handle.call: who calls whomdata: where the transaction goesIllustrative sequenceCallValueReturnWaiting- Publish10 ns (illustrative)
At 10 ns
in_moncallsap.write(#1)once. The port callswriteon each of its three resolved imps, in turn, inside that one call.Follow the calls, values and waits
- call write(#1): in_mon → chk.fifo
- call write(#1): in_mon → cov
- call write(#1): in_mon → sb
- Return10 ns (illustrative)
Every
writeis a function, so all three finish at 10 ns andin_mongoes on at once. The FIFO stored the handle;covandsbdid their work. - Consume later10 ns (illustrative)
The checker's own thread takes #1 from the FIFO at 10 ns and works on it for 25 ns. The monitor never waited for it.
Follow the calls, values and waits
- return #1: chk.fifo → chk run_phase
- Waiting: chk run_phase — working on #1 until 35 ns
- Second input15 ns (illustrative)
At 15 ns
out_monwrites the result to the scoreboard's second imp, which callswrite_out.Follow the calls, values and waits
- call write_out(#1): out_mon → sb
- Publish #2 into a busy checker20 ns (illustrative)
At 20 ns
in_monwrites #2. The FIFO stores it although the checker is still busy with #1.Follow the calls, values and waits
- call write(#2): in_mon → chk.fifo
- call write(#2): in_mon → cov
- call write(#2): in_mon → sb
- Take #235 ns (illustrative)
At 35 ns the checker finishes #1 and takes #2, which has waited in the FIFO since 20 ns.
Follow the calls, values and waits
- return #2: chk.fifo → chk run_phase
- Waiting: chk run_phase — working on #2 until 60 ns
- Released: chk run_phase
- Finish60 ns (illustrative)
The checker finishes #2 at 60 ns: it took 2 and finished 2.
Follow the calls, values and waits
- Released: chk run_phase
Read the diagram as text
- in_mon: ap.write(t) at 10 and 20 ns
- chk.fifo: Analysis FIFO, unbounded
- cov: uvm_subscriber: write(t)
- sb: write_in(t) and write_out(r)
- chk run_phase: fifo.get(t), then 25 ns of work
- out_mon: ap.write(r) at 15 and 25 ns
- in_mon → chk.fifo: 1: write(t)
- in_mon → cov: 2: write(t)
- in_mon → sb: 3: write_in(t)
- chk.fifo → chk run_phase: t returns to get(t)
- out_mon → sb: write_out(r)
The publisher's code does not change with the number of listeners, zero included.
Self-Check
Tick each key point you covered in your answer.
Misconception
"Add a
@(posedge clk)insidewrite()to wait for the DUT."A function cannot contain timing controls, so this does not compile.
Source IEEE 1800.2-2020 §12.2.10.1.4 (write is a function)
- Publish10 ns (illustrative)
-
What IfA Subscriber That Changes the ItemL1 JuniorL2 Mid-Level
What if one subscriber changes the item inside its
write()?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Every subscriber gets the same object, not a copy. So the change is seen by every subscriber called after it, and by the monitor too. Delivery order is not the connect order, so the effect can move when a component is renamed. Clone the item before changing it.
Self-Check
Tick each key point you covered in your answer.
Misconception
"Each subscriber gets its own copy of the item."
writepasses one handle to all subscribers. A change in one is visible to the others.Source Lesson U3.5 key points
-
CompareAnalysis Port vs Put PortL2 Mid-Level
Compare an analysis port with a put port for sending monitored items.
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
An analysis port goes to any number of subscribers, including none, and never blocks. A put port goes to exactly one receiver and may block until it accepts. Monitors use analysis ports, so adding a coverage collector never changes the monitor's timing.
Self-Check
Tick each key point you covered in your answer.
Misconception
"An analysis port needs at least one subscriber."
An analysis port with no connections is legal;
write()then simply does nothing.Source Accellera, UVM 1.1 User's Guide, §2.5.1 Analysis Ports (PDF p24)
-
Scale ItThirty Subscribers on One PortL3 Senior
At SoC level one monitor feeds thirty subscribers: scoreboards, coverage, loggers. What risks do you manage?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
All thirty run inside the monitor's time step, so heavy work there slows every cycle. One careless subscriber that edits the item corrupts the rest. Keep
write()short, move slow work into FIFOs read by separate threads, and make items read-only by rule. Loggers that print every item should be off by default.Self-Check
Tick each key point you covered in your answer.
Missed Corner
"Fan-out is free because it takes zero simulation time."
Zero simulated time is not zero wall-clock time. Thirty writes per item add real run time.
Source Verification Academy, UVM Cookbook, Analysis Components: analysis port write behaviour (PDF p152-160)
-
Prove ItSolve U7.2.1: A Scoreboard Among Careless ListenersSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"write() gives each subscriber its own copy."
It hands the same object to every subscriber. The twin's coverage edit reaches the scoreboard.
Run It
The interview's bench: a monitor, a nibble coverage subscriber and a scoreboard.
sb got 0c, expected 3c sb got 05, expected a5 sb got 00, expected f0 FAIL: write() passes one handle to every subscriber, so the coverage edit reached the scoreboardSee the Fix
`timescale 1ns/1ns
`include "uvm_macros.svh"
import uvm_pkg::*;
class bus_item extends uvm_sequence_item;
`uvm_object_utils(bus_item)
rand bit [7:0] data;
function new(string name = "bus_item"); super.new(name); endfunction
endclass
class bus_monitor extends uvm_component;
`uvm_component_utils(bus_monitor)
uvm_analysis_port #(bus_item) ap;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase); ap = new("ap", this); endfunction
task run_phase(uvm_phase phase);
bit [7:0] seen[3] = '{8'h3c, 8'ha5, 8'hf0};
phase.raise_objection(this);
foreach (seen[i]) begin
bus_item t = bus_item::type_id::create("t");
t.data = seen[i];
#10 ap.write(t);
end
phase.drop_objection(this);
endtask
endclass
// Coverage only cares about the low nibble.
class nibble_cov extends uvm_subscriber #(bus_item);
`uvm_component_utils(nibble_cov)
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void write(bus_item t);
bus_item mine;
$cast(mine, t.clone()); // the fix: edit a private copy
mine.data &= 8'h0f;
endfunction
endclass
class bus_sb extends uvm_subscriber #(bus_item);
`uvm_component_utils(bus_sb)
bit [7:0] expected[$] = '{8'h3c, 8'ha5, 8'hf0};
int errors;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void write(bus_item t);
bit [7:0] want = expected.pop_front();
$display("sb got %h, expected %h", t.data, want);
if (t.data != want) errors++;
endfunction
endclass
class bus_env extends uvm_env;
`uvm_component_utils(bus_env)
bus_monitor mon; nibble_cov cov; bus_sb sb;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase);
mon = bus_monitor::type_id::create("mon", this);
sb = bus_sb::type_id::create("sb", this);
cov = nibble_cov::type_id::create("cov", this);
endfunction
function void connect_phase(uvm_phase phase);
mon.ap.connect(sb.analysis_export);
mon.ap.connect(cov.analysis_export);
endfunction
function void check_phase(uvm_phase phase);
if (sb.errors) $display("FAIL: write() passes one handle to every subscriber, so the coverage edit reached the scoreboard");
else $display("PASS: the scoreboard saw what the monitor saw");
endfunction
endclass
class fan_test extends uvm_test;
`uvm_component_utils(fan_test)
bus_env env;
function new(string name, uvm_component parent); super.new(name, parent); endfunction
function void build_phase(uvm_phase phase); env = bus_env::type_id::create("env", this); endfunction
endclass
module tb;
initial run_test("fan_test");
endmodule
Prints: sb got 3c, expected 3c sb got a5, expected a5 sb got f0, expected f0 PASS: the scoreboard saw what the monitor saw
Tool as Truth
"Subscribers are called in the order you connected them."
The scoreboard was connected first and still ran second. uvm-core keeps the connections in a table keyed by name.
Source uvm-core 2020.3.1 (IEEE 1800.2 library) source, base/uvm_port_base.svh, m_imp_list[string]
Half-Truth
"Let the monitor clone the item for each subscriber."
It works, but it pays for a copy per subscriber per item. The usual rule is read-only subscribers and copy only on write.
Source Verification Academy, UVM Cookbook, Coding Guidelines 10.1, manual copy on write (PDF p585)