mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: implement DMA IRQ handling and WS2812 completion race tests
This commit is contained in:
5 files changed
+503
-14
No files matched your search
+18
-2
@@ -5,16 +5,25 @@
|
||||
|
||||
static const rs_dma_session_t *rs_dma_owners[RS_DMA_CHANNEL_COUNT];
|
||||
|
||||
#ifdef RS_DMA_TEST_MMIO
|
||||
uint32_t rs_dma_test_irq_save(void);
|
||||
void rs_dma_test_irq_restore(uint32_t saved);
|
||||
#endif
|
||||
|
||||
static uint32_t rs_dma_lock(void) {
|
||||
uint32_t saved = 0U;
|
||||
#if defined(__riscv) && defined(CSR_ENABLE)
|
||||
#ifdef RS_DMA_TEST_MMIO
|
||||
saved = rs_dma_test_irq_save();
|
||||
#elif defined(__riscv) && defined(CSR_ENABLE)
|
||||
__asm__ volatile("csrrci %0, mstatus, 8" : "=r"(saved)::"memory");
|
||||
#endif
|
||||
return saved;
|
||||
}
|
||||
|
||||
static void rs_dma_unlock(uint32_t saved) {
|
||||
#if defined(__riscv) && defined(CSR_ENABLE)
|
||||
#ifdef RS_DMA_TEST_MMIO
|
||||
rs_dma_test_irq_restore(saved);
|
||||
#elif defined(__riscv) && defined(CSR_ENABLE)
|
||||
if ((saved & UINT32_C(8)) != 0U) {
|
||||
__asm__ volatile("csrsi mstatus, 8" ::: "memory");
|
||||
}
|
||||
@@ -185,6 +194,7 @@ rs_status_t rs_dma_submit_tcd_chain(uint32_t channel, rs_dma_tcd_t *first, uint3
|
||||
rs_status_t result;
|
||||
uint32_t control;
|
||||
uint32_t burst;
|
||||
uint32_t saved;
|
||||
|
||||
result = rs_dma_tcd_validate(channel, current);
|
||||
if (result != RS_OK) {
|
||||
@@ -208,14 +218,20 @@ rs_status_t rs_dma_submit_tcd_chain(uint32_t channel, rs_dma_tcd_t *first, uint3
|
||||
config.crc_expected = current->crc_expected;
|
||||
config.priority = (uint8_t)((control >> RS_DMA_TCD_PRIORITY_SHIFT) & UINT32_C(0x3));
|
||||
config.burst_beats = (uint8_t)burst;
|
||||
/* Publish configuration, TCD and START before an ISR can lease the
|
||||
* idle channel. Nested helpers preserve this outer interrupt mask.
|
||||
* Restore interrupts before the bounded completion wait. */
|
||||
saved = rs_dma_lock();
|
||||
result = rs_dma_configure(channel, &config);
|
||||
if (result != RS_OK) {
|
||||
rs_dma_unlock(saved);
|
||||
return result;
|
||||
}
|
||||
RS_DMA_CH_REG(channel, RS_DMA_CH_REG_TCD_HEAD) = (uint32_t)(uintptr_t)current;
|
||||
RS_DMA_CH_REG(channel, RS_DMA_CH_REG_TCD_COUNT) = UINT32_C(1);
|
||||
rs_dma_fence();
|
||||
result = rs_dma_start(channel);
|
||||
rs_dma_unlock(saved);
|
||||
if (result != RS_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -419,7 +419,11 @@ rs_status_t rs_ws2812_dma_service(uint64_t now) {
|
||||
return rs_ws2812_dma_finish();
|
||||
}
|
||||
if ((transmitter_flags & RS_WS2812_STATUS_BUSY) == 0U) {
|
||||
return rs_ws2812_dma_fail(RS_EIO);
|
||||
/* Completion may occur between the interrupt and status reads, and
|
||||
* sticky DONE can lag the core's idle transition. Observe terminal
|
||||
* events on the next bounded service call; never refill an idle core.
|
||||
* Errors, aborts and the deadline remain checked on every call. */
|
||||
return RS_OK;
|
||||
}
|
||||
if (rs_ws2812_transfer.remaining == 0U) {
|
||||
rs_ws2812_write_register(RS_WS2812_INTR_STATE_OFFSET, RS_WS2812_INTR_FIFO_LOW);
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
This record covers the two P1 findings approved for follow-up on
|
||||
`bab01352f8f7c80e39546b04e3ed37a3d927f475` plus the existing P3 worktree.
|
||||
It does not approve Mini fabric enablement or advance TINY-R2-P4.
|
||||
Earlier sections retain their original development status and attribution;
|
||||
the source-bound campaign below records completed validation on `3e46cc8`.
|
||||
The final section separately records the subsequent two HAL race fixes.
|
||||
|
||||
## Retained Tiny Icarus finding: closed
|
||||
|
||||
@@ -182,6 +185,10 @@ STA observations qualify a new physical operating point.
|
||||
|
||||
## Compiler-matrix execution corrections (2026-10-09)
|
||||
|
||||
The intermediate snapshots below are historical. The final source-bound results
|
||||
later in this record supersede their in-progress status without relabeling any
|
||||
failed attempt or earlier artifact.
|
||||
|
||||
The initial flat-image collector could not read `_stack_point` from its symbol
|
||||
listing. Flat placement now falls back to the retained linker map's explicit
|
||||
`PROVIDE (_stack_point = .)` value; the exact SRAM endpoint and 4 KiB stack
|
||||
@@ -286,3 +293,280 @@ the selected target's successful simulation checks. This behavioral-only run
|
||||
provides no Mini synthesis, netlist, STA or physical evidence. Mini lint baseline
|
||||
differences remain non-blocking observations, separately retained in the
|
||||
`56f28cd9230c` variant's `meta/rtl-lint-warnings.json`.
|
||||
|
||||
## Final source-bound P3 matrix (2026-10-10)
|
||||
|
||||
After the external style commit and the publication/configuration corrections
|
||||
settled, the final campaign was run against commit
|
||||
`3e46cc80e2d2243233d284b7cd9583714b0773bb`, source digest
|
||||
`a7fc5112cd6f20df956243c4d081a6a31ede6192cd270e3c13340557b0e58776`.
|
||||
Its master record is
|
||||
`build/ics55-tiny-performance-2026-10-09-17-10-53cc6674d532/meta/tiny-r2-p3/matrix/attempt-3jy5g5vo/record.json`;
|
||||
the final report is in the same root at `meta/tiny-r2-p3/report.json`.
|
||||
|
||||
All eight cases pass image collection, normal Tiny acceptance and three cold
|
||||
Verilator runs. The selected native Icarus cases also pass three cold runs:
|
||||
|
||||
- `compat-os-flat`: 7464.762, 7891.159 and 7428.430 seconds;
|
||||
- `perf-o2-lto-flat`: 5841.742, 5890.497 and 6149.375 seconds;
|
||||
- `perf-o2-plain-banked`: 5951.447, 6345.716 and 5964.039 seconds.
|
||||
|
||||
The collector validates Tiny `TEST_STATUS`/`SIM_TEST_PASS`, forbidden markers,
|
||||
matched retained image/model/tool artifacts, source digests, three repetitions,
|
||||
and cross-simulator sample identity. `report.json` remains
|
||||
`measurement_complete`; the ledger's human phase gate is still required.
|
||||
|
||||
The earlier 09-25, 15-10 and 16-45 campaigns remain historical: source changes
|
||||
during execution included the `352b200` style commit, the configuration/publication
|
||||
repairs, and the performance profile's trailing-newline change. Their raw passing
|
||||
samples and provenance failures are retained and are not relabeled as final
|
||||
evidence. The final campaign uses the complete committed corrections in `3e46cc8`.
|
||||
|
||||
### Current validation and commands
|
||||
|
||||
The tested primary platform is TINY/ICS55, external SAFE24 with HAVE_PLL=YES
|
||||
but the PLL parked off. CPU and the existing 128 KiB main SRAM remain at SYS24.
|
||||
The IHP130 compatibility profile keeps no PLL. Dependencies, warning baselines,
|
||||
metrics policy, hardware integration and the frozen specification blob
|
||||
`7e19de49d49efaafacccfa85671e314d53dd15a4` are unchanged by this validation.
|
||||
|
||||
After activating `.cache/retrosoc/development/tiny-r2-p1/activate.sh`, the matrix
|
||||
and final report commands were:
|
||||
|
||||
```sh
|
||||
make CONFIG=configs/benchmark/ics55-tiny-performance.mk SOC=TINY PDK=ICS55 \
|
||||
BUILD_TIMESTAMP=2026-10-09-17-10 SOC_SIM_TIME=21600 JOBS=3 \
|
||||
TINY_P3_RESUME=NO tiny-r2-p3-matrix
|
||||
make CONFIG=configs/benchmark/ics55-tiny-performance.mk SOC=TINY PDK=ICS55 \
|
||||
BUILD_TIMESTAMP=2026-10-09-17-10 tiny-r2-p3-report
|
||||
```
|
||||
|
||||
The current full Pytest run reports **1629 passed, 1 skipped** in 4200.10 seconds.
|
||||
The one skipped PDF inspection test requires `pypdf`, absent from this environment;
|
||||
it is not a hardware or simulation pass. Its command, complete log and result are
|
||||
in the matrix root under `meta/tiny-r2-p3/quality/pytest.{log,json}`. The previous
|
||||
4 failures and 94 fixture errors remain in their old logs; they are resolved by
|
||||
the configuration declaration and publication/source-fixture corrections in
|
||||
`3e46cc8`. The focused correction check also passed 149 tests with the same one
|
||||
PDF skip. No PDF or publication source revision was advanced by these checks.
|
||||
|
||||
`ruff check .`, dependency-lock validation and `git diff --check` pass. The
|
||||
current C format/policy/host and RTL format/style/readiness checks pass; their
|
||||
exact Make command and outputs are retained under
|
||||
`meta/tiny-r2-p3/quality/policy.{log,json}`. These are the repository's mechanical
|
||||
quality checks, not complete MISRA certification; no new deviation is recorded.
|
||||
|
||||
Regression dry-runs selected TINY explicitly for both PDKs and MINI with
|
||||
`--behavioral-only`. Tiny nightly resolves to the same commands as PR, so it was
|
||||
not executed a second time. The final executions were:
|
||||
|
||||
```sh
|
||||
BUILD_TIMESTAMP=2026-10-09-19-55 python3 scripts/regress.py --root . --suite pr --soc TINY --pdk ICS55
|
||||
BUILD_TIMESTAMP=2026-10-09-19-56 python3 scripts/regress.py --root . --suite pr --soc TINY --pdk IHP130
|
||||
JAVA_TOOL_OPTIONS=-Dsbt.server.forcestart=true BUILD_TIMESTAMP=2026-10-09-19-57 \
|
||||
python3 scripts/regress.py --root . --suite pr --soc MINI --pdk ICS55 --behavioral-only
|
||||
```
|
||||
|
||||
All three exit zero. Current evidence roots and results are:
|
||||
|
||||
| Scope | Evidence root below `build/` | Result |
|
||||
| --- | --- | --- |
|
||||
| Tiny ICS55 PR | `ics55-tiny-2026-10-09-19-55-42d5beccb726/` | `meta/tiny-r2-p3/regress-ics55.{log,json}`; behavioral/JTAG, netlist boot, synthesis and STA commands pass |
|
||||
| Tiny IHP130 PR | `ihp130-tiny-2026-10-09-19-56-bff91e3529ba/` | `meta/tiny-r2-p3/regress-ihp130.{log,json}`; same target-specific gates pass |
|
||||
| Mini ICS55 behavioral-only | `ics55-2026-10-09-19-57-d1cacf6d3b62/` | `meta/tiny-r2-p3/regress-mini.{log,json}`; SDRAM Verilator and Icarus assembly boot pass |
|
||||
|
||||
Each Tiny PR's HAVE_SVA=YES Verilator acceptance has its separate configuration
|
||||
variant, identified in the retained command/log. Mini's SDRAM run uses
|
||||
`dc24d22ad53d` and assembly boot uses `ec9e1f2e9c2c` at the same 19-57 timestamp.
|
||||
Mini behavioral-only supplies no synthesis, netlist, STA or physical evidence.
|
||||
|
||||
The additional IHP130 performance/banked normal-firmware check also passes:
|
||||
|
||||
```sh
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk SOC=TINY PDK=IHP130 \
|
||||
BUILD_TIMESTAMP=2026-10-10-00-13 SW_ISA_PROFILE=TINY_PERF SW_OPT=O2 SW_LTO=NO \
|
||||
LINK_TYPE=ld2_tiny_banked SIMU=VERILATOR firmware sim
|
||||
```
|
||||
|
||||
Its root is `build/ihp130-tiny-2026-10-10-00-13-8648aa4845d9/`, with the exact
|
||||
command/result at `meta/tiny-r2-p3/performance-banked.{log,json}` and strict Tiny
|
||||
simulation check at `sim/verilator/result-sim-check.json`. This is normal
|
||||
firmware compatibility; it is not an additional IHP130 compiler measurement matrix.
|
||||
|
||||
The ICS55 platform auditor captured inputs before this execution and successfully
|
||||
produced `meta/tiny-ics55-p1/report.json` in the actual APP=ci_smoke variant. This
|
||||
reuses the platform audit under P3; its original phase label is unchanged. Metrics
|
||||
were explicitly collected in each actual synthesis/STA variant rather than the
|
||||
regression runner's final default-bringup observation directory:
|
||||
|
||||
| TINY PDK | Cells | Reported library area | Max WNS (ns) | Max TNS (ns) |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| ICS55 | 197677 | 1786686.260799 | -41.14 | -508669.53 |
|
||||
| IHP130 | 208547 | 9109320.296998 | -94.28 | -1594880.00 |
|
||||
|
||||
Both min WNS/TNS values are zero in these smoke reports. Full reports are at
|
||||
`sta/opensta/timing_metrics.rpt` and `meta/metrics.json` within the corresponding
|
||||
APP=ci_smoke roots. Library area is not placed/routed die area; negative margins
|
||||
remain unclosed. No 96/192/240 MHz operation, routed/PVT signoff or physical
|
||||
qualification is claimed, and no half-rate main-SRAM fallback is introduced.
|
||||
|
||||
Lint comparisons remain non-blocking observations: ICS55 Tiny has 459 new
|
||||
signatures relative to its baseline, IHP130 Tiny 403, and Mini ICS55 1536 new /
|
||||
118 resolved; all three have zero increased signatures. Counts are not attribution
|
||||
of every warning to P3. The reports are in each timestamp's lint variant
|
||||
(`303f95040df3`, `2dc2e5c747e5`, and `56f28cd9230c` respectively), under
|
||||
`meta/rtl-lint-warnings.json`. Baselines were not edited.
|
||||
|
||||
### Software measurements and remaining boundaries
|
||||
|
||||
Each row below uses the retained P3 workload (1024 words, four jobs, 4096 CPU
|
||||
iterations, seed `0x12345678`). Cycle counts are raw measured windows; the report
|
||||
also retains the separate empty-window calibration, retired instructions, bus
|
||||
observations and CPI. These are different compiler/layout binaries, not a
|
||||
matched-binary architectural speedup claim.
|
||||
|
||||
| Case | BIN bytes | CPU cycles | Copy cycles | Burst-16 DMA cycles | Chunk-256 cycles | Observed stack bytes |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| compat-os-flat | 11132 | 98682 | 164096 | 18881 | 511389 | 692 |
|
||||
| perf-o2-plain-flat | 10148 | 73951 | 127157 | 16520 | 373812 | 648 |
|
||||
| perf-o2-lto-flat | 8592 | 73974 | 127180 | 13980 | 339167 | 552 |
|
||||
| perf-o3-plain-flat | 10404 | 73951 | 127157 | 16058 | 372690 | 628 |
|
||||
| perf-o3-lto-flat | 9872 | 73974 | 127180 | 13980 | 339167 | 564 |
|
||||
| perf-os-plain-flat | 8000 | 74064 | 139487 | 18421 | 394248 | 692 |
|
||||
| perf-os-lto-flat | 6360 | 74064 | 139484 | 14169 | 343769 | 584 |
|
||||
| perf-o2-plain-banked | 10184 | 73954 | 114875 | 16523 | 374016 | 648 |
|
||||
|
||||
Compare compatible Os with performance Os to hold optimization/layout fixed;
|
||||
compare performance O2 with/without LTO to isolate that selection; compare the
|
||||
two O2/no-LTO rows for placement. BIN bytes exclude BSS, and observed stack use
|
||||
does not prove a static upper bound. Each image reserves at least 4096 stack
|
||||
bytes. Bank conflicts remain unavailable because P4 hardware is not implemented.
|
||||
The original P1 binaries and their historical phase/source identities are retained.
|
||||
|
||||
Current Mini PIO compatibility is additionally retained at
|
||||
`build/ics55-2026-10-09-20-00-d0c568d0142e/meta/tiny-r2-p3/pio-retry/evidence.json`.
|
||||
The initial default 180-second attempt emits SIM_TEST_TIMEOUT despite emulator
|
||||
exit zero, and fails the simulation checker. A retry of the identical model and
|
||||
BIN with `--fast-flash -t 1800` passes in 323.930 seconds, including 4/16/33/65-word
|
||||
frames, IRQ count 5, exact waveform/reset-low checks, underflow/abort recovery,
|
||||
and observer totals `frames=6 completed=4 underflows=1 aborts=2 dma_starts=0`.
|
||||
The evidence records the before/after model and BIN hashes, command, manifest,
|
||||
compile/run logs and a post-build recheck of 487 compiled input sizes/mtimes.
|
||||
It is explicitly a post-build audit; neither the failed timeout nor the original
|
||||
unsupported Mini DMA attempt is relabeled as a passing run.
|
||||
|
||||
Product-integrated WS2812 DMA/IRQ service budgets remain deferred under approved
|
||||
option A to an actual supported route, including Tiny R2-P6. Full-product,
|
||||
physical, silicon and publication-PDF qualification remain outside these results.
|
||||
Human review and acceptance of TINY-R2-P3 are required before authorizing any
|
||||
R2-P4 implementation; this execution does not automatically advance a phase.
|
||||
|
||||
## Subsequent P1 HAL race fixes (2026-10-10)
|
||||
|
||||
This approved follow-up starts from `3e46cc80e2d2243233d284b7cd9583714b0773bb`
|
||||
and preserves the preceding uncommitted documentation/evidence updates. The
|
||||
specification remains blob `7e19de49d49efaafacccfa85671e314d53dd15a4`.
|
||||
Only `crt/src/hal/dma.c`, `crt/src/hal/ws2812.c` and
|
||||
`tests/c/test_runtime.c` change executable/test source. No public interface,
|
||||
register, RTL, profile, dependency, warning baseline or metric policy changes.
|
||||
|
||||
- WS2812: completing between INTR_STATE and STATUS reads no longer produces a
|
||||
false I/O error. Idle without an observed sticky DONE retains ownership and
|
||||
returns to the caller; the next bounded service checks error, abort, deadline
|
||||
and completion again. No refill is admitted to an idle core. DMA response
|
||||
draining and source-buffer lifetime rules are unchanged.
|
||||
- DMA: one outer interrupt save/restore spans legacy TCD configuration,
|
||||
descriptor publication and START, including ownership rejection. Nested HAL
|
||||
helpers preserve the saved mask; the blocking completion wait is outside this
|
||||
critical section. Test-only IRQ hooks model a pending ISR at mask restoration
|
||||
and do not appear in target builds.
|
||||
- Deterministic production-HAL host tests cover an ISR trying to lease the
|
||||
channel during TCD publication, rejection without modifying an existing lease,
|
||||
an initially masked caller, completion between WS2812 register reads, delayed
|
||||
sticky DONE, genuine error/abort and expiry while idle. Existing final-B drain,
|
||||
timeout ownership and 16-word FIFO admission tests remain enabled.
|
||||
|
||||
New evidence is rooted at
|
||||
`build/ics55-tiny-2026-10-10-09-00-b4aa59f3e5d9/meta/tiny-r2-p3-races/`.
|
||||
The timestamp is a fixed build label; each structured result records actual UTC
|
||||
start/end times. `source.json` records the base revision, dirty state, locked
|
||||
tool identities, input hashes, source archive and worktree patch. Its combined
|
||||
ICS55/IHP130 source/test/spec digest is
|
||||
`dfa171fc1adbdfc5c7c9d31ef4ac7ba1a66710caac0fb13b869ddac89186b2f7`.
|
||||
This digest's input set differs from the earlier compiler-matrix input set.
|
||||
|
||||
Before fixes, `host-red.{log,json}` records host test exit 10 (TCD race).
|
||||
After the TCD fix alone, `host-ws-red.{log,json}` records exit 11 (WS2812 race).
|
||||
Both fail the enclosing Make command. `host-green.{log,json}` passes after both
|
||||
fixes; `policy.{log,json}` additionally covers the final error/abort/deadline and
|
||||
interrupt-mask cases, C formatting and policy checks. `focused.{log,json}` has
|
||||
156 passing tests, including P3, Tiny baseline, DMA/register parity, WS2812 RTL
|
||||
and publication API behavior. No new MISRA deviation is introduced. These are
|
||||
partial project checks, not complete MISRA certification.
|
||||
|
||||
Commands run with the existing locked environment:
|
||||
|
||||
```sh
|
||||
source .cache/retrosoc/development/tiny-r2-p1/activate.sh
|
||||
make sw-format-check sw-policy-check sw-host-test
|
||||
python3 -m pytest -q tests/test_tiny_r2_p3.py tests/test_tiny.py \
|
||||
tests/test_tiny_r2_baseline.py tests/test_dma.py \
|
||||
tests/test_dma_register_parity.py tests/test_ws2812.py \
|
||||
tests/test_publication_api_bundle.py
|
||||
ruff check .
|
||||
git diff --check
|
||||
python3 scripts/regress.py --root . --suite pr --soc TINY --pdk ICS55 --dry-run
|
||||
python3 scripts/regress.py --root . --suite nightly --soc TINY --pdk ICS55 --dry-run
|
||||
python3 scripts/regress.py --root . --suite pr --soc TINY --pdk IHP130 --dry-run
|
||||
python3 scripts/regress.py --root . --suite pr --soc MINI --pdk ICS55 --behavioral-only --dry-run
|
||||
BUILD_TIMESTAMP=2026-10-10-09-00 JOBS=3 JAVA_TOOL_OPTIONS=-Dsbt.server.forcestart=true \
|
||||
python3 scripts/regress.py --root . --suite pr --soc TINY --pdk ICS55
|
||||
BUILD_TIMESTAMP=2026-10-10-09-00 JOBS=3 JAVA_TOOL_OPTIONS=-Dsbt.server.forcestart=true \
|
||||
python3 scripts/regress.py --root . --suite pr --soc TINY --pdk IHP130
|
||||
BUILD_TIMESTAMP=2026-10-10-09-00 JOBS=3 JAVA_TOOL_OPTIONS=-Dsbt.server.forcestart=true \
|
||||
python3 scripts/regress.py --root . --suite pr --soc MINI --pdk ICS55 --behavioral-only
|
||||
JAVA_TOOL_OPTIONS=-Dsbt.server.forcestart=true make CONFIG=configs/ci/ics55.mk \
|
||||
SOC=MINI PDK=ICS55 APP=ci_smoke WS2812_P3_ACCEPTANCE=YES HAVE_CSR=YES \
|
||||
LINK_TYPE=ld2_all_sram SIMU=VERILATOR VERILATOR_SIM_ARGS=--fast-flash \
|
||||
SOC_SIM_TIME=3600 BUILD_TIMESTAMP=2026-10-10-09-00 JOBS=3 firmware sim
|
||||
```
|
||||
|
||||
Regression dry-runs passed; Tiny PR and nightly select identical commands, so
|
||||
the long run is not duplicated. All three regression executions passed once;
|
||||
their exact commands and verdicts are retained as
|
||||
`regress-{tiny-ics55,tiny-ihp130,mini-ics55}.{log,json}` in the new evidence root.
|
||||
Durations are 3210.491 seconds (Tiny ICS55), 2205.505 seconds (Tiny IHP130),
|
||||
and 3170.591 seconds (Mini ICS55 behavioral-only). Mini PIO passes once in
|
||||
423.766 seconds including build, with 4/16/33/65-word frames, five IRQs and
|
||||
observer totals `frames=6 completed=4 underflows=1 aborts=2 dma_starts=0`.
|
||||
Its variant is `build/ics55-2026-10-10-09-00-d0c568d0142e/`.
|
||||
|
||||
`audit.py` and `evidence.json` retain the final artifact audit: all 1287 captured
|
||||
source/test/spec inputs are unchanged, 487 Mini PIO compiled inputs retain their
|
||||
recorded sizes/mtimes, and the firmware/model/log/result hashes are recorded.
|
||||
The Mini model audit is explicitly post-build. Eight ordinary regression
|
||||
simulations are independently checked against their executable success marker,
|
||||
command exit and forbidden-error rules. All selected targets, including the
|
||||
current Mini assembly fixture, require `SIM_TEST_PASS`; UART output is not used
|
||||
to infer success. This evidence is in addition to the separate PIO audit.
|
||||
|
||||
Current Tiny synthesis/netlist/STA results are in
|
||||
`build/ics55-tiny-2026-10-10-09-00-42d5beccb726/` and
|
||||
`build/ihp130-tiny-2026-10-10-09-00-bff91e3529ba/`. Both netlist checks pass;
|
||||
STA command success does not mean timing closure. Observed max WNS/TNS remain
|
||||
-41.14 ns / -508669.53 ns (ICS55) and -94.28 ns / -1594880.00 ns (IHP130),
|
||||
with min WNS/TNS zero. Raw reports are `sta/opensta/timing_metrics.rpt`.
|
||||
Lint baseline comparisons still fail as non-blocking regression observations:
|
||||
459 new signatures for ICS55 Tiny, 403 for IHP130 Tiny, and 1536 new / 118
|
||||
resolved for Mini, with zero increased signatures. No baseline was changed.
|
||||
Build logs also retain a roughly four-second generated-file clock-skew warning;
|
||||
these were fresh variant builds, and the input audit passed.
|
||||
|
||||
The old compiler/layout matrix, full Pytest and earlier timing observations stay
|
||||
bound to `3e46cc8`; they are not reattributed to this follow-up. The compiler
|
||||
matrix and full Pytest are not rerun for these isolated C changes (no build or
|
||||
Python implementation changes). Product-integrated WS2812 DMA/IRQ budgets remain
|
||||
deferred under option A; no Mini DMA-to-MMIO route is added. Human P3 acceptance
|
||||
and separate approval are still required before R2-P4. Per the maintainer's
|
||||
instruction, long checks default to a single execution; additional repetitions
|
||||
need a concrete failure/inconsistency or an explicit frozen acceptance rule.
|
||||
@@ -1,14 +1,58 @@
|
||||
# Tiny MCU Verification Record
|
||||
|
||||
## TINY-R2-P3 implementation in progress (2026-10-08–09)
|
||||
## TINY-R2-P3 implementation in progress (2026-10-08–10)
|
||||
|
||||
The retained source-bound compiler/layout matrix is complete for commit
|
||||
`3e46cc80e2d2243233d284b7cd9583714b0773bb`, source digest
|
||||
`a7fc5112cd6f20df956243c4d081a6a31ede6192cd270e3c13340557b0e58776`.
|
||||
All eight configurations pass ordinary Tiny acceptance and three deterministic
|
||||
Verilator cold starts. `compat-os-flat`, `perf-o2-lto-flat` and
|
||||
`perf-o2-plain-banked` also pass three native Icarus cold starts, with exact
|
||||
cross-simulator sample identity. The structured measurement report is
|
||||
`build/ics55-tiny-performance-2026-10-09-17-10-53cc6674d532/meta/tiny-r2-p3/report.json`.
|
||||
It records software measurements only; it does not close phase acceptance,
|
||||
physical timing, hardware bank conflict or Mini integrated-DMA gates.
|
||||
|
||||
Quality evidence for that committed source is complete: full Pytest reports 1629 passed and
|
||||
one environment skip for missing `pypdf`; focused P3 tests and the embedded/RTL
|
||||
quality checks pass. Its Tiny PR regressions pass for ICS55 and IHP130, and
|
||||
Mini ICS55 behavioral-only compatibility passes. Negative STA margins and
|
||||
non-blocking lint observations remain recorded as observations.
|
||||
|
||||
Exact commands, measurements, current evidence roots and remaining qualification
|
||||
limits are in the final section of the [P3 review-fix record](tiny-soc-r2-p3-review-fixes.md).
|
||||
Human review and acceptance remain required before any R2-P4 work.
|
||||
|
||||
### Subsequent P1 race-fix follow-up
|
||||
|
||||
The approved follow-up fixes WS2812 completion between register reads and
|
||||
legacy TCD publication across an ISR lease acquisition. Current source is
|
||||
`3e46cc8` plus the two HAL fixes and deterministic host tests; the matrix above
|
||||
remains evidence for the original commit. New evidence is under
|
||||
`build/ics55-tiny-2026-10-10-09-00-b4aa59f3e5d9/meta/tiny-r2-p3-races/`.
|
||||
The two new tests fail before their respective fixes and pass afterward;
|
||||
C format/policy/host checks and 156 focused tests pass. Mini PIO compatibility
|
||||
also passes once with strict SIM_TEST_PASS and no forbidden markers. Tiny
|
||||
ICS55/IHP130 PR and Mini ICS55 behavioral regressions each pass once. Final
|
||||
`evidence.json` checks all 1287 source inputs, 487 Mini PIO compiled inputs and
|
||||
all eight ordinary regression simulations. Lint baseline differences and
|
||||
negative STA remain observations; no timing closure is claimed. See the final
|
||||
review-fix section for commands, hashes, exact paths and unrun gates.
|
||||
|
||||
Per the maintainer's follow-up instruction, long checks default to one execution;
|
||||
repeat only for a concrete failure/inconsistency or an explicit acceptance
|
||||
requirement. This follow-up does not repeat the three-cold-start compiler matrix.
|
||||
It does not waive any frozen qualification requirement or reattribute old runs.
|
||||
|
||||
### Historical development snapshot
|
||||
|
||||
The 2026-10-09 execution snapshot in the [P3 review-fix record](tiny-soc-r2-p3-review-fixes.md)
|
||||
records all eight ordinary Tiny/Verilator compiler experiments completed, with
|
||||
selected Icarus groups still running. The current-source full Pytest result is
|
||||
selected Icarus groups still running at that snapshot. The then-current full Pytest result was
|
||||
1531 passed, 4 failed, 94 fixture errors and 1 skipped; configuration-declaration
|
||||
and publication source/fixture drift remain open. IHP130 Tiny PR completes with
|
||||
and publication source/fixture drift were still open. IHP130 Tiny PR completed with
|
||||
non-blocking lint observations and negative STA margin. These results do not
|
||||
close the remaining matrix, quality or human phase-acceptance gates.
|
||||
replace the final results above or imply human phase acceptance.
|
||||
|
||||
The [P3 review-fix record](tiny-soc-r2-p3-review-fixes.md) closes the retained
|
||||
banked O2 Icarus finding: all three runs completed successfully and match the
|
||||
@@ -28,8 +72,8 @@ is bound at
|
||||
underflow/abort recovery, zero DMA starts and strict TEST_STATUS/SIM_TEST_PASS.
|
||||
Focused checks report 96 passed; C/RTL quality, Ruff and diff checks pass.
|
||||
The old Mini DMA failure remains failed/unsupported evidence, not a PIO pass.
|
||||
The full compiler/placement matrix, broader current-source regressions and human
|
||||
phase acceptance remain pending. See the review-fix record for exact commands,
|
||||
The full compiler/placement matrix and broader regressions were pending in this
|
||||
initial record; human phase acceptance remains pending. See the review-fix record for exact commands,
|
||||
artifacts, historical attribution and unrun gates.
|
||||
|
||||
The user explicitly approved the P3 preflight and implementation on source
|
||||
@@ -42,9 +86,9 @@ Original phase IDs, historical evidence and qualification limits are retained.
|
||||
|
||||
The [P3 runbook](tiny-soc-r2-software-scheduling.md) defines compiler/layout
|
||||
experiments, shared finite DMA/WS2812 service, ownership and exact commands.
|
||||
Implementation and validation are in progress; this entry does not claim
|
||||
phase completion or performance improvement. The existing GNU toolchain is
|
||||
used first, as requested; no dependency version has been changed.
|
||||
The initial entry recorded implementation and validation in progress; it did not
|
||||
claim phase completion or performance improvement. The existing GNU toolchain
|
||||
was used as requested; no dependency version has been changed.
|
||||
|
||||
Early development testing found a compressed-instruction acceptance bug:
|
||||
`rs_mcu_unmapped_probe` assembled its faulting load as 16-bit `4108`, while
|
||||
@@ -448,7 +492,7 @@ not a prerequisite to the architectural improvements in R2-P3 through R2-P5.
|
||||
| TINY-R2-P0 - Performance Contract and Roadmap Freeze | Reviewable requirements, exact old/new phase mapping, invariant package/IO counts, same-frequency CPU/main-SRAM ownership, explicit performance budgets, links and commands. Record actual documentation checks separately. | Documentation freeze only; no hardware result |
|
||||
| TINY-R2-P1 - Reproducible Baseline, Constraints and Measurements | Reviewed source/profile/lock/tool identity; current 24 MHz functional and workload baseline; clocks, reset endpoints, constraints and timing-exception audit; counters and comparison methodology. Historical WNS is a risk reference, not a refreshed measurement. | Functional/measurement baseline accepted by explicit P2 approval on 2026-10-06; timing, warning and physical gaps retained |
|
||||
| TINY-R2-P2 - Reset Distribution and CPU/SRAM Clock Feasibility | Reset distribution and payload-reset semantics; locked IHP130 main-SRAM macro timing, candidate common CPU/SRAM periods and representative paths; early clock/reset feasibility with explicit gaps. No final routed/PVT pass is implied. | Implementation and evidence ready for review; all analyzed rates retain timing failures; phase acceptance pending human review |
|
||||
| TINY-R2-P3 - Software and DMA Scheduling | Compiler and placement A/B results, finite DMA ownership, burst/chunk scheduling, WS2812 refill budget and workload correctness on the available platform. | Pending |
|
||||
| TINY-R2-P3 - Software and DMA Scheduling | Compiler and placement A/B results, finite DMA ownership, burst/chunk scheduling and available-path correctness; approved option A retains product DMA/IRQ budget qualification for the platform that supplies the route. | Matrix retained on `3e46cc8`; subsequent two P1 HAL fixes and focused/compatibility checks complete in the worktree; human review/acceptance pending |
|
||||
| TINY-R2-P4 - Dual-Port Hazard3 and Four-Bank Local SRAM | Actual separate I/D paths, four independent 32 KiB bank frontends, SYS-clocked physical main-SRAM macros, local latency/fairness, FENCE.I, debug/reset and early inventory/SDC/macro-binding updates. | Pending |
|
||||
| TINY-R2-P5 - Per-Target Concurrent Fabric | Cross-target concurrency, one combined transaction per target, central-DMA read/write overlap, AW/W binding, errors, simultaneous faults/counters and accepted-transfer drain. | Pending |
|
||||
| TINY-R2-P6 - Shared IP and Eight-Channel DMA Integration | Legacy P7 obligations; shared PWM reporting, I2S slave and alternate-input-route prerequisites; common ABI/HAL parity; Crypto banks/lifecycle; truthful capabilities and affected Mini compatibility. | Pending |
|
||||
|
||||
+142
-1
@@ -69,9 +69,47 @@ volatile uint32_t rs_dma_test_mmio[1024];
|
||||
static uint32_t ws_registers[16];
|
||||
static uint32_t ws_pushed;
|
||||
static uint32_t ws_pixels[33];
|
||||
static uint32_t ws_idle_on_interrupt_read;
|
||||
static uint32_t dma_irq_enabled = 8U;
|
||||
static bool dma_irq_pending;
|
||||
static rs_dma_session_t dma_irq_owner;
|
||||
static rs_status_t dma_irq_result;
|
||||
|
||||
uint32_t rs_dma_test_irq_save(void) {
|
||||
const uint32_t saved = dma_irq_enabled;
|
||||
dma_irq_enabled = 0U;
|
||||
return saved;
|
||||
}
|
||||
|
||||
void rs_dma_test_irq_restore(uint32_t saved) {
|
||||
dma_irq_enabled = saved;
|
||||
if ((saved != 0U) && dma_irq_pending) {
|
||||
dma_irq_pending = false;
|
||||
/* Model START taking effect before an interrupt can execute. */
|
||||
if (RS_DMA_CH_REG(3U, RS_DMA_CH_REG_CTRL) == RS_DMA_CH_CTRL_START) {
|
||||
RS_DMA_CH_REG(3U, RS_DMA_CH_REG_STATUS) = RS_DMA_STATUS_BUSY;
|
||||
}
|
||||
dma_irq_result = rs_dma_session_acquire(&dma_irq_owner, 3U);
|
||||
if (dma_irq_result == RS_OK) {
|
||||
const rs_dma_config_t config = {.kind = RS_DMA_KIND_MM_TO_MM,
|
||||
.source = 0x3000U, .destination = 0x4000U, .byte_count = 16U,
|
||||
.width = RS_DMA_WIDTH_32, .source_increment = true,
|
||||
.destination_increment = true, .burst_beats = 1U};
|
||||
dma_irq_result = rs_dma_session_configure(&dma_irq_owner, &config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rs_ws2812_test_read(uint32_t offset) {
|
||||
return ws_registers[offset / 4U];
|
||||
const uint32_t value = ws_registers[offset / 4U];
|
||||
if ((offset == 0x30U) && (ws_idle_on_interrupt_read != 0U)) {
|
||||
ws_registers[0x18U / 4U] = 8U;
|
||||
if (ws_idle_on_interrupt_read == 1U) {
|
||||
ws_registers[0x30U / 4U] |= RS_WS2812_INTR_DONE;
|
||||
}
|
||||
ws_idle_on_interrupt_read = 0U;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void rs_ws2812_test_write(uint32_t offset, uint32_t value) {
|
||||
@@ -105,6 +143,107 @@ static void ws_test_reset(void) {
|
||||
ws_registers[0x18U / 4U] = 8U;
|
||||
ws_registers[0x24U / 4U] = 3U;
|
||||
ws_pushed = 0U;
|
||||
ws_idle_on_interrupt_read = 0U;
|
||||
}
|
||||
|
||||
static int test_dma_tcd_preemption(void) {
|
||||
static _Alignas(64) rs_dma_tcd_t tcd = {
|
||||
.source = 0x1000U, .destination = 0x2000U, .byte_count = 32U, .y_count = 1U,
|
||||
.control = RS_DMA_TCD_VALID | RS_DMA_TCD_SRC_INC | RS_DMA_TCD_DST_INC |
|
||||
(UINT32_C(1) << RS_DMA_TCD_BURST_SHIFT)};
|
||||
rs_status_t result;
|
||||
bool valid;
|
||||
ws_test_reset();
|
||||
dma_irq_pending = true;
|
||||
dma_irq_result = RS_OK;
|
||||
result = rs_dma_submit_tcd(3U, &tcd, 1U);
|
||||
valid = (result == RS_ETIMEOUT) && (dma_irq_result == RS_EIO) &&
|
||||
!dma_irq_pending && (dma_irq_enabled == 8U) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_TCD_HEAD) == (uint32_t)(uintptr_t)&tcd) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_TCD_COUNT) == 1U) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_SRC_ADDR) == tcd.source);
|
||||
RS_DMA_CH_REG(3U, RS_DMA_CH_REG_STATUS) = 0U;
|
||||
(void)rs_dma_session_release(&dma_irq_owner);
|
||||
if (!valid) {
|
||||
return 1;
|
||||
}
|
||||
/* An already leased direct channel must remain untouched on rejection. */
|
||||
if (rs_dma_session_acquire(&dma_irq_owner, 3U) != RS_OK) {
|
||||
return 2;
|
||||
}
|
||||
RS_DMA_CH_REG(3U, RS_DMA_CH_REG_SRC_ADDR) = 0x3000U;
|
||||
result = rs_dma_submit_tcd(3U, &tcd, 1U);
|
||||
valid = (result == RS_EIO) && (dma_irq_enabled == 8U) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_TCD_HEAD) == 0U) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_TCD_COUNT) == 0U) &&
|
||||
(RS_DMA_CH_REG(3U, RS_DMA_CH_REG_SRC_ADDR) == 0x3000U);
|
||||
(void)rs_dma_session_release(&dma_irq_owner);
|
||||
if (!valid) {
|
||||
return 3;
|
||||
}
|
||||
/* Calling from an already masked context must not enable interrupts. */
|
||||
dma_irq_enabled = 0U;
|
||||
result = rs_dma_submit_tcd(3U, &tcd, 1U);
|
||||
valid = (result == RS_ETIMEOUT) && (dma_irq_enabled == 0U);
|
||||
dma_irq_enabled = 8U;
|
||||
return valid ? 0 : 4;
|
||||
}
|
||||
|
||||
static int test_ws2812_completion_race(void) {
|
||||
rs_ws2812_dma_status_t transfer;
|
||||
for (uint32_t delay = 1U; delay <= 2U; ++delay) {
|
||||
ws_test_reset();
|
||||
if (rs_ws2812_dma_begin(ws_pixels, 4U, 0U, 100U) != RS_OK) {
|
||||
return 1;
|
||||
}
|
||||
/* Complete after INTR_STATE was sampled, before STATUS is sampled.
|
||||
* The second case also delays the sticky DONE latch until next service. */
|
||||
ws_idle_on_interrupt_read = delay;
|
||||
if (rs_ws2812_dma_service(1U) != RS_OK) {
|
||||
return 2;
|
||||
}
|
||||
(void)rs_ws2812_dma_status(&transfer);
|
||||
if (!transfer.active || transfer.draining || transfer.dma_pending) {
|
||||
return 3;
|
||||
}
|
||||
ws_registers[0x30U / 4U] |= RS_WS2812_INTR_DONE;
|
||||
if (rs_ws2812_dma_service(2U) != RS_OK) {
|
||||
return 4;
|
||||
}
|
||||
(void)rs_ws2812_dma_status(&transfer);
|
||||
if (transfer.active || (transfer.result != RS_OK) ||
|
||||
(ws_registers[0x24U / 4U] != 3U)) {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
/* An idle core without DONE must still terminate on error, abort or the
|
||||
* original deadline; waiting for the sticky latch cannot hide a failure. */
|
||||
for (uint32_t failure = 0U; failure < 3U; ++failure) {
|
||||
const rs_status_t expected = (failure == 2U) ? RS_ETIMEOUT : RS_EIO;
|
||||
ws_test_reset();
|
||||
if (rs_ws2812_dma_begin(ws_pixels, 4U, 0U, 3U) != RS_OK) {
|
||||
return 6;
|
||||
}
|
||||
ws_idle_on_interrupt_read = 2U;
|
||||
if (rs_ws2812_dma_service(1U) != RS_OK) {
|
||||
return 7;
|
||||
}
|
||||
if (failure == 0U) {
|
||||
ws_registers[0x2cU / 4U] = 1U;
|
||||
} else if (failure == 1U) {
|
||||
ws_registers[0x30U / 4U] = RS_WS2812_INTR_ABORTED;
|
||||
}
|
||||
if (rs_ws2812_dma_service(3U) != expected) {
|
||||
return 8;
|
||||
}
|
||||
(void)rs_ws2812_dma_service(4U);
|
||||
(void)rs_ws2812_dma_service(5U);
|
||||
(void)rs_ws2812_dma_status(&transfer);
|
||||
if (transfer.active || (transfer.result != expected)) {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_dma_sessions(void) {
|
||||
@@ -2989,6 +3128,8 @@ int main(void) {
|
||||
test_ws2812_helpers(),
|
||||
test_dma_sessions(),
|
||||
test_ws2812_refill(),
|
||||
test_dma_tcd_preemption(),
|
||||
test_ws2812_completion_race(),
|
||||
test_timer_helpers(),
|
||||
test_psram_helpers(),
|
||||
test_sdram_helpers(),
|
||||
|
||||
Reference in new issue
Block a user