Skip to question
asic.fyi
DesignVerificationSystemVerilogFirmwareArchitectureInterviews
asic.fyi/Interview questions/Build a Two-Bank Ping-Pong Frame Buffer

Hardware interview practice

Build a Two-Bank Ping-Pong Frame Buffer

MediumTimingSystemVerilog

Input and output use the same clock. Every frame is exactly four accepted bytes. Two 4-byte banks allow the producer to fill one bank while the consumer drains the other. Completed frames must leave in arrival order. Implement bank ownership, atomic handoff, ready/valid backpressure, and fixed four-beat output framing.

Try it in the question bankReason first. Then compare.

Keep this exact question selected while you check your answer and review the full solution.

Practice this question →
Starting point

Question code

module pingpong4(input logic clk,rst_n,
 input logic in_valid, output logic in_ready, input logic [7:0] in_data,
 output logic out_valid, input logic out_ready, output logic [7:0] out_data,
 output logic out_first,out_last);
// each input frame is exactly four accepted bytes
Reviewed example

Work through one case

Input
Case 1: Input [1,2,3,4]
Case 2: Input frames [10,11,12,13] and [20,21,22,23]
Case 3: If output stalls on byte 12, `out_data=12`, `out_valid=1`, and both framing flags
Expected output
Case 1: Must later output [1,2,3,4] with `out_first` only on 1 and `out_last` only on 4.
Case 2: May fill both banks before output starts, but must drain in that same frame order.
Case 3: Must remain stable; input may continue into the other free bank only.

The shown result follows by applying this rule: Ownership transitions are atomic and prevent simultaneous producer/consumer access to one bank. The cases also demonstrate this requirement: Deassert `in_ready` only when no bank is available for filling. Producer and consumer may access different banks in the same cycle but must never access the same bank concurrently.

What to cover

Requirements

  1. Track each bank as FREE, FILL, FULL, or DRAIN plus monotonically ordered frame ownership. Reset makes both banks free and clears all valid/framing outputs.
  2. Write one byte only on an input handshake. After the fourth byte, atomically mark that bank FULL; never expose a partially filled bank to the consumer.
  3. Drain the oldest FULL bank. Hold data, first, and last stable while stalled; after the fourth output handshake, atomically free the bank.
  4. Deassert `in_ready` only when no bank is available for filling. Producer and consumer may access different banks in the same cycle but must never access the same bank concurrently.
asic.fyi · Learn silicon end to end.info@asic.fyi