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
.ymlthat reproduces the problem, the output offloogen --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:
pip works too, if you prefer it:
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:
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:
--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:
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 fromutil/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 withuv 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:
Documentation Changes¶
The documentation is built with Zensical from docs/. Preview it
locally with:
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, useSHL-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-cidoes 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.