Interview Question · Code Reading
The Extra Pointer Bit in a FIFO
The Question
The interviewer asks
This 8-entry FIFO uses 4-bit pointers for 3 address bits. Why the extra bit? When are full and empty true?
logic [AW:0] wptr, rptr; // AW = 3: 8 entries, 4-bit pointers
assign empty = (wptr == rptr);
assign full = (wptr[AW] != rptr[AW]) && (wptr[AW-1:0] == rptr[AW-1:0]);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
With only address bits, equal pointers mean either empty or full, and you cannot tell which. The extra bit tells whether the pointer has wrapped an odd or even number of times. Equal pointers, extra bit included, mean empty. Equal address bits with different extra bits mean the writer is one whole lap ahead: full. So all 8 entries are usable with no counter.
- Write
An accepted write stores the word at the slot the low bits of
wptr_qname, then adds one to the pointer. - Read
An accepted read takes the word at
rptr_qintoread_dataat the edge and adds one to the read pointer.read_validis 1 after that edge. - Flags
Equal pointers mean empty. Equal low bits with different top bits mean the writer is one lap ahead: full.
Read the diagram as text
- Producer: write_en, write_data
- Write pointer: wptr_q: AW + 1 bits
- Memory: DEPTH words
- Read pointer: rptr_q: AW + 1 bits
- Flags: full, empty
- Consumer: read_en; read_data, read_valid
- Producer → Write pointer: accepted write
- Write pointer → Memory: slot
- Read pointer → Memory: slot
- Memory → Consumer: word, one edge later
- Write pointer → Flags: wptr
- Read pointer → Flags: rptr
The top pointer bit counts laps. It never addresses the memory.
- Cycle 0
Edge 2: the first word, 0xa0, goes into slot 00 and the write pointer moves to 01.
- Cycle 3
Edge 5: the fourth word fills slot 11 and the write pointer wraps to 00. Now both pointers are 00, which is what empty looks like, and
emptyrises. - Cycle 4
Edge 6:
fullis 0, so the fifth push, 0xa4, is accepted into slot 00, over 0xa0. - Cycle 5
Edge 7: the consumer reads one word, 0xa4, and the FIFO is empty again. Words 0xa0 to 0xa3 are lost.
Measured in lesson R5.2 at depth 4. With pointers only as wide as the address, a full FIFO looks empty and four words are lost.
Write until full, then read until empty, checking order.
writes accepted before full=8 (full=1 empty=0) reads before empty=8, out of order=0Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Fresher)
A good fresher answer explains that equal pointers can mean empty or full. It says the extra bit tells an odd number of laps from an even one.
What Interviewers Listen For (Mid-Level)
A good mid-level answer compares the extra bit with a level counter and with keeping one slot empty. It names what each choice costs.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfProve ItBreak ItCompareScale It
- The Extra Pointer Bit in a FIFO
-
CompareA Level Counter Versus the Extra Pointer BitL1 JuniorL2 Mid-Level
Compare keeping a level counter with using the extra pointer bit.
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 level counter gives full, empty and the fill level directly, and it works for any depth. It costs a counter and an adder that updates on reads and writes. The extra bit costs one flop per pointer, but it needs a power-of-two depth. Only the extra-bit style carries over to an asynchronous FIFO, where no single counter can see both clocks.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"A counter is always simpler."
In one clock domain it may be. Across two clocks a shared counter would need both clocks, so asynchronous FIFOs compare Gray pointers instead.
Source Mehta, ASIC/SoC Functional Design Verification (2018) ch. 8.3.5 Design of an asynchronous FIFO using Gray code counters
-
Scale ItInside an Asynchronous FIFOL2 Mid-LevelL3 Senior
Draw an asynchronous FIFO between two unrelated clocks. What crosses between the domains, and how are full and empty computed?
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 memory is written in the write domain and read in the read domain. Only the two pointers cross, each Gray-coded and through two flops. The write side compares its pointer with the synchronized read pointer to compute full. The read side compares the other way to compute empty. Each side sees the other pointer late, so a flag can stay on too long, but it is never wrongly off.
Two Domains, One Memory, Two CrossingsArrows show signals. Everything left of the memory runs on wclk, everything right of it onrclk.Illustrative sequenceCallValueReturnWaiting- Write
The write side stores the word and steps its pointer in the same edge.
Follow the calls, values and waits
- data word 16: Write side → Memory
- The write pointer crosses
The pointer goes through two read-clock flops. The read side compares it with its own pointer to compute
empty.Follow the calls, values and waits
- data wptr 0000: Write side → rq1, rq2
- data wptr 0000: rq1, rq2 → Read side
- Read
The word itself never goes through a synchronizer. By the time the read side sees the pointer, the word has sat still in memory for two cycles.
Follow the calls, values and waits
- data word 16: Memory → Read side
- The read pointer crosses back
The write side computes
fullfrom its own pointer and its copy of the read pointer.Follow the calls, values and waits
- data rptr: Read side → wq1, wq2
- data rptr: wq1, wq2 → Write side
Read the diagram as text
- Write side: wbin_q, wptr_q, full
- wq1, wq2: read pointer, two wclk flops
- Memory: 8 words of 8 bits
- rq1, rq2: write pointer, two rclk flops
- Read side: rbin_q, rptr_q, empty
- Write side → Memory: write word
- Memory → Read side: read word
- Write side → rq1, rq2: wptr_q
- rq1, rq2 → Read side: seen
- Read side → wq1, wq2: rptr_q
- wq1, wq2 → Write side: seen
Each flag is computed in its own domain, from one local pointer and one synchronized copy.
Write domain
Binary write pointer for the RAM address, Gray copy registered for the crossing.
Crossing
Gray write pointer through two read-clock flops; Gray read pointer through two write-clock flops.
Read domain
Empty when the read Gray pointer equals the synchronized write pointer.
Write domain
Full when the write Gray pointer equals the synchronized read pointer with its top two bits inverted.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Mid-Level)
A good mid-level answer draws both clock domains and shows that only the pointers cross. It explains why the flags can be late but are never unsafe.
What Interviewers Listen For (Senior)
A good senior answer names the constraints the crossing needs, such as a limit on skew between pointer bits. It plans assertions for the data path and a reset scheme for both sides.
Misconception
"Send the binary pointer through two flops per bit."
Several bits change at once, and each can land on a different read edge. In the twin, the step from 7 to 8 is read as 0.
Run It
A 4-bit pointer crossing with different wire delays per bit, binary then Gray.
RUNIcarus Verilog · in your browserExpected:first torn value: 7 -> 0binary pointer: 215 changes seen, 32 jumped by more than oneFAIL: a binary pointer with two flops per bit showed values that were neither the old nor the next pointerSee the Fix
`timescale 1ps/1ps // A 4-bit write pointer crosses into a faster read clock. Each bit reaches the reader with its // own wire delay (0, 700, 1400, 2100 ps). The reader samples at its clock and decodes the value. module tb; logic wclk = 0, rclk = 0; logic [3:0] wcount = 0, tx = 0, wire_d = 0, s1 = 0, s2 = 0, now, prev = 0; int torn = 0, steps = 0; always #5000 wclk = ~wclk; // write clock, 10 ns always #3650 rclk = ~rclk; // read clock, 7.3 ns logic [3:0] next; assign next = wcount + 4'd1; always @(posedge wclk) begin wcount <= next; tx <= next ^ (next >> 1); // the pointer as sent: Gray code, registered end for (genvar i = 0; i < 4; i++) begin : wires always @(tx[i]) wire_d[i] <= #(i * 700) tx[i]; end always @(posedge rclk) begin s1 <= wire_d; // two-flop synchronizer s2 <= s1; end always @(s2) begin now = s2 ^ (s2 >> 1) ^ (s2 >> 2) ^ (s2 >> 3); // Gray to binary steps++; if (4'(now - prev) > 1) begin if (torn == 0) $display("first torn value: %0d -> %0d", prev, now); torn++; end prev = now; end initial begin #2000000; $display("Gray pointer: %0d changes seen, %0d jumped by more than one", steps, torn); if (torn == 0) $display("PASS: the Gray pointer only ever showed the old or the next value"); $finish; end endmodulePrints:
Gray pointer: 199 changes seen, 0 jumped by more than onePASS: the Gray pointer only ever showed the old or the next valueMisconception
"Full and empty are exact in an asynchronous FIFO."
Each side sees the other pointer two or three cycles late. Full stays high a little after a read frees space. It is safe, and it costs some throughput.
Source Mehta, ASIC/SoC Functional Design Verification (2018) ch. 8.3.5 Design of an asynchronous FIFO using Gray code counters
Half-Truth
"Gray code makes any counter safe to cross."
Only if it steps by one between samples. The depth must be a power of two, so the wrap is also one step. Reset can also change many bits at once.
Source Golson, Synchronization and Metastability (SNUG Silicon Valley 2014) §5.2
- Write
-
WhyWhy Async FIFO Flags Are Late but SafeL2 Mid-Level
Why is it acceptable that the write side sees the read pointer a few cycles late?
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 late read pointer looks like fewer reads than really happened. So the write side thinks the FIFO is fuller than it is, and full may stay high a little too long. It never thinks there is space that is not there. The same reasoning makes empty late but safe on the read side.
Self-Check
Tick each key point you covered in your answer.
Misconception
"The delay can make the FIFO overflow."
A stale read pointer can only make full assert early or release late. Overflow would need the write side to see reads that have not happened.
Source Mehta, ASIC/SoC Functional Design Verification (2018) ch. 8.3.5 Design of an asynchronous FIFO using Gray code counters
-
What IfSetting an Almost-Full ThresholdL2 Mid-LevelL3 Senior
What if the source needs a warning before full, because it takes 3 cycles to stop?
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
Raise almost-full when the free space drops to the number of words the source can still send after the warning. Here that is 3, plus any cycles the flag itself takes to reach the source. In an asynchronous FIFO, the flag is already pessimistic, which adds a little margin at no extra cost.
Self-Check
Tick each key point you covered in your answer.
Delivery
"Almost-full at half depth is a good default."
The threshold must come from the source's stopping delay. Half depth either wastes space or, for a slow-to-stop source, is not enough.
-
CompareGray-Code Pointers vs a Handshake for Multi-Bit CrossingsL2 Mid-Level
Compare a Gray-coded value with a request/acknowledge handshake for carrying a multi-bit value across clock domains.
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
Gray code changes one bit per step, so a value caught mid-change is either the old or the new one. It suits counters that move by one, such as FIFO pointers. A handshake holds any data stable while a synchronized request crosses and an acknowledge comes back. It carries any value, but takes several cycles per transfer. Choose Gray for streaming pointers, and a handshake or FIFO for occasional wide data.
The Same Edges with Gray PointersAn asynchronous FIFO with Gray-coded pointers, sampled at the read clock clk.All cycles- Cycle 1
Edge 21:
emptyis 1 while the FIFO holds two words. The read side has not seen those writes yet. - Cycle 2
Edge 22: the pointer steps from 1000 to 0000, one bit, the Gray wrap from 15 to 0.
- Cycle 4
Edge 24:
read_levelis 1 with two words held. Low is safe; the read side just waits a cycle.
Edges 20 to 25 of the run: the level the read side sees never rises above the words held.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Gray-code any multi-bit bus and it crosses safely."
Gray only helps when consecutive values differ by one step. Arbitrary data jumps change many bits at once.
Source Cummings, CDC Design and Verification Techniques (SNUG Boston 2008) §5.7.2-5.7.4; Mehta, ASIC/SoC Functional Design Verification ch. 8.3.4 (p155-156)
- Cycle 1
-
Prove ItSolve R6.4.2: The Torn PointerSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
-
Break ItBreaking a Gray Pointer CrossingL3 Senior
The FIFO uses Gray pointers and two-flop synchronizers. How could it still fail in silicon?
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
Gray code assumes the bits arrive close together. If the wires of one pointer differ by more than about a clock period, two steps can mix. Logic between the Gray register and the synchronizer can glitch. And a Gray pointer that is computed but not registered can show several bits changing.
Self-Check
Tick each key point you covered in your answer.
Missed Corner
"Put a false path on the pointer crossing; it is synchronized."
A false path lets the bits of one pointer be routed with any skew. The crossing then needs a maximum-delay or skew constraint instead.
Source Lesson L8.1, Constrain the asynchronous FIFO (set_max_delay on the pointer crossing, false path for hold only)
-
Scale ItCDC Sign-Off on a Many-Clock SoCL3 SeniorL4 Staff
How do you sign off clock domain crossings on an SoC with dozens of clocks?
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
Start with structural analysis: define the clocks and their relationships. Then let the tool find every crossing and check that each has the right synchronizer for its type. Next comes protocol checking: each scheme's rules, such as hold times and Gray steps, become assertions in formal and simulation. Add reconvergence checks and reviewed waivers. Use metastability injection in simulation to expose designs that assume exact timing.
Self-Check
Tick each key point you covered in your answer.
Tool as Truth
"Our regressions pass with all clocks running, so CDC is covered."
RTL simulation never goes metastable and rarely hits the bad clock phase. CDC needs structural and protocol checks, not only passing tests.
Source Mehta, ASIC/SoC Functional Design Verification ch. 8.5 (PDF p186-188); Sutherland, RTL Modeling with SystemVerilog ch. 8.1.6
Wrong Altitude
A staff-level answer that stops at "run the CDC tool".
The interviewer wants the flow: constraints, structure, protocol, reconvergence, waiver review and who owns each step.
-
Prove ItSolve R6.6.1: The Asynchronous FIFOSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
-
WhyWhy FIFO Flags Are Often RegisteredL2 Mid-Level
Why might you register
fullandemptyinstead of computing them from the pointers?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
Combinational flags sit after a pointer compare, and the other block uses them in its own logic in the same cycle. That makes a long path across two blocks. Registered flags start that path at a flop. The cost is that you compute next-cycle flags from the next pointer values, which is easy to get wrong at the boundaries.
Self-Check
Tick each key point you covered in your answer.
Missed Corner
"Registering the flag just delays it by a cycle; that is harmless."
A flag that is one cycle late lets one extra write in at full or one read at empty. Registered flags must be computed from the next pointers, not delayed.
Source Lesson R5.2 and problem R5.2.2 brief: a write is accepted only when write_en is 1 and full is 0, a read only when read_en is 1 and empty is 0, both on the flags before the edge; a refused write changes nothing
-
Prove ItSolve R5.2.1: A FIFO of Any DepthSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
-
What IfA FIFO Whose Depth Is Not a Power of TwoL2 Mid-Level
Asked if they claim it works for any depth
What if the FIFO must be 6 entries deep?
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 address bits no longer wrap by themselves at the end of the memory. Each pointer must wrap by compare: back to 0 after 5. Then track full with a lap bit that flips on each wrap, or keep a level counter. Many teams just round up to 8 when the area allows.
Self-Check
Tick each key point you covered in your answer.
Missed Corner
"Use a 3-bit pointer and let it run to 7; the last two slots just stay unused."
Then the FIFO holds 8, not 6, and full arrives late. Any logic sized for 6 overflows.
Source Lesson R5.3 (a FIFO of any depth) and problem R5.2.1 brief
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"The extra bit is not needed: use 3-bit pointers and call it full when wptr + 1 == rptr."
That works, but one slot can never be used. The twin writes until full and the 8-entry FIFO holds 7.
Run It
The same bench on a FIFO with 3-bit pointers and one slot kept empty.
writes accepted before full=7 (full=1 empty=0) reads before empty=7, out of order=0 FAIL: without the extra bit the 8-entry FIFO held only 7 wordsSee the Fix
// An 8-entry FIFO: AW address bits, pointers of AW + 1 bits.
module fifo #(parameter int W = 8, AW = 3) (
input logic clk, rst_n, wr_en, rd_en,
input logic [W-1:0] wr_data,
output logic [W-1:0] rd_data,
output logic full, empty
);
logic [W-1:0] mem [0:(1<<AW)-1];
logic [AW:0] wptr, rptr; // one bit wider than the address
assign empty = (wptr == rptr);
assign full = (wptr[AW] != rptr[AW]) && (wptr[AW-1:0] == rptr[AW-1:0]);
assign rd_data = mem[rptr[AW-1:0]];
always_ff @(posedge clk)
if (wr_en && !full) mem[wptr[AW-1:0]] <= wr_data;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin
wptr <= '0;
rptr <= '0;
end else begin
if (wr_en && !full) wptr <= wptr + 1'b1;
if (rd_en && !empty) rptr <= rptr + 1'b1;
end
endmodule
module tb;
logic clk = 0, rst_n = 0, wr_en = 0, rd_en = 0;
logic [7:0] wr_data = 0, rd_data;
logic full, empty;
int writes = 0, reads = 0, wrong = 0;
always #5 clk = ~clk;
fifo #(.W(8), .AW(3)) dut (.*);
initial begin
#12 rst_n = 1;
while (!full && writes < 20) begin // write until the FIFO says full
@(negedge clk); wr_en = 1; wr_data = 8'h10 + writes;
@(posedge clk); #1 wr_en = 0; writes++;
end
$display("writes accepted before full=%0d (full=%b empty=%b)", writes, full, empty);
while (!empty) begin // read until empty, checking the order
@(negedge clk); if (rd_data !== 8'h10 + reads) wrong++; rd_en = 1;
@(posedge clk); #1 rd_en = 0; reads++;
end
$display("reads before empty=%0d, out of order=%0d", reads, wrong);
if (writes == 8) $display("PASS: with the extra bit all 8 entries are usable");
$finish;
end
endmodule
Prints: writes accepted before full=8 (full=1 empty=0) reads before empty=8, out of order=0 PASS: with the extra bit all 8 entries are usable
Missed Corner
"The extra bit works for any depth."
The wrap trick needs a power-of-two depth, so the address bits roll over exactly at the end. Other depths need pointers that wrap by compare, plus a lap bit or a counter.
Source Problem R5.2.2 brief (DEPTH a power of two) and lesson R5.3 (a FIFO of any depth)
Buzzword Without Mechanism
Says "the MSB tells full from empty" without saying how.
The interviewer wants the rule: same lap and same address is empty, different lap and same address is full.