← Design Verification Interviews
Interview Question · Debug
Two Drivers, One Bus
The Question
The interviewer asks
A bench has two ports, each with its own driver. Port 1 never sees traffic and port 0 shows corrupted beats. Here is the log. What do you check first?
@10 d0 send 11 on port0
@10 d1 send 22 on port0 <- d1 was configured for port1
@15 port0 valid=1 data=22 (beat 11 overwritten)
@40 port0 beats=1 port1 beats=0You 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
Check which interface instance each driver's virtual interface points at. Here both drivers got port0, so they overwrite each other and port1 stays idle. A virtual interface is a reference, so copying one handle shares the bus. Print each agent's interface path at the start of the run, and give every agent its own handle from the top level.
- Cycle 0
drv0drives port 0, as intended. - Cycle 1
drv1was built for port 1, but its hard-coded pathtb.port0drives port 0 again. - Cycle 3
Port 1 never moves, so its coverage can only stay at zero.
The symptom on the waveform: every beat meant for port 1 appears on port 0. A copied handle and a hard-coded path look exactly the same.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer suspects the handle assignment from the log alone, before looking at the DUT.
What Interviewers Listen For (Mid-Level)
A good mid-level answer prints every agent's interface path at the start of the test. It adds a check that no two active agents share one interface.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyProve ItBreak ItCompareScale It
- Two Drivers, One Bus
-
WhyWhy Classes Need Virtual InterfacesL1 Junior
Why can't a driver class simply contain the interface instance? Why the
virtualkeyword?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
Interfaces are static, elaborated hierarchy, while class objects are created at run time, so a class cannot instantiate one. A virtual interface is a variable holding a reference to an existing interface instance. The bench assigns it before use, so one driver class can be pointed at any instance of the interface.
Self-Check
Tick each key point you covered in your answer.
Misconception
"
virtualmeans the same as invirtual function: it can be overridden."Here it means a reference to an interface instance; it has nothing to do with method dispatch.
Source IEEE 1800-2017 §25.9
-
Break ItA Virtual Interface That Was Never SetL1 Junior
The test crashes with a null access the first time the driver touches
vif.valid. What happened and how do you fail faster?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 virtual interface variable is null until something assigns it, and nothing did. Check it where it is received, for example right after the configuration lookup, and stop with a message naming the agent. The failure then points at the missing assignment, not at the first signal access.
Self-Check
Tick each key point you covered in your answer.
Misconception
"An unassigned virtual interface points at the first instance of that interface."
It is null until assigned; there is no default binding to any instance.
Source IEEE 1800-2017 §25.9
-
ComparePassing the Interface by Constructor or by ConfigurationL2 Mid-Level
Compare handing each driver its virtual interface through the constructor with fetching it from a configuration database.
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 constructor argument is explicit and checked at the call site, which suits a small hand-built bench. A configuration object or database lets deep components get the handle without every parent passing it down. UVM benches work this way. The cost is indirection: a wrong path or key leaves the handle null, so check it on receipt.
Each Driver Reaches the Port It Was GivenThree drivers built by the top module, each given a virtual interface handle through its constructor. Arrows from the top module carry a handle into a constructor; arrows from a driver are drives through that handle to real pins. Illustrative sequenceCallValueReturnWaiting- The instances exist first
rd_if port0 (clk);andrd_if port1 (clk);are part of the elaborated design. They exist before time 0 and never move. - Hand each driver its portt=0 (illustrative)
The top module passes
port0tod0andport1tod1. Each constructor stores a handle; no signals are copied.Follow the calls, values and waits
- data handle: port0: tb module → d0: rd_driver
- data handle: port1: tb module → d1: rd_driver
- A driver with no portt=0 (illustrative)
d2is built withnull. Its handle refers to nothing until something assigns it.Follow the calls, values and waits
- data null: tb module → d2: rd_driver
- Waiting: d2: rd_driver — vif == null
- Both drivers sendt=7 (illustrative)
Forked, both drivers wait for the edge at 5 and drive through
vif.cb. With output skew 2, each pin changes at t=7, on that driver's own port.Follow the calls, values and waits
- data rvalid=1, rdata=0a: d0: rd_driver → port0
- data rvalid=1, rdata=1b: d1: rd_driver → port1
- Two ports, two beatst=15 (illustrative)
At the edge at 15 the module prints
port0 carries 0aandport1 carries 1b. - The null check reports
d2.send()checksviffirst and printsdrv2: no interface configured; nothing sentinstead of failing on a null handle.Follow the calls, values and waits
- Waiting: d2: rd_driver — no interface configured
Read the diagram as text
- tb module: knows which port each driver gets
- d0: rd_driver: vif refers to port0
- d1: rd_driver: vif refers to port1
- d2: rd_driver: vif is null
- port0: rd_if instance
- port1: rd_if instance
- tb module → d0: rd_driver: new(.., port0)
- tb module → d1: rd_driver: new(.., port1)
- tb module → d2: rd_driver: new(.., null)
- d0: rd_driver → port0: vif.cb drives
- d1: rd_driver → port1: vif.cb drives
One driver class serves any number of ports. Which pins a driver reaches is decided by the handle it was given.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"The config database guarantees each agent gets the right interface."
It returns whatever matches the path and name you set. A wildcard path set once can hand the same interface to every agent.
- The instances exist first
-
Prove ItSolve 6.4.1: Give Each Driver Its Own BusSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
-
Scale ItBinding Sixteen Agents to Sixteen PortsL3 Senior
The DUT grows to sixteen ports, generated by a parameter. How do you connect sixteen agents without copy-paste bugs like this one?
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
Create the interfaces in a generate loop indexed by port number. Publish each handle under a name built from the same index. Build the agents in a loop that reads the handle with that index. Then add a start-of-test check that the sixteen handles are all different and not null. A binding mistake then stops the run at time zero.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer removes copy-paste completely, so one index drives both sides. It adds a cheap check at time zero instead of relying on review.
Wrong Altitude
"Review the sixteen lines carefully."
Review does not scale with the parameter. When the port count changes, the hand-written lines become wrong.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"Each driver gets its own copy of the bus when it is constructed."
A virtual interface holds a reference to an instance, not a copy. The twin hands port0 to both drivers and port1 sees nothing.
Run It
Two drivers built from a copy-pasted line that passes port0 twice.
port0 beats=1 port1 beats=0 FAIL: both drivers held a handle to port0, so port1 never saw a beatSee the Fix
interface bus_if(input logic clk);
logic valid = 0; logic [7:0] data = 0;
endinterface
class driver;
virtual bus_if vif;
function new(virtual bus_if v); vif = v; endfunction
task send(logic [7:0] d);
@(negedge vif.clk); vif.valid = 1; vif.data = d;
@(negedge vif.clk); vif.valid = 0;
endtask
endclass
module tb;
logic clk = 0; always #5 clk = ~clk;
bus_if port0(clk), port1(clk);
int got0 = 0, got1 = 0;
always @(posedge clk) begin if (port0.valid) got0++; if (port1.valid) got1++; end
initial begin
driver d0 = new(port0);
driver d1 = new(port1); // the fix: each driver gets its own port
fork d0.send(8'h11); d1.send(8'h22); join
#20 $display("port0 beats=%0d port1 beats=%0d", got0, got1);
if (got1 == 0) $display("FAIL: both drivers held a handle to port0, so port1 never saw a beat");
else $display("PASS: one beat on each port");
$finish;
end
endmodule
Prints: port0 beats=1 port1 beats=1 PASS: one beat on each port
Delivery
Starts by debugging the DUT's port 1 logic.
The log already shows d1 sending on port0. Read the evidence first; it saves time spent in the RTL.
Wrong Altitude
"Use a global interface variable and let every driver read it."
A single global makes sharing the default and is the root cause of this bug class. Per-agent configuration objects make the binding explicit.