Registry-wide guards¶
The guards are pytest tests that walk the whole registry rather than one
core. They run with python -m pytest dau_core/tests; none of them needs
Vivado, and only the elaboration guard needs verilator.
Four of them compare an exact set rather than a predicate. Those are
scoped to source_package == "dau_core.hdl" so that an installed
third-party tile does not read as drift in this package’s palette.
test_cores.py¶
Registry shape, declaration completeness, and the resource-pricing contract.
Guard |
Fails on |
|---|---|
|
An |
|
An entry whose |
|
A |
|
A |
|
An operator tile with no reference semantics. |
|
A missing |
|
An operator with no |
|
An operator declaring neither or both of |
|
|
|
A stateful or multi-word tile claiming the generic elastic-depth axis. |
|
The wide combinational tiles silently moving their depth bounds or their per-slot rate. |
|
A dependency closure that emits a package after its consumer, or duplicates a source. |
|
|
|
A synthesizable operator or stream-infra tile with no envelope, an unmeasured estimate, or a zero-LUT point. |
|
Coordinate lookup ignoring a declared parameter default. |
|
One part’s number pricing another part’s build. |
|
A resource record that is not a list of measurement points. |
|
A combinational core’s point recording a timing status it never had, or failing to price a clock. |
|
A timing-failed build being consumed as a smaller budget. |
|
A period derived as |
|
A parallel Python-literal core list reappearing, and the registry-path view drifting from the accessor view. |
|
A default reload clobbering a consumer’s composed overrides. |
|
A core changing its status class (silent mid-chain or a per-batch close-out) without the change being stated. |
|
The known record-width-blind dispatcher rate gap being treated as closed. |
|
Negative resource counts, empty part strings, or non-positive clock periods entering the registry. |
|
A spec that would reject every override, including its own default. |
|
The override rule being re-implemented outside |
|
Storage cost ignoring a parameter override. |
|
An intent scaling by a parameter the core does not declare. |
|
A scale-free intent being mispriced. |
|
Pricing an override that no buildable design could use. |
|
A third-party tile being forced to vendor its SystemVerilog into |
|
An installed third-party tile failing this package’s exact-set guards. |
|
A raw |
|
A resource path that formats correctly and does not exist, discovered at synthesis. |
test_core_contract.py¶
Guard |
Fails on |
|---|---|
|
A |
The check runs through dau_build.sv_contract.validate_stream_tile. In CI a
missing dau_build fails the guard; anywhere else it skips.
test_measured_from_matches_the_hdl.py¶
Guard |
Fails on |
|---|---|
|
An edit to a tile’s source, or to a package it imports or a header it includes, without re-measuring and re-stamping its |
|
A measured core without a |
|
A core whose HDL closure cannot be digested. |
|
A |
test_hdl_elaboration.py¶
Guard |
Fails on |
|---|---|
|
The registry advertising a parameter value the RTL’s own elaboration guard rejects. Parametrized per operator; a lint-only Verilator run over the declared parameter space, capped at 24 combinations per core. |
test_parameter_bounds_match_the_hdl.py¶
Guard |
Fails on |
|---|---|
|
A registry |
|
The unparsed-guard holdout list outliving its holdouts, in either direction. |
|
|
Because the bound is parsed out of the $error string, that string is
machine-readable text, not a comment. The recognized forms are
X must be in [a, b], X must be between a and b,
X must divide N and lie in [a, b], X must be a/b/c, and
X must be a, b, or c.
test_hdl_parameter_bindings_resolve.py¶
Guard |
Fails on |
|---|---|
|
A |
|
The identity wrapper failing to forward a capability parameter, which would advertise it as zero. |
test_capability_contract.py¶
Guard |
Fails on |
|---|---|
|
A tile declaring an opcode it cannot execute, or declaring a host-computed operation as hardware. |
test_public_tile_surface.py¶
Guard |
Fails on |
|---|---|
|
|
|
The declaration surface acquiring a runtime dependency beyond |
|
The declared debt list growing, and separately, going stale. |
Imports are read statically rather than by importing the modules, because an import-time check passes on a dependency reached only inside a function.
test_benches_can_fail.py¶
Guard |
Fails on |
|---|---|
|
A bench that always passes. Each mutation edits a copy of the HDL and asserts the bench fails, and that it failed in the run rather than at compile time. |
test_generated_cores.py¶
Guard |
Fails on |
|---|---|
|
A generated core silently resolving to a stale or absent file. |
|
Rendered output landing somewhere the registry entry does not name. |
|
A checked-in source being overwritten by a render. |
|
A generator’s operating point being fixed in Python rather than composed. |
|
Two operating points collapsing to one source. |
|
An untraceable generated file. |
dau_core/tests/conftest.py renders the generated cores once per session
in an autouse fixture, so registry-walking guards see real files.
See also¶
How to test a core: the order to run these in while developing a tile.
How to add an operator tile: the steps these guards check.
CoreDefinitionfields: the declarations most of these guards read.