sync_fifo·A single-clock first-in, first-out buffer.
This is everything Akrida knew about the design. It never sees the design's code.
sfifo is a single-clock first-in, first-out buffer. A producer pushes
words with i_wr, a consumer pops them with i_rd, and the FIFO reports
how full it is. The read side is first-word fall-through: whenever the FIFO
is not empty, o_data already shows the oldest word, and i_rd removes it.
+------------------------------+
i_wr --> | | --> o_data
i_data -> | 16 x 8-bit storage | --> o_empty
o_full <- | (oldest word at the head) | <-- i_rd
o_fill <- | |
+------------------------------+
| Name | Default | Meaning |
|---|---|---|
| BW | 8 | Data width in bits |
| LGFLEN | 4 | log2 of the depth; the FIFO holds 2^LGFLEN words |
| OPT_ASYNC_READ | 1 | 1 reads storage combinationally; 0 uses a registered read path |
| OPT_WRITE_ON_FULL | 0 | 1 lets a write proceed when full if a read happens in the same cycle |
| OPT_READ_ON_EMPTY | 0 | 1 lets a word written into an empty FIFO pass straight through in the same cycle |
The verification target is BW=8, LGFLEN=4, OPT_ASYNC_READ=0, OPT_WRITE_ON_FULL=0, OPT_READ_ON_EMPTY=0: 8-bit words, depth 16, registered
read path, and neither pass-through option. The requirements below describe
that configuration.
| Port | Dir | Width | Description |
|---|---|---|---|
| i_clk | in | 1 | Clock. All inputs are sampled on the rising edge. |
| i_reset | in | 1 | Synchronous reset, active high |
| i_wr | in | 1 | Write request: push i_data at this clock edge |
| i_data | in | BW | Write data |
| o_full | out | 1 | High when the FIFO holds 2^LGFLEN words |
| o_fill | out | LGFLEN+1 | Number of words currently held (0 to 2^LGFLEN) |
| i_rd | in | 1 | Read request: pop the word on o_data at this clock edge |
| o_data | out | BW | Oldest word in the FIFO. Valid whenever o_empty is low. |
| o_empty | out | 1 | High when the FIFO holds no words |
o_fill equals the number of words held: the number of
accepted writes minus the number of accepted reads since reset.o_empty is high exactly when o_fill is 0.o_full is high exactly when o_fill is 2^LGFLEN.o_fill, o_empty and o_full change only on a clock
edge: an accepted write or read at one edge is reflected in the status
outputs for the following cycle, never earlier in the same cycle.i_wr is high and o_full is low at
a rising clock edge. The word on i_data becomes the newest entry.o_fill stays at 2^LGFLEN, and no data is lost or overwritten.
This holds even when i_rd is high in the same cycle.o_empty is low, o_data holds the oldest word in
the FIFO (first-word fall-through). No read request is needed to see it.i_rd is high and o_empty is low at
a rising clock edge. The oldest word is removed and, if words remain,
o_data shows the next oldest one in the following cycle.o_fill stays at
0 and later data is not affected.i_wr and
i_rd are high, both are accepted at the same edge: the oldest word is
removed, the new word is appended, and o_fill is unchanged.i_wr and
i_rd are high, the held word is removed and the new word becomes the
only entry. In the next cycle o_empty is low and o_data is the new
word.i_wr and i_rd are high,
only the write is accepted (see REQ-RD-3).i_wr and i_rd are high,
only the read is accepted (see REQ-WR-2); o_full stays high during that
cycle.i_reset is high at a clock edge, the FIFO is emptied:
in the next cycle o_fill is 0, o_empty is high and o_full is low.
Writes and reads in a reset cycle are ignored.o_data.Separate read and write clocks, almost-full/almost-empty thresholds and the
non-default option settings are not part of this verification target. The
contents of o_data while o_empty is high are undefined.