Difficulty: Medium · Puzzle 3 of 6 · Topic: Real Interview Rounds: End-to-End Debug Walkthrough
Interview trace: every APB read returns the data of the PREVIOUS address. Separate a protocol violation in the driver from a monitor sampling bug in five clear steps.
always @(posedge pclk) begin
if (start_read) begin
psel <= 1'b1;
paddr <= req.addr;
penable <= 1'b1; // bug: psel, paddr and penable all change on the same edge
end
endAPB setup and enable phases must be distinct and ordered.
1) Symptom: read data lags by one transfer under back-to-back traffic.
2) Hypotheses: APB phase violation in the driver, monitor sampling skew, or a DUT pipeline bug.
3) Instrumentation: mark SETUP (psel=1, penable=0) and ACCESS (psel=1, penable=1) phases on the waveform and add an SVA: $rose(psel) |=> penable (and !$past(penable) on the first cycle). Compare what the DUT sees with what the monitor samples: if the monitor reports the same address/data pairs the DUT saw, it is not a monitor bug.
4) Root cause: psel, paddr and penable change on the same edge, so there is no setup cycle. A slave that latches the address in the setup cycle (psel && !penable) never sees it and returns data for the previous address. This symptom assumes a slave that latches the address in the setup cycle; a slave that samples paddr in the access cycle would not show it, but the sequence is still an APB protocol violation.
5) Fix: drive psel and paddr in the setup cycle, penable in the next, and hold until pready; deassert penable (and psel unless back to back) after the access. Rerun a directed back-to-back read sequence and keep the SVA in regressions.Answer: Actual bug: the driver asserts psel, paddr and penable on the same edge, so there is no APB setup phase and the slave latches a stale address. Fix: split the transfer into setup (psel, paddr) then access (penable), wait for pready, and deassert correctly.
Checked by running the code in Verilator 5; the printed output supports the answer above. Plain-SV model of an APB slave that latches the address in the setup cycle: with no setup phase it returns stale data, with one it is correct.
Many candidates inspect the scoreboard first; this is protocol timing in the stimulus. An SVA on the setup-to-access order separates driver, monitor and DUT in one run.
Which assertion would you write to enforce APB setup/access sequencing in future regressions? Model answer: Setup then access: assert property (@(posedge pclk) disable iff (!presetn) $rose(psel) |=> (psel && penable)); plus penable never rises without psel and psel && penable && !pready |=> $stable(paddr) && penable (hold until ready).
Reads return previous data, so I look at the protocol timing on the bus before blaming the scoreboard. The root cause is that the driver asserts psel, paddr and penable on the same edge, so there is no APB setup phase and the slave latches a stale address. I confirm it with an SVA on the setup to access order, which separates driver, monitor and DUT in one run. The fix is to split the transfer into setup then access, wait for pready, and deassert correctly.