Imported from CESNET/ndk-fpga (
AGENTS.md). Install upstream withnpx skills add CESNET/ndk-fpga. Copyright stays with the author.
AGENTS.md
Signpost for AI agents working in this repository. This file does not duplicate documentation — it points to where the real content lives, so check here before searching blind.
What this repository is
NDK-FPGA (CESNET's Network Development Kit for FPGA): a VHDL/SystemVerilog IP library
plus a Tcl/Make build system, used to build FPGA firmware for network acceleration
cards (cards/), assembled from reusable components (comp/) and a shared core
pipeline (core/). The repo also ships a runnable reference design, the "Minimal"
application (apps/minimal).
Verification is a mix of two styles: UVM/SystemVerilog (QuestaSim, comp/**/ver/ and
comp/**/uvm/) and cocotb (Python-driven, comp/**/cocotb/) — both widespread, and
cocotb is what this repo's AI-agent skills currently cover.
Some IP (e.g. DMA Medusa) is closed-source and only available to CESNET and its partners — its
integration points live under extra/.
Build system architecture
Read build/readme.rst for the full picture; the essentials:
Modules.tclfiles (one per component directory) declare that component's structure:MOD(own source files, in dependency order),COMPONENTS(subcomponents, as[ENTITY ENTITY_BASE ARCHGRP]triples),PACKAGES(VHDL packages, compiled first).ARCHGRPlets oneModules.tcldescribe multiple architecture variants (commonlyFULLvsEMPTY).- Every buildable target has a plain
MakefilesettingTOP_LEVEL_ENT(and sometimesTARGET) that includes the sharedbuild/Makefile, which dispatches toMakefile.Vivado.inc/Makefile.Quartus.inc/Makefile.Synplify.inc, or tobuild/cocotb.mkwhenTARGET=cocotb. env.sh(source from repo root) sets up the env vars local Python packages (python/ofm,python/cocotbext) need to resolve for PDM/pip installs. Only source it when creating a virtualenv — not when just running cocotb tests.
Simulating/verifying VHDL — pick the right level first
There are two distinct kinds of cocotb simulation here. They share the same build
machinery but differ significantly in what dut is and how you configure them —
picking the wrong doc/skill for the task wastes time.
-
Single VHDL component (a
comp/**/cocotb/directory — a pipe, FIFO, MFB/MVB/ AXI4-Stream block, etc.):dutin the test is the component under test. No card, noNFBDevice, noCARD/DMA_TYPE/PCIE_CONF.- Read first:
.agents/skills/ndk-cocotb-ver/SKILL.md— structure conventions, generic randomized test pattern, backpressure/rate-limiter helpers, MI/Device Tree integration, reference implementations. - Docs:
doc/source/basic_cocotb_test.rst(getting started),doc/source/cocotbext.rst(driver/monitor/utility library reference).
- Read first:
-
Whole-firmware / top-level simulation (
apps/minimal/tests/cocotb/):dutis the entire card's top-level entity. Tests go throughNFBDeviceand the MI/PCIe/ Ethernet interfaces; the card and DMA engine variant are selected withCARD,DMA_TYPE,PCIE_CONF(not every combination is valid for every card — check the target card'scards/<vendor>/<card>/config/card_conf.tclandapps/minimal/tests/cocotb/top-level-sim.jenkinsfile'sEXTRA_COMBINATIONSfor which combinations actually exist and are CI-covered).- Docs:
doc/source/top_level_simulation.rst.
- Docs:
-
Tips shared by both:
doc/source/cocotb_tips_and_tricks.rst— running a single test fast (COCOTB_TEST_FILTER), debug logging, random seed control, optional MFB/MVB/AXI4-Stream signals, throughput probes.TARGET=cocotb(Questa/vsim) is the default simulator for a plainmakeon both kinds of test; NVC is opt-in viamake TARGET=nvc-sim(ormake nvc-simfor a component), not the default.
-
Bus protocol references:
doc/source/mi.rst,doc/source/mfb.rst,doc/source/mvb.rst,doc/source/axi.rst. -
Alternative to cocotb: some components use UVM/SystemVerilog instead (
comp/**/ver/,comp/**/uvm/;.fdoscripts,tbench/test_pkg.sv,ver_settings.py; run viavsim -do top_level.fdo, orchestrated by Jenkins jobs intests/jenkins/ver_*.jenkins). No agent skill covers this style yet — read the component's existingver/uvmdirectory for conventions before touching it.
Debugging without a waveform GUI
The .rst docs above point at the idiomatic human debugging path (cocotb_test_sig.fdo
- a waveform viewer). You don't have a display, so use that path's agent-side
substitute instead — reading internal hierarchy signals directly for a few clock
cycles and logging them — documented in
.agents/skills/ndk-cocotb-ver/SKILL.md(section "Probing Internal DUT Signals (No Waveform GUI)"), which covers both the component-level and top-level-sim variants.
Before considering a change done
- Changed Python (including cocotb tests)? Run
tests/ci/pycodestyle.sh(flake8 + mypy againstpython/ofm) — CI enforces this. - Changed VHDL? Check it with
vhdl_lsfirst (.agents/skills/vhdl-lint/SKILL.md), then see "Per-component simulation/synthesis check" below for a deeper check. CI also enforces style withvsg(tests/ci/vsg_config.yaml); if unavailable locally, at least match the surrounding file's formatting by hand.- If the component has a
cocotb/directory, run the cocotb test. Ask the user whether they want a default run (makein thecocotb/dir) or a full multi-ver run (all combinations fromver_settings.py). See the "Running Multiple Generic Combinations" section in.agents/skills/ndk-cocotb-ver/SKILL.md.
- If the component has a
- Changed Verilog/SystemVerilog?
python3 tests/verible/verible_runner.py(rules/ exclusions intests/verible/). - Commit messages follow Conventional Commits (
type(scope): summary, e.g.fix(pcie-pkt_reader): ...), enforced by commitlint; scope is usually the component/module name. User-facing changes also belong inCHANGELOG.mdunder[Unreleased], grouped by area (build:,ci:,cocotb:,comp:, ...) — match existing entries' phrasing.
Building/synthesizing firmware
- Card firmware:
apps/<app>/build/<card>/Makefile, e.g.make -C apps/minimal/build/n6010. Requires Quartus Prime Pro or Vivado (per card) with a valid license. - Per-component simulation/synthesis check: any component with a
synth/Makefilecan be built standalone —make -C comp/<path>/synth SYNTH=vivado(orSYNTH=quartus), ormake -C comp/<path>/synth TARGET=nvcfor a syntax/elaboration check via the open-source NVC simulator without needing a vendor license. Run.agents/skills/vhdl-lint/SKILL.md'svhdl_lscheck first — it's much faster and catches most of the same name/type errors. - Published documentation (built from
doc/source/with Sphinx +sphinx-vhdl, which also picks up doc-comments directly above VHDLentity/generic/portdeclarations and each component'sreadme.rst): https://cesnet.github.io/ndk-fpga/devel/. Build locally withcd doc && make html(needsdoc/requirements.txtinstalled in a venv).
Directory map (non-obvious parts only)
comp/— reusable IP, organized by bus/domain (mi_tools,mfb_tools,mvb_tools,axis_tools,dma,pcie,nic,tsu,ctrls,base, ...). Each leaf component typically has its ownModules.tcl,readme.rst, andsynth//cocotb//ver/subfolders.core/— the shared core pipeline (network/PCIe/DMA glue, MI address space, device tree) instantiated by every application.apps/minimal/— the reference application; also home of the top-level cocotb simulation and per-card firmware buildMakefiles.cards/<vendor>/<card>/— card-specific constraints, IP, and build glue.python/ofm— core Python utilities (used by both CI lint and cocotb runs).python/cocotbext—cocotbext-ofm, this repo's cocotb extensions (drivers/monitors/transactions per bus).