Skip to content

nelsoncsc/verilaxi

Repository files navigation

verilaxi

verilaxi is a lightweight, Verilator-friendly AXI verification library written in SystemVerilog.

It provides simple, task-based AXI, AXI-Lite, and AXI-Stream drivers, monitors, and test environments designed for fast RTL bring-up — without UVM.

For a deeper walkthrough of the architecture, module inventory, register maps, and verification flow, see the Developer Guide.


✨ Features

  • ✅ AXI4, AXI-Lite, and AXI-Stream support
  • ✅ UART core, AXI-Lite GPIO, and UART↔AXI-Lite control-plane blocks
  • ✅ AXI-Stream packet, beat, and weighted round-robin arbitration
  • ✅ AXI-Stream width converters — integer-ratio (k:1 up, 1:k down) and rational-ratio (e.g. 16↔24)
  • ✅ Synchronous and asynchronous AXI-Stream FIFOs
  • ✅ Verilator-first (tested with FST + Surfer)
  • ✅ No UVM, no factory, no phases
  • ✅ Task-based drivers (write, read, write_burst, read_burst)
  • ✅ Parameterized widths (ADDR, DATA, ID)
  • ✅ AXI stream backpressure (SRC_BP / SINK_BP) and AXI slave ready backpressure (READY_PROB)
  • ✅ Selectable test scenarios via TESTTYPE plusarg
  • ✅ Clean Makefile-driven test selection with interactive menu
  • ✅ SVA protocol checkers for AXI4-Full, AXI-Lite, and AXI-Stream, plus 4KB AXI burst-boundary checks (Verilator --assert)

Related Articles

These sistenix posts are the narrative layer for the repository. The intent is that a reader can understand the design choices in the blog, then inspect the exact RTL, VIP, and testbench code here in verilaxi.


📁 Repository Structure

verilaxi/
├── rtl/
│   ├── axi/        snix_axi_dma, snix_axi_cdma, snix_axi_mm2mm, mm2s, s2mm
│   ├── axil/       snix_axil_register, snix_axil_gpio, snix_uart_axil_slave, snix_uart_axil_master
│   │               snix_axi_dma_csr, snix_axi_cdma_csr
│   ├── axis/       snix_axis_arbiter, snix_axis_fifo, snix_axis_afifo, snix_axis_register
│   │               snix_axis_upsizer, snix_axis_downsizer
│   │               snix_axis_rr_converter, snix_axis_rr_upsizer, snix_axis_rr_downsizer
│   ├── uart/       snix_uart_lite
│   └── common/     snix_sync_fifo, snix_async_fifo, snix_register_slice
├── tb/
│   ├── classes/     axi_master, axi_slave, axil_master, axis_source, axis_sink …
│   ├── interfaces/  axi4_if, axil_if, axis_if
│   ├── packages/    axi_pkg, axi_dma_pkg, axi_cdma_pkg
│   ├── assertions/  axis_checker, axil_checker, axi_mm_checker, axi_4k_checker
│   └── tests/       test_dma, test_cdma, test_axil_register, test_axil_gpio, test_axis_*
├── filelists/      common.f, tb_top.f
├── mk/             config.mk, build.mk, menu.mk, help.mk
└── Makefile

🚀 Getting Started

Clone

git clone https://github.com/nelsoncsc/verilaxi.git
cd verilaxi

Requirements

  • Verilator 5.046
  • Yosys 0.63
  • SystemVerilog support enabled
  • Surfer (recommended) or GTKWave for FST viewing

This repository is validated against Verilator 5.046 and Yosys 0.63. Older packaged 5.x Verilator releases may fail to parse or build parts of the testbench and should not be assumed to work. Older Yosys releases such as 0.33 may also fail on some of the newer SystemVerilog syntax used by modules like snix_axis_arbiter.


🧪 Example: AXI Write / Read

logic [31:0] wr_data[];
logic [31:0] rd_data[];

wr_data = new[4];
rd_data = new[4];

wr_data[0] = 32'h1111_0001;
wr_data[1] = 32'h2222_0002;
wr_data[2] = 32'h3333_0003;
wr_data[3] = 32'h4444_0004;

driver.write_read_check(32'h100, wr_data, rd_data, 4);

Build and Run

Interactive menu (prompts for test scenario and backpressure settings):

make
make run TESTNAME=dma            # AXI4 DMA (stream → memory, memory → stream)
make run TESTNAME=cdma           # AXI4 CDMA (memory-to-memory copy)
make run TESTNAME=axil_register  # AXI-Lite register
make run TESTNAME=axil_gpio      # AXI-Lite GPIO with user LEDs, RGB LEDs, and debounced buttons
make run TESTNAME=uart_lite      # UART core loopback test
make run TESTNAME=uart_axil_slave   # AXI-Lite UART peripheral
make run TESTNAME=uart_axil_master  # UART-to-AXI-Lite bridge
make run TESTNAME=axis_register  # AXI-Stream register slice
make run TESTNAME=axis_arbiter   # AXI-Stream round-robin arbiter (packet mode)
make run TESTNAME=axis_arbiter_beat      # AXI-Stream beat-mode arbiter
make run TESTNAME=axis_arbiter_weighted  # AXI-Stream weighted packet arbiter
make run TESTNAME=axis_fifo      # AXI-Stream FIFO
make run TESTNAME=axis_afifo         # AXI-Stream async FIFO / CDC FIFO
make run TESTNAME=axis_upsizer       # AXI-Stream integer upsizer  (IN=8  → OUT=32)
make run TESTNAME=axis_downsizer     # AXI-Stream integer downsizer (IN=32 → OUT=8)
make run TESTNAME=axis_rr_converter  # AXI-Stream rational-ratio converter (IN=32 → OUT=48)
make run TESTNAME=axis_rr_upsizer    # AXI-Stream rational-ratio upsizer   (IN=16 → OUT=24)
make run TESTNAME=axis_rr_downsizer  # AXI-Stream rational-ratio downsizer  (IN=24 → OUT=16)

Simulation Waveform

# AXI-Stream arbiter with sink and source backpressure
make run TESTNAME=axis_arbiter SRC_BP=1 SINK_BP=1

# Beat-mode arbiter
make run TESTNAME=axis_arbiter_beat SRC_BP=1 SINK_BP=1

# Weighted packet arbiter
make run TESTNAME=axis_arbiter_weighted SRC_BP=1 SINK_BP=1

# AXI-Stream async FIFO in streaming mode
make run TESTNAME=axis_afifo FRAME_FIFO=0 TESTTYPE=1 SRC_BP=1 SINK_BP=1

# AXI-Stream async FIFO in frame-store-and-forward mode
make run TESTNAME=axis_afifo FRAME_FIFO=1 TESTTYPE=1 SRC_BP=1 SINK_BP=1

Select a test scenario and stress with AXI slave backpressure:

# CDMA: 4KB boundary test with 80% AXI ready probability
make run TESTNAME=cdma TESTTYPE=1 READY_PROB=80

Simulation Waveform

# DMA: 4KB boundary test
make run TESTNAME=dma TESTTYPE=3 READY_PROB=80

Simulation Waveform

Synthesis

make synth SYNTH_NAME=axis_arbiter        SYNTH_TARGET=generic
make synth SYNTH_NAME=uart_lite           SYNTH_TARGET=generic
make synth SYNTH_NAME=axil_gpio           SYNTH_TARGET=generic
make synth SYNTH_NAME=uart_axil_slave     SYNTH_TARGET=generic
make synth SYNTH_NAME=uart_axil_master    SYNTH_TARGET=generic
make synth SYNTH_NAME=axis_fifo           SYNTH_TARGET=generic
make synth SYNTH_NAME=axis_afifo          SYNTH_TARGET=artix7
make synth SYNTH_NAME=axis_upsizer        SYNTH_TARGET=artix7
make synth SYNTH_NAME=axis_downsizer      SYNTH_TARGET=artix7
make synth SYNTH_NAME=axis_rr_converter   SYNTH_TARGET=artix7
make synth SYNTH_NAME=axis_rr_upsizer     SYNTH_TARGET=artix7
make synth SYNTH_NAME=axis_rr_downsizer   SYNTH_TARGET=artix7
make synth SYNTH_NAME=dma                 SYNTH_TARGET=artix7
make synth SYNTH_NAME=cdma                SYNTH_TARGET=generic

Simulation logs and FST waveforms are written with parameter-aware filenames so sweep runs do not overwrite each other. For example, make run TESTNAME=axis_afifo FRAME_FIFO=1 TESTTYPE=1 SRC_BP=1 SINK_BP=1 produces work/logs/axis_afifo_ff1_tt1_src1_sink1.log and work/waves/axis_afifo_ff1_tt1_src1_sink1.fst.

Docker

A minimal Docker environment is included for reproducible Linux runs with Verilator 5.046, Yosys 0.63, and make.

docker build -t verilaxi .
docker run --rm -it -v "$PWD":/workspace -w /workspace verilaxi \
  make run OBJ_DIR=work/obj_dir_linux TESTNAME=axis_afifo FRAME_FIFO=1 TESTTYPE=1 SRC_BP=1 SINK_BP=1

This is also the recommended cross-platform path for macOS, Linux, and Windows via WSL2 when you want a consistent tool environment. Using a container-specific OBJ_DIR avoids collisions between host-built binaries and Linux container builds.

Useful Docker examples:

# Tool versions
docker run --rm -it -v "$PWD":/workspace -w /workspace verilaxi \
  bash -lc "verilator --version && yosys -V"

# Synthesis
docker run --rm -it -v "$PWD":/workspace -w /workspace verilaxi \
  make synth SYNTH_NAME=axis_afifo SYNTH_TARGET=generic

# Sweep wrapper
docker run --rm -it -v "$PWD":/workspace -w /workspace verilaxi \
  ./scripts/sweep.sh synth generic

Sweep Script

A convenience regression script is included for broader simulation and synthesis sweeps:

scripts/sweep.sh sim
scripts/sweep.sh synth both
scripts/sweep.sh all both

The simulation sweep covers the AXIS register, UART core, AXI-Lite GPIO, UART/AXI-Lite control-plane blocks, arbiter (packet/beat/weighted), FIFO, AFIFO, upsizer, downsizer, rr_converter, rr_upsizer, rr_downsizer matrices, axil_register, and DMA/CDMA runs with READY_PROB=70. The synthesis sweep covers all supported designs for generic, artix7, or both.

Acknowledgements

This project was developed independently. Credit is due to the wider open-source AXI community for helping shape good engineering practice around AXI design and verification. In particular, ZipCPU's AXI articles and examples, together with Alex Forencich's AXI and AXI-Stream component work, were useful sources of inspiration and reference.

This repository does not use code from my current or previous employers; rather, it is a summary of my learnings during my spare time. AI tools were used as auxiliary tools for debugging, scripting, and documentation support.

About

SystemVerilog AXI, AXI-Lite, and AXI-Stream verification and DMA learning project using Verilator, Yosys, Docker, and GitHub Actions

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages