← Protocols Interviews

Interview Question · Debug

Lost Bytes on a Clean Wire

L1 JuniorL2 Mid-Leveluarterrors

The Question

The interviewer asks

A customer says bytes go missing from your UART under load. Yet a protocol analyser on the RX pin shows every frame clean. What is going on? Also, tell me how framing, parity, overrun and break differ.

log
Illustrative receiver observations under load
Pin analyser decoded: 21h, 22h, 23h, 24h
Software consumed:   21h, 22h, 24h
Pin analyser framing/parity errors: 0
Reveal the Model Answer

A clean wire with lost bytes points inside the receiver, to an overrun. A frame completes before software read the previous byte, and the new byte overwrites it. Framing errors (the stop sample reads 0) and parity errors are visible on the wire; an overrun is not. A break is the line held low for longer than a whole frame. A correct receiver reports it once and delivers no byte. It hunts for a start only after the line is high again.

Two frames, nothing read
012345678910111213141516171819202122232425rxvalidoverrundata0011220x11 lands0x22 overwrites

Measured, one column per bit-time. Nobody reads 0x11, so at the next stop sample 0x22 overwrites it and overrun rises.

ErrorWhere it happensWhat the receiver sees
FramingOn the wireThe stop sample reads 0
ParityOn the wireThe count of 1s has the wrong sense
OverrunInside the receiverA frame completes while the last byte is still unread
BreakOn the wireThe line stays low longer than a full frame

Only overrun is invisible to a wire monitor.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Junior)

A good junior answer separates errors visible on the wire from an overrun inside the receiver. It knows the new byte overwrites the old one.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItBreak It

  1. Lost Bytes on a Clean Wire
  2. WhyRecovering from a BreakL1 JuniorL2 Mid-Level

    After a break, why must the receiver wait for the line to go high before it hunts for a start bit?

    Reveal the Model Answer

    During a break the line is a continuous 0. A receiver that re-arms at once takes the low level as a new start every frame time. It delivers a stream of 00h framing errors. Waiting for the high level means the next frame begins on a real falling edge. A common bug that tests miss is a lost first frame after recovery: the receiver re-armed too late or too early.

    What the Receiver Does After the Stop SampleArrows are decisions in time order, read from the bench receiver. A break is the line held low for longer than a frame.
    What the receiver does after the stop sampleArrows are decisions in time order, read from the bench receiver. A break is the line held low for longer than a frame. component Stop sample the last bit of theframe component Reads 1 deliver the byte component Reads 0, data notall 0 deliver it with FE component Reads 0, data all0 hold it back: frame orbreak? component Wait for a high never start on a lowline component High within 176ticks deliver 00 with FE component 176 low ticks break_seen; drop theheld frame component Look for a start eight low ticks again
    1. A good stop

      The stop sample reads 1: the byte goes to the holding register and the receiver looks for the next start.

    2. A bad stop

      The stop sample reads 0. The byte is delivered with FE, and the receiver waits for the line to go high before it looks for a start.

    3. Frame or break?

      A frame of all zeros with a 0 stop is held back. If the line rises soon, it was a frame: 00 with FE. If it stays low for 176 ticks, it is a break, reported once.

    Read the diagram as text
    • Stop sample: the last bit of the frame
    • Reads 1: deliver the byte
    • Reads 0, data not all 0: deliver it with FE
    • Reads 0, data all 0: hold it back: frame or break?
    • Wait for a high: never start on a low line
    • High within 176 ticks: deliver 00 with FE
    • 176 low ticks: break_seen; drop the held frame
    • Look for a start: eight low ticks again
    • Stop sample → Reads 1
    • Stop sample → Reads 0, data not all 0
    • Stop sample → Reads 0, data all 0
    • Reads 1 → Look for a start
    • Reads 0, data not all 0 → Wait for a high
    • Reads 0, data all 0 → High within 176 ticks
    • Reads 0, data all 0 → 176 low ticks
    • Wait for a high → Look for a start

    Waiting for a high before the next start keeps a break from becoming a stream of bytes. This bench calls 176 low ticks a break.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Junior)

    A good junior answer says a line held low would look like a new start bit every frame time.

  3. Prove ItSolve P6.7.3: Find the Lost Frame After RecoverySimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem P6.7.3

  4. Break ItA Receiver That Re-Arms Too LateL1 JuniorL2 Mid-Level

    Break it: after a break, the receiver waits for a whole frame of idle high before it hunts again. What goes wrong?

    Reveal the Model Answer

    The transmitter may send the next start bit soon after the line goes high. A receiver that waits a whole frame misses that falling edge. It loses the first byte, or starts in the middle of it and reads garbage. Re-arm on the first high level, then hunt for the next falling edge.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Waiting longer after a break is always safer."

    A long wait can miss a start bit that follows the break closely. Re-arm as soon as the line is high.

  5. What IfRTS, CTS and the Trigger LevelL1 JuniorL2 Mid-Level

    Software cannot always keep up. How do RTS and CTS prevent overrun, and why is the RTS trigger set below the FIFO size?

    Reveal the Model Answer

    Each side drives RTS from its own receive FIFO level. The peer sees it as CTS and starts no new frame while CTS is deasserted. But frames already started, or already loaded in the transmitter, still arrive after RTS changes. So the trigger sits below full, and the room above it absorbs those frames. The P6.6 bench uses 12 of 16; a trigger at 16 left no room.

    Honoured: 24 bytes, nothing read
    0123456789101112131415161718192021222324252627rxq count123456789101112rts_ntxq count151615141312frames sent123456789101112overrun

    Measured, one column per frame time (176 ticks). The count climbs to the trigger, rts_n rises, the sender stops. End: sent 12, rxq holds 12, txq holds 12, lost 0.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Junior)

    A good junior answer drives RTS from the receive FIFO level. It says CTS only stops new frames from starting.

  6. Prove ItSolve P6.6.1: RTS and CTS Around a Byte FIFOSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem P6.6.1

  7. Break ItError Checks Without False AlarmsL2 Mid-Level

    Your scoreboard fires on every framing error, and the error-injection tests now fail. How should the checker decide whether a flag is a bug?

    Reveal the Model Answer

    A flag is a bug only if it disagrees with what was sent. So the checker predicts flags from the stimulus. An injected short stop expects FE, a break expects one break and no byte, and a slow read expects overrun. It flags both a missing expected flag and an unexpected one. Banning all errors makes error tests impossible; ignoring flags misses a receiver that never sets them.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Mid-Level)

    A good mid-level answer predicts the expected flags from the stimulus. It flags both a missing expected flag and an unexpected one.

  8. Prove ItSolve P6.5.2: Check UART Errors Without False AlarmsSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem P6.5.2

  9. Prove ItSolve P6.5.1: The Missing Overrun FlagSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem P6.5.1

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"The wire monitor shows no errors, so the receiver is fine."

Overrun happens behind the pins. In the twin, three clean frames arrive and the CPU reads late. The buggy receiver loses 22h without raising overrun, and the wire monitor still reports 0 errors. Only a model of the read timing catches it.

Run It

The wire monitor reports 0 errors in both runs. Only the model of the read timing sees the missing overrun flag.

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: cpu read 33, overrun 0 wire monitor: 3 frames, 0 errors FAIL: wire is clean, but a byte was lost and overrun is 0 (model 1)
See the Fix
`timescale 1ns/1ps
// Three clean 8N1 frames arrive (11h, 22h, 33h) and the CPU reads late, after the third.
// The receiver has one holding register. BUG = 0.
// A wire monitor and a reference model watch the same traffic.
module tb;
  localparam bit BUG = 0;
  reg [7:0] rbr; reg valid = 0, overrun = 0;          // receiver under test
  int wire_frames = 0, wire_errors = 0;               // wire monitor: counts frames with a 0 stop sample
  reg model_valid = 0, model_overrun = 0;             // reference model of the holding register
  task automatic frame_done(input [7:0] b, input bit stop);
    wire_frames++; if (!stop) wire_errors++;
    if (model_valid) model_overrun = 1;
    model_valid = 1;
    if (valid && !BUG) overrun = 1;
    rbr = b; valid = 1;
  endtask
  initial begin
    frame_done(8'h11, 1); #160;
    frame_done(8'h22, 1); #160;
    frame_done(8'h33, 1); #20;
    $display("cpu read %h, overrun %b", rbr, overrun);
    valid = 0; model_valid = 0;
    $display("wire monitor: %0d frames, %0d errors", wire_frames, wire_errors);
    if (model_overrun === overrun) $display("PASS: overrun %b as the model predicts", overrun);
    else $display("FAIL: wire is clean, but a byte was lost and overrun is %b (model %b)", overrun, model_overrun);
    $finish;
  end
endmodule

Prints: cpu read 33, overrun 1 wire monitor: 3 frames, 0 errors PASS: overrun 1 as the model predicts

Half-Truth

"A break is just a framing error on a 00h byte."

It does fail the stop sample. But a correct receiver reports one break, delivers no byte, and waits for the line to go high before hunting. Treating it as data delivers phantom bytes.

Half-Truth

"Fix overrun with a deeper FIFO."

Depth only absorbs a burst. If software is slower on average, any depth fills. Flow control fixes it. The P6.6 bench lost 8 bytes into a 16-byte FIFO when CTS was ignored, and none when CTS was honoured.

Learn It, Then Prove It