# Synchronous FIFO — RTL and self-checking verification A small single-clock **SystemVerilog** FIFO (first-in/first-out buffer), designed as an independently reproducible digital-hardware learning project. It demonstrates queue-control state, handshakes, boundary semantics, parameter handling, and an independent reference-model testbench. ## Reproduce Install **Icarus Verilog 12** (or a compatible simulator) and run from the repository root: ```sh bash projects/fifo-rtl/run_tests.sh ``` The runner covers `DEPTH=1,3,4,8` with 8-bit and 16-bit data widths. Each configuration compiles RTL and the testbench, runs directed stimuli and **800 deterministic pseudo-random cycles**, and requires a final `PASS` line. It writes separate per-configuration VCD and text logs to `/tmp/admo-fifo-regression` by default, or an output directory supplied as its first argument. ## Interface contract | Signal | Meaning | | --- | --- | | `wr_en`, `wr_data` | Request to write one word on rising `clk` | | `rd_en` | Request to read one word on rising `clk` | | `rd_data` | Registered last **accepted** read; unchanged otherwise | | `count`, `full`, `empty` | Post-clock occupancy and boundary flags | | `rst_n` | Active-low **asynchronous** reset for pointers, count and output register | - An empty FIFO **does not fall through**: simultaneous push and pop accepts the push only; the read is blocked. - A full FIFO **supports replacement**: simultaneous push and pop accepts both, returning the old oldest word, enqueuing the new word and maintaining full occupancy. - Writes on full without a valid pop are ignored. Reads on empty are ignored; last output is retained. - Both pointers wrap explicitly at `DEPTH-1`, so non-power-of-two depths work. - Storage registers are **not reset**. After reset, `count=0` makes their old contents inaccessible until overwritten. - No explicit ready/valid output is provided; acceptance is determined by `full`, `empty`, and the simultaneous transaction rule. ## Tests and evidence The testbench uses a **shift-array reference queue** (intentionally unlike RTL's read/write pointers). Every cycle it compares count, flags and registered output to predicted behaviour. Tests include empty read, simultaneous operations at both boundaries, exact capacity, overflow prevention, underflow prevention, pointer wrap, asynchronous reset checked before the next clock edge and reset while nonempty, and fixed-seed pseudo-random traffic. Four parameter combinations exercise depth one, odd depth, conventional depth, and a wider data bus. Real simulation traces are VCD files, not artist-rendered waveforms. Test logs and a short waveform trace can be published with the case study after actually running the suite. To regenerate the visual trace from the depth-four VCD (generated by the runner): ```sh python3 projects/fifo-rtl/trace_to_svg.py \ /tmp/admo-fifo-regression/fifo_depth4_width8.vcd \ assets/fifo-waveform.svg ``` The SVG samples registered outputs one nanosecond after successive rising edges; it is a presentation of actual simulation signal values, not physical measurements. ## Boundaries and future work This is a **single-clock** FIFO with behavioural register-array storage. It is **not** an asynchronous clock-domain-crossing FIFO, a production bus interface, a timing closure result, an FPGA deployment, or proof of exhaustive formal verification. Future work could add configurable fall-through semantics, ready/valid interfaces, SVA or formal properties, and synthesis studies.