OpenRMAP Conventions¶
OpenRMAP follows the coding conventions of Open Logic and the module development process of the architecture document. This page lists the rules and the few OpenRMAP-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
omap_<function>(for exampleomap_target_rx). All OpenRMAP sources are compiled into the VHDL libraryopenrmap; 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. The core has one clock domain
Clk. - Every data path between blocks is a valid / ready stream (AXI4-Stream handshake semantics) or a valid-only stream of one-cycle events where the receiver is never slower than the source.
- Standard functions (FIFOs, RAMs, crossings, synchronisers, arbiters, pipeline stages) are instantiated from Open
Logic, never rewritten. FIFOs and crossings use the fault-tolerant
olo_ft_*entities. - State machines have a
when othersbranch that returns to a defined recovery state; the reset leads to that state from any state. - 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.3.3.6.3a). - 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.pyelaboratesomap_corewith the synthesis of GHDL (afterpython run.py --compile) and fails on errors and inferred latches.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
(
omap_tb_pkg.omapTestEnd). - Tests observe ports and management interfaces only, never internal signals.
- GHDL is the default simulator; QuestaSim (
python run.py --questa) is used for code coverage (coverage.md). Every test passes in both simulators. - A side effect is never obtained by calling an impure function and discarding its result: QuestaSim may remove such a call. Protected types offer a procedure for it.
- Packets are built and checked by the RMAP model of
tb/(own implementation of the packet formats and of the CRC with the table method of ECSS Annex A.3); tests never use the RTL of the core to build or check packets. - Target memory is the AXI memory model of
tb/; written data is checked through its backdoor. - Negative tests inject the fault from the bench (corrupted CRC, early EOP, EEP, excess data, wrong key, error
response of the memory, double error through the
ErrInjports, ...) and expect the status in the reply, the confirmation or the counters of the register file.
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.