First Word Fall Through FIFO Wrapper
High-performance pipelines and AXI interfaces require First-Word Fall-Through (FWFT) FIFOs where data is available immediately without requiring a read cycle first. However, standard hardware FIFO primitives, such as those built from synchronous block RAMs, inherently have a one-cycle read latency.
The FWFT wrapper module interfaces with a standard synchronous FIFO and hides this latency. It automatically prefetches the next word from the standard FIFO so that fwft_dout always presents valid data immediately when fwft_empty is low. When the user asserts fwft_read, the current word is consumed, and the next word (if available) appears on fwft_dout on the following clock cycle.
The standard FIFO primitive being wrapped behaves as follows: it asserts std_empty when it contains no data. When std_read is asserted, the next word appears on std_dout on the following clock cycle and remains stable until the cycle after the next std_read is asserted.
Timing and Reset Rules
- Clock edge:
posedge clk - Reset type: Asynchronous, active-low (
rst_n) - Output values on reset:
std_readgoes to 0,fwft_emptygoes to 1, andfwft_doutgoes to8'b00000000 - Priority: If
fwft_readis asserted whilefwft_emptyis high, the read is invalid and must be ignored
Worked Trace
Cycle 1: rst_n=0 → std_read=0, fwft_empty=1, fwft_dout=0 Cycle 2: rst_n=1, std_empty=0 (Standard FIFO has data) → Wrapper prefetches by asserting std_read=1 Cycle 3: std_dout=D1 (Data arrives) → std_read=0, fwft_empty=0, fwft_dout=D1 Cycle 4: fwft_read=1, std_empty=0 (User reads, standard FIFO has more data) → Wrapper fetches next word with std_read=1 Cycle 5: std_dout=D2 (Next data arrives) → std_read=0, fwft_empty=0, fwft_dout=D2. User asserts fwft_read=1, but std_empty=1 (Standard FIFO is empty) → std_read=0 Cycle 6: User read completes, no more data → fwft_empty=1, fwft_dout=0
{ "signal": [
{ "name": "clk", "wave": "p......." },
{ "name": "rst_n", "wave": "01......" },
{ "name": "std_empty", "wave": "10...1.." },
{ "name": "std_read", "wave": "0.1010.." },
{ "name": "std_dout", "wave": "x..=.=.x", "data": ["D1", "D2"] },
{ "name": "fwft_read", "wave": "0...110." },
{ "name": "fwft_empty", "wave": "1..0..1." },
{ "name": "fwft_dout", "wave": "=.=.=.=.", "data": ["0", "D1", "D2", "0"] }
], "head": { "text": "FWFT wrapper prefetching data and handling back-to-back reads." } }Port Table
| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | std_empty | input | 1 | High when the standard FIFO has no data | | std_dout | input | 8 | Data output from the standard FIFO (1-cycle latency) | | std_read | output | 1 | Read enable to the standard FIFO | | fwft_read | input | 1 | Read enable from the user to consume the current word | | fwft_empty | output | 1 | High when no data is available for the user | | fwft_dout | output | 8 | FWFT data output; must be 8'b0 when fwft_empty is 1 |
Constraints
- Clock is positive-edge triggered and reset is asynchronous active-low
fwft_doutmust explicitly output8'b00000000whenfwft_emptyis high, including during resetstd_readmust only be asserted ifstd_emptyis low- If
fwft_readis asserted whilefwft_emptyis high, the read must not corrupt the internal state
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.