File size: 1,890 Bytes
2b4ae64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# Task 7: Parameterized Ring Buffer (Medium)

## Objective

Implement a power-of-2-depth ring buffer (circular FIFO) with push/pop interface,
full/empty flags, and an item count output. Ring buffers are the standard data
structure for KV-cache management and activation streaming in inference accelerators.

## Interface

```verilog
module ring_buffer #(
    parameter DEPTH  = 8,   // must be power of 2
    parameter DATA_W = 8
) (
    input  wire              clk,
    input  wire              rst,          // synchronous reset, active high
    input  wire              push,
    input  wire [DATA_W-1:0] push_data,
    input  wire              pop,
    output wire [DATA_W-1:0] pop_data,    // valid only when !empty
    output wire              full,
    output wire              empty,
    output wire [$clog2(DEPTH):0] count   // 0 … DEPTH (extra bit for full detection)
);
```

## Specification

- On `push` when **not full**: store `push_data` at tail, advance tail, increment count.
- On `pop` when **not empty**: advance head, decrement count.
- On **simultaneous push + pop** when **neither full nor empty**: both happen, count unchanged.
- On `push` when **full**: push is silently ignored (no data loss).
- On `pop` when **empty**: pop is silently ignored.
- `rst` (synchronous): clears head, tail, and count to 0.
- `pop_data` always reflects `mem[head]` combinatorially (valid only when `!empty`).
- `full` is true when `count == DEPTH`.
- `empty` is true when `count == 0`.

## Scoring

- Correct compilation: 10%
- Passing simulation tests: 70%
- Area efficiency vs reference: 20%

## Notes

- Wrap head and tail with modulo arithmetic or by masking to `$clog2(DEPTH)-1` bits.
- The count register needs one extra bit: `[$clog2(DEPTH):0]` to distinguish 0 from DEPTH.
- Simultaneous push + pop is the tricky case — handle it explicitly with `do_push`/`do_pop` wires.