OpenWire Conventions¶
OpenWire follows the coding conventions of Open Logic and the module development process of the architecture document. This page lists the rules and the few OpenWire-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
owr_<function>(for exampleowr_enc_tx). All OpenWire sources are compiled into the VHDL libraryopenwire; 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_base_reset_genbrings the reset into each clock domain. - 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.5.7.6b). - 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.pyelaboratesowr_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
(
owr_tb_pkg.owrTestEnd). - 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 (for example
txDropof the far-end model). - The far end of a link is the behavioural Data-Strobe model of
tb/(character encoder and decoder in continuous time) or a second port; tests never rely on the receiver of the port under test to check its own transmitter. - Negative tests inject the fault from the bench (parity error, ESC error, disconnect, credit violation, double error
through the
ErrInjports, ...) and expect the alert withincrement_expected_alertsor the status in the MIB.
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.