Skip to content

Contributing to FlooNoC

Thanks for taking the time to contribute! FlooNoC is developed at the Integrated Systems Laboratory of ETH Zurich and the University of Bologna as part of the PULP Platform, and we welcome bug reports, questions and pull requests from outside the group.

This repository holds two things that are built and tested very differently:

Part Language Location License
The FlooNoC hardware IPs SystemVerilog hw/ Solderpad Hardware License 0.51
The FlooGen network generator Python floogen/ Apache License 2.0

Most sections below are split along that line, so start by working out which half your change touches. Changes to floogen/templates/ count as both: they are Python-side files that emit SystemVerilog.

Reporting a Bug or Asking a Question

Please open a GitHub issue. To get a useful answer on the first reply, include:

  • For FlooGen: the configuration .yml that reproduces the problem, the output of floogen --version (if exists), and the full traceback.
  • For the hardware IPs: the simulator and version, the testbench (TB_DUT), and whether the RTL was hand-written or generated by FlooGen. If generated, attach the configuration file.

Development Setup

FlooGen (Python)

FlooGen is managed with uv, which resolves the dependencies pinned in uv.lock:

uv sync --locked --group dev
uv run floogen --help

pip works too, if you prefer it:

python3 -m venv .venv && source .venv/bin/activate
pip install -e . && pip install --group dev

FlooGen supports Python 3.10 and newer, and CI generates a network on every version from 3.10 to 3.14. Please do not use syntax or standard-library APIs that were added after 3.10.

Hardware

The hardware IPs need Bender >= 0.31.0 for dependency management and either QuestaSim or VCS to simulate:

bender checkout
make compile-vsim
make run-vsim-batch TB_DUT=tb_floo_router

See the Getting Started guide for the full list of testbenches and for the mesh testbenches, which require RTL generated by FlooGen first.

Git Hooks

The repository ships a set of pre-commit hooks that catch formatting, linting, spelling and licensing problems before they reach a pull request. The same hooks run on every pull request in the lint workflow, so installing them locally saves a review cycle.

Hooks are managed with prek, a drop-in replacement for pre-commit written in Rust. It is part of the dev dependency group, so no separate installation is needed:

uv run prek install --allow-missing-config --hook-type pre-commit --hook-type pre-push

--allow-missing-config keeps git commit working when you check out a branch that predates the hook configuration, for instance an older pull request. The configuration in .pre-commit-config.yaml is the standard format, so pre-commit install works just as well if you already have that installed — prek is only the recommended runner because it is faster and needs no Python environment of its own.

Stage Hooks
pre-commit trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-merge-conflict, check-case-conflict, mixed-line-ending, ruff check, ruff format, ty check, reuse lint-file, typos
pre-push pytest

ruff, ty, reuse, typos and pytest run through uv, so their versions come from uv.lock and are identical locally and in CI. Verible and Slang are not part of the hooks, they only run in CI.

To run them by hand:

# All hooks over the whole repository, as CI does it.
uv run prek run --all-files

# A single hook, e.g. after adding a waiver.
uv run prek run typos --all-files

# Only the files changed in the last commit.
uv run prek run --last-commit

Some hooks fix files instead of just reporting, for example trailing-whitespace. When that happens the commit is aborted with the fixes applied but unstaged; review them, git add them and commit again. To skip the hooks for a single commit, use git commit --no-verify — please only do this for work-in-progress commits that you clean up before opening a pull request, since CI runs the same checks anyway.

The typos hook spell-checks comments, documentation and identifiers. It deliberately runs without --write-changes, because its guesses for identifiers can be wrong. If it flags a term that is spelled correctly, add it to _typos.toml:

[default.extend-words]
# An `inport` is an input port, not an `import`.
inport = "inport"

Making Changes

Hardware Changes

  • Run the testbench that covers the module you touched, and say in the pull request which simulator you used. hw/tb/ lists what is available.
  • Keep Verible happy: CI lints all of hw/ with waivers from util/verible.waiver. Add a waiver only when the lint rule is wrong for the case at hand, and explain why in the waiver file.
  • New parameters and ports should be documented in the relevant page under docs/floonoc/.

FlooGen Changes

  • Add or extend a test under floogen/tests/; run them with uv run -m pytest.
  • If you add a configuration option or a topology feature, add an example configuration under floogen/examples/. Examples are not just documentation — CI generates from them.
  • When you touch floogen/templates/, regenerate every example config and check that the RTL still elaborates. CI elaborates the cross product of {axi_mesh, nw_mesh} and {xy, yx, src, id} with Slang, so a template change that only works for one routing algorithm will fail there:
uv run floogen rtl -c floogen/examples/nw_mesh_xy.yml -o generated

Documentation Changes

The documentation is built with Zensical from docs/. Preview it locally with:

uv run zensical serve -o

The navigation is not inferred from the directory tree — it is the nav table in zensical.toml. A new page stays invisible until you add it there.

Licensing and File Headers

Every file needs copyright and license information, following the REUSE specification; reuse lint-file runs as a hook and in CI. When adding a file, copy the header from a neighbouring one, and pick the license by location:

  • Files in hw/, and templates that generate them, use SHL-0.51.
  • Python sources, documentation and CI configuration use Apache-2.0.

Files that cannot carry a comment, such as images and lockfiles, are annotated by path in REUSE.toml instead. Feel free to add yourself to the Author: line of files you make substantial contributions to.

Commit Messages

Use a short area prefix followed by an imperative summary:

floogen: add support for YX routing
hw: use per-channel valid for dec_error assertion in id_translation
docs: describe traffic configuration files

Common prefixes are hw, floogen, docs, ci, sim, synth, chore and treewide. Conventional Commit types (feat:, fix:, chore(deps):) are equally welcome. Pull requests are squash-merged, so the pull request title becomes the commit subject — it is worth getting that one right, and individual commits within a branch matter less.

Changelog

User-visible changes need an entry in CHANGELOG.md, which follows Keep a Changelog. Add it under ## [Unreleased], creating that section if it is not there, and put it under an #### Hardware or #### FlooGen sub-heading so the two halves stay separated:

## [Unreleased]

### Added

#### FlooGen

- Add `--version` flag to the CLI to print the installed _FlooGen_ version

Once your pull request has a number, append its URL to the entry. Purely internal changes — refactors, CI, dependency bumps — do not need an entry.

Opening a Pull Request

Target the main branch and fill in the pull request template. Then watch the checks:

Workflow What it checks
lint Verible over hw/, the prek hooks (ruff, ty, typos, whitespace, YAML/TOML) and REUSE compliance
slang Elaborates all eight generated example networks
floogen pytest under both pip and uv, plus generation on Python 3.10–3.14
gitlab-ci Mirrors to the internal GitLab and runs the RTL simulation regression
docs Builds and deploys the documentation (on main only)

Note that gitlab-ci does not run on pull requests from forks. It needs a secret that forks cannot access, so it is skipped — which means a fork pull request can show all checks green while the RTL simulation regression never ran. This is expected. A maintainer will re-run the regression from a branch in this repository before merging, so please do report which testbenches you ran locally.

Small, focused pull requests get reviewed faster than large ones. If you are planning a larger change — a new topology, a new routing algorithm, a reworked network interface — please open an issue first so we can agree on the approach before you write the code.

Releases

For maintainers: releases are cut from main by bumping the version with uv version, moving the [Unreleased] changelog section under the new version number with today's date, and tagging the release commit as vX.Y.Z. Pushing the tag publishes to PyPI; the release workflow asserts that the tag matches uv version --short, so the bump has to land first.