Fix a receive buffer that sizes its FIFO from the burst arithmetic but leaves out the consumer's stall, so that its depth is the smallest that loses no word.
Hardware context: A receive buffer between a bursting camera and a consumer that stalls, then reads every PERIOD cycles. Fix the burst buffer whose depth formula leaves out the consumer's stall.
A camera sends bursts of up to 16 words, one per cycle, into a receive buffer. The consumer behind it may wait up to 4 cycles before its first read, then reads one word every 2 cycles. The buffer's FIFO is built from flops, so the brief asks for the smallest depth that loses nothing, computed from the parameters (lesson R5.3). In the lab, overflow went high on the longest burst.
This is a Fix problem: the design below works except for one defect. Find it so that every pattern within the brief loses no word and the FIFO holds exactly the depth the brief asks for.
Brief: parameters BURST, PERIOD (2 or more) and STALL; the FIFO ports of R5.3 (clk, rst_n asynchronous and active-low, write_en, write_data, read_en; read_data, read_valid, full, empty, overflow). DEPTH is the smallest depth that loses no word when a burst of BURST words starts in cycle 0 and the consumer waits STALL cycles, then reads in the last cycle of every PERIOD; both requests are decided on the count before the edge. Any shorter burst or stall must fit too. Corner cases: no stall, a burst whose last word arrives with no read, a depth that is a power of two. The tests run five copies with their own parameters. Synthesis check: the design must build on the site's synthesis flow with no latch. The cell and level counts come from an open-source flow and are a proxy for area and depth, not a foundry result.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
which | 3 | input of each check |
burst | 8 | input of each check |
stall | 8 | input of each check |
Full specification
module burst_buf #(
parameter int BURST = 16, // the longest burst: words at one per cycle
parameter int PERIOD = 2, // the consumer reads one word every PERIOD cycles (2 or more)
parameter int STALL = 4, // the longest wait before the consumer's first read cycle
parameter int WIDTH = 8
) (
input logic clk,
input logic rst_n, // asynchronous, active-low
input logic write_en,
input logic [WIDTH-1:0] write_data,
input logic read_en,
output logic [WIDTH-1:0] read_data,
output logic read_valid,
output logic full,
output logic empty,
output logic overflow // a write was refused: a word was lost
);
// the depth, and the FIFO
endmodule
| Copy | BURST | PERIOD | STALL |
|---|---|---|---|
| 0 | 16 | 2 | 4 |
| 1 | 11 | 2 | 3 |
| 2 | 20 | 3 | 5 |
| 3 | 12 | 4 | 0 |
| 4 | 10 | 3 | 2 |
Each case resets the buffer and fills it with writes only for 24 cycles: capacity is the number of writes accepted. It then resets it again and runs 72 cycles of one pattern within the copy's brief: a burst of words numbered 0, 1, 2 ..., one per cycle from cycle 0, and a consumer that waits s cycles, then reads in the last cycle of every PERIOD. The result is capacity, lost (writes offered while full), most_held (words held after an edge, at most), words_out, order_errors (words read out of order) and overflow at the end.
Examples
Example 1
The default buffer- Input
BURST 16, PERIOD 2, STALL 4: a fill, then a burst of 16 with a stall of 4
- Output
capacity = 11, lost = 0, most_held = 10, words_out = 16, order_errors = 0, overflow = no
The consumer first reads in cycle 5 and then every 2 cycles, so 6 of the 16 words leave during the burst and 10 are held at the peak. The last word arrives in cycle 15, a read cycle, so the depth is 11. The shipped buffer counts 8 reads, holds 9 words and loses 2.
Example 2
A stall of 3- Input
BURST 11, PERIOD 2, STALL 3: a fill, then a burst of 11 with a stall of 3
- Output
capacity = 8, lost = 0, most_held = 7, words_out = 11, order_errors = 0, overflow = no
4 reads land inside the 11-word burst, so the peak is 7; the last word arrives with a read, so the depth is 8, a power of two. The 8-word FIFO never fills.
Example 3
Reads every 3- Input
BURST 20, PERIOD 3, STALL 5: a fill, then a burst of 20 with a stall of 5
- Output
capacity = 16, lost = 0, most_held = 15, words_out = 20, order_errors = 0, overflow = no
Reads in cycles 7, 10, 13, 16 and 19: 5 inside the burst, a peak of 15, and the last word arrives in cycle 19 with a read: 16 words.
Constraints and contract
- PERIOD is at least 2 and STALL is less than BURST.
- Keep the module names burst_buf and sync_fifo and their ports; the whole design is in your file.
Hints
Hint 1
Run the first example and compare capacity with most_held. How many words did the consumer take during the burst?
Hint 2
The consumer's first read cycle comes STALL cycles later than it would with no stall. Which of the three localparams should know that?
Hint 3
Count the reads that land inside the burst: they start after the stall, one every PERIOD cycles, so there are (BURST - STALL) / PERIOD of them, rounded down.
What the grader checks: Fifteen patterns run on five copies with their own BURST, PERIOD and STALL: a capacity fill, then a burst and a stall within the copy's brief, with the words held, lost and read compared with an independent model of a FIFO of the depth the brief asks for. Parameters outside the five copies follow the same arithmetic but are not simulated. The synthesis check adds the latch count.
The submitted design must synthesize with 0 latches and no combinational loop. Counts come from the pinned open-source synthesis flow. They are proxies for logic size and depth, not physical area or timing.
15 checks on Icarus Verilog + Yosys · server. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.
See all 1 steps and the final capstone