OpenFibre Conventions¶
OpenFibre follows the coding conventions of Open Logic and the module development process of the architecture document. This page lists the rules and the few OpenFibre-specific additions.
VHDL coding¶
- The Open Logic coding conventions apply in full: port names
<Interface>_<Signal>, generics_g, constants_c, variables_v, types_t, FSM types<Name>Fsm_twith states_s, functions inlowerCamelCase, four spaces of indentation, no tabs, no trailing whitespace. - Entities are named
ofb_<function>(for exampleofb_lane_tx). All OpenFibre sources are compiled into the VHDL libraryopenfibre; Open Logic is compiled into the libraryolo. - Language: VHDL-2008.
- Entities with non-trivial state use the two-process pattern of Open Logic: all registers in one
TwoProcess_rrecord, signalsrandr_next, a combinational process starting withv := r;and ending withr_next <= v;, a sequential process withr <= r_next;and the reset override at its end. - Resets are synchronous and high-active. Only state registers are reset.
olo_ft_cc_resetbrings a reset into each clock domain. - Every data path between blocks is a valid / ready stream (AXI4-Stream handshake semantics).
- Standard functions (FIFOs, RAMs, crossings, CRC, PRBS, arbiters, width converters, pipeline stages) are
instantiated from Open Logic, never rewritten. RAMs and crossings use the fault-tolerant
olo_ft_*entities. - Every line that implements an ECSS requirement is traceable through the module specification; comments name the
clause where it helps the reader (for example
-- ECSS 5.5.2.11e.3). - File header: copyright line and authors, then a 1 to 2 sentence description that links to the module documentation. Never write "all rights reserved".
- Never use em-dashes in code, comments or documentation. Use UTF-8 only.
- VSG 3.27 with the Open Logic configuration in
lint/configmust report no errors and no warnings:vsg -c lint/config/vsg_config.yml -f <file>. Safe automatic fixes:vsg -c lint/config/vsg_config.yml --fix --fix_only lint/config/fix_only_config.yml -f <file>. - The design must be synthesizable in a technology-independent way:
python lint/synth_check.pyelaboratesofb_corefor 1, 2 and 4 lanes with the synthesis of GHDL (afterpython run.py --compile) and fails on errors and inferred latches. Signals with a variable index select a slice with a loop over the constant slices rather than a slice with variable bounds;to_01and other simulation-only functions are not used in RTL. - Traceability: every requirement of a specification is verified by at least one test case of the verification plan,
every ECSS clause of the traceability matrix (architecture section 10) by the test cases of its requirements, and
every test case of a plan is run by a testbench.
python tools/compliance.pywrites the compliance matrix;python tools/compliance.py --checkfails on a gap.
Module development process¶
Every module goes through the seven phases of the architecture document (section 9):
| Phase | Output |
|---|---|
| A Requirements | hdl/<module>/docs/specification.md: requirements with IDs, each tracing to ECSS clauses |
| B Architecture | hdl/<module>/docs/architecture.md: blocks, ports, state machines, data formats |
| C Verification plan | hdl/<module>/docs/verification_plan.md: test cases with IDs, requirement coverage |
| D RTL | hdl/<module>/src/*.vhd |
| E Testbenches | hdl/<module>/tb/<entity>_th.vhd (harness) and <entity>_tb.vhd (VUnit runner) |
| F Verification | Regression green, hdl/<module>/docs/verification_report.md |
| G Integration | Tests at the next level that cross every seam the module touches |
A module is one layer or one group of blocks of the architecture (section 7). Every block keeps its own entity and
its own unit testbench. hdl/<module>/README.md links the four documents and explains how to run the tests.
Verification¶
- VUnit runs every test (
run.py); UVVM supplies VVCs, BFMs, checks, randomisation and functional coverage. - The harness (
_th) contains clocks, reset, the DUT and the VVCs, the testbench (_tb) contains oneif run("<test id>") thenblock per test case of the verification plan. The test IDs of the plan and the names inrun(...)are identical. - A test passes only when UVVM reports no unexpected alerts and every expected alert occurred
(
ofb_tb_pkg.ofbTestEnd). - Tests observe ports and management interfaces only, never internal signals.
- GHDL is the default simulator. Only the tests that instantiate the vendor transceiver model (PA-1 wrapper test and
the end-to-end test of two cores over the transceivers) run in the AMD Vivado simulator
(
tools/run_xsim.py); their testbenches use plain VHDL checks evaluated from the log. The transceiver model (secure IP with a firmware simulation) is not deterministic under heavy CPU load: anofb_pa_gty_tbrun next to six GHDL simulations failed to align two lanes. Runtools/run_xsim.pywithout other simulations. - Negative tests inject the fault from the bench (corrupted word, wrong sequence number, ...) and expect the alert
with
increment_expected_alerts.
Git¶
mainholds the integrated state. Every module or change is developed on a branchfeature/<module>orbugfix/<topic>and merged with--no-ffonce its regression is green.- Commit messages: imperative subject line, body explains what and why.