← All problems

Ping-Pong Buffer Controller

Medium · Sequential · SystemVerilog

Design a ping-pong (double-buffer) controller that manages two fixed-depth storage banks, keeping one bank accepting writes while the other is drained by a reader, with an atomic bank-swap when the write bank becomes full.

The module maintains two internal banks, each capable of holding DEPTH words of DATA_W bits. At all times one bank is the **write bank** and the other is the **read bank**. After reset, bank 0 is the write bank and bank 1 is the read bank (initially empty).

**Write port behavior:**

- {wr_ready} is high when the write bank has at least one empty slot. - When {wr_en} is asserted and {wr_ready} is high, {wr_data} is written into the next available slot of the write bank on the rising clock edge and the write pointer advances. - When {wr_en} is asserted but {wr_ready} is low, the write is suppressed — no data is written and no pointer advances.

**Bank-swap:**

- When a write fills the last slot of the write bank (the write pointer reaches DEPTH after the write), the two banks swap roles atomically on the same clock edge: the newly full bank becomes the read bank and {rd_valid} asserts; the previously empty read bank becomes the new write bank. - A swap only occurs when the incoming read bank is empty. If the read bank still contains unread words when the write bank becomes full, both banks are occupied and {wr_ready} deasserts — no further writes are accepted until the reader drains the read bank completely and a swap can occur.

Open this challenge in the editor →