mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-05 06:32:37 +00:00
4576 lines
296 KiB
Markdown
4576 lines
296 KiB
Markdown
# Mini Audio Processing Unit
|
|
|
|
## Purpose and Research Boundary
|
|
|
|
This document is the authoritative architecture, interface, microcode, software,
|
|
and verification contract for the retroSoC Mini Audio Processing Unit (APU).
|
|
The stable feature slug is `apu`. The current release provides autonomous
|
|
WAV/PCM and native FLAC decode, fixed-point sample processing, private DMA,
|
|
direct I2S streaming, and continuous keyword spotting (KWS).
|
|
|
|
Current-release scope: APU-P6 MP3 decoding is explicitly DEFERRED. The stable
|
|
Phase 6 ID/title remain as an inactive placeholder; Phase 7 proceeds from
|
|
the reviewed Phase 5 baseline and Phase 8 does not require Phase 6 completion.
|
|
The retained P6 design/reference sections are historical, non-normative notes
|
|
for a future refreeze. They do not enable MP3 or require MP3 dependencies,
|
|
three-active-codec packing, PSNR or MP3 real-time evidence in this release.
|
|
This scope rule takes precedence over those deferred notes. All other active
|
|
WAV/FLAC, KWS, transport, ABI, ownership and physical-evidence requirements
|
|
remain in force.
|
|
|
|
APU-P7 is refrozen on 2026-09-11 by the P7 sections below. They fix the
|
|
reference inputs, APUM 1.0 wire format, numerical profile, capture settings,
|
|
HAL and acceptance rules; they do not assert that P7 is implemented. The
|
|
starting implementation for that freeze was reviewed P5 with
|
|
`CAPABILITY0=0x000001bd`. Completed pre-P9 KWS qualification permits
|
|
`0x000001fd`. No P6 work is reactivated.
|
|
|
|
The 2026-09-24 **APU-P9 macro-backed storage refreeze** supersedes the physical
|
|
ROM representation and inferred loader-memo implementation, not their numerical
|
|
or proof semantics. Its objective is to remove large synthesis-inferred
|
|
memories, prioritizing additional physical SRAM macros, then additional bounded
|
|
processing cycles. It does not shrink the advertised model/workspace capacity
|
|
or weaken real-time/accuracy requirements. P9 introduces a separately loaded
|
|
APUC coefficient image and additive APB V1.2 discovery/control; APUM 1.0,
|
|
APUMC V1/V2 and the job descriptor remain unchanged. The detailed P9 contract
|
|
below takes precedence for the post-P9 release; earlier phase identities and
|
|
their historical discovery values remain valid for those earlier profiles.
|
|
This refreeze is a future implementation contract, not a synthesis/PPA result.
|
|
|
|
The APU is deliberately coreless. LP loads one validated codec-microcode bundle
|
|
at startup and HP or LP later submits jobs. The APU contains a bounded codec
|
|
sequencer and fixed processing engines; it does not contain Hazard3, VexiiRiscv,
|
|
a DSP CPU, a general-purpose instruction set, or a C runtime.
|
|
|
|
The design was frozen on 2026-09-02 from these repository sources of truth:
|
|
|
|
- `rtl/mini/address_map/memory_map.json` for the reserved `APB4_APU` window;
|
|
- `rtl/mini/integration/soc_topology.json` for APB4, IRQ, resource, and data
|
|
integration;
|
|
- `rtl/mini/integration/clock_reset_domains.json` for clock/reset and CDC/RDC;
|
|
- `docs/lp-hp-architecture.md`, `docs/axi4-interconnect.md`, and
|
|
`docs/axi4-stream.md` for the control, memory, and stream planes;
|
|
- `docs/ip/dma.md`, `docs/ip/i2s.md`, `docs/ip/jpeg.md`, `docs/ip/xpi.md`, and
|
|
`docs/ip/resource-controller.md` for DMA, stream, fixed-pipeline,
|
|
programmable-LUT, and lifecycle patterns; and
|
|
- `dependencies/dependencies.lock.json` for managed inputs.
|
|
|
|
APU-P2 implements the private AXI4 DMA, descriptor ring scheduler, fair Gateway
|
|
A arbitration, and the production audio stream router with two 64-word Common
|
|
FIFOs. The shell reports only private-DMA and ring capabilities; public direct
|
|
start, ring doorbell, and APU stream routes remain fail-closed until their
|
|
later-phase engines exist. No claim is made that microcode, sequencer, codec
|
|
engines, KWS, codec conformance, Linux driver, timing closure, power closure,
|
|
CDC/RDC signoff, or silicon qualification exists.
|
|
|
|
## Commercial References
|
|
|
|
The selected design uses public architectural lessons and does not reproduce
|
|
proprietary decoder RTL or microcode.
|
|
|
|
| Reference | Relevant behavior and status | Reuse boundary | Avoided boundary |
|
|
| --- | --- | --- | --- |
|
|
| [Cadence Tensilica HiFi DSP family](https://www.cadence.com/en_US/home/resources/product-briefs/tensilica-hifi-dsp-family-pb.html) | Current programmable audio/voice IP with codec, bitstream, SIMD, and AI support. | Keep codec behavior updateable and separate scalar control from fixed arithmetic. | Do not import a DSP core, proprietary ISA/toolchain, floating point, or vendor PPA claims. |
|
|
| [Ceva-BX1](https://www.ceva-ip.com/product/ceva-bx1/) | Current compact controller/DSP with MACs, queue management, accelerator ports, and light-AI support. | Use bounded queues and explicit accelerator commands. | Do not instantiate a controller core or project 7 nm frequency/GMAC data onto Mini. |
|
|
| [NXP FlexSPI](https://mcuxpresso.nxp.com/api_doc/dev/1315/group__flexspi.html) | Active programmable command-LUT controller with distinct mapped and indirect data paths. | Reuse the model of host-loaded, validated sequences executed by a hardware sequencer. | A serial-memory phase LUT is much simpler than audio parsing; its eight-instruction scale is not reused. |
|
|
| [CAST H264-D-BP](https://www.cast-inc.com/compression/avc-hevc-video-compression/h264-d-bp) | Current standalone streaming decoder IP with zero host decode overhead, errors, bit-accurate model, and AXI wrappers. | Reuse autonomous decode, flow-controlled streams, explicit errors, and independent BAM delivery. | Video codec gates, memory, throughput, and PPA are not Audio/Mini evidence. |
|
|
| [AMD Audio Formatter](https://docs.amd.com/r/en-US/pg330-audio-formatter/Features) | Maintained AXI4 memory/stream audio mover with DMA, completion/error interrupts, timeout, and graceful halt. | Reuse independent memory/stream paths, bounded halt, and period/error observability. | It formats PCM/AES audio and is not a compressed-file decoder. |
|
|
| [MP3 hardware/software co-design](https://scholars.ncu.edu.tw/en/publications/a-hardwaresoftware-co-design-of-mp3-audio-decoder/) | A programmable parser controls dedicated IMDCT/filterbank hardware, showing the split between irregular bitstream control and regular arithmetic. | Implement irregular parsing in bounded microcode and regular kernels in fixed engines. | Its process, area, frequency, and embedded parser processor are not reused. |
|
|
| [RFC 9639 FLAC](https://datatracker.ietf.org/doc/rfc9639/) | Current standards-track FLAC definition; decode uses integer bit parsing, Rice residuals, fixed/LPC prediction, and channel decorrelation. | Implement the native streamable decoder using integer primitives and bounded history. | Ogg/Matroska/MP4 mappings and the full 1..8-channel standard are outside MVP. |
|
|
| [MLPerf Tiny KWS](https://github.com/mlcommons/tiny/blob/master/benchmark/training/keyword_spotting/README.md) | Reproducible 49 by 10 INT8 MFCC/DS-CNN workload with 12 classes and a 90 percent quality threshold. | Use its operator set, corpus, accuracy threshold, and reproducibility rules. | Do not claim an MLPerf result unless the applicable runner and reporting rules are followed exactly. |
|
|
|
|
The selected pattern is bounded microcode plus fixed decoder primitives. A
|
|
general-purpose processor is not retained as normative behavior. Separate
|
|
per-format RTL is also not selected because it would duplicate bitstream,
|
|
entropy, arithmetic, DMA, and recovery logic and make fixes silicon changes.
|
|
|
|
## Requirements and Non-goals
|
|
|
|
### MVP requirements
|
|
|
|
| ID | Requirement |
|
|
| --- | --- |
|
|
| `APU-MVP-001` | The APU MUST expose APB4 configuration at the reserved `APB4_APU` window `0x1001_3000..0x1001_3fff`. |
|
|
| `APU-MVP-002` | The APU MUST use a private 32-bit AXI4 DMA master for microcode, model, descriptors, compressed input, and optional PCM output. |
|
|
| `APU-MVP-003` | The APU MUST expose 32-bit AXI4-Stream PCM input and output integrated with existing I2S RX/TX streams. |
|
|
| `APU-MVP-004` | WAV/PCM and native FLAC decode MUST execute entirely in the coreless APU. MP3 decoding is deferred and MUST NOT be advertised by this release. |
|
|
| `APU-MVP-005` | LP MUST load one bundle containing exactly three entry descriptors: active WAV and FLAC entries plus the existing unsupported-MP3 trap stub. Successful load MUST lock microcode until hard reset. |
|
|
| `APU-MVP-006` | The codec sequencer MUST execute only the bounded V1 microcode ISA and MUST NOT execute RV32, C, ELF, or arbitrary system-memory instructions. |
|
|
| `APU-MVP-007` | Continuous 16 kHz mono KWS MUST use an independent fixed MFCC/INT8 DS-CNN engine and MUST run concurrently with decode. |
|
|
| `APU-MVP-008` | DMA, sequencer, primitive, stream, resampler, and KWS work MUST have timeout, abort, first-error, and recovery behavior. |
|
|
| `APU-MVP-009` | Microcode, KWS model, descriptors, tables, and buffers MUST use versioned, bounds-checked formats with no dynamic allocation. |
|
|
| `APU-MVP-010` | The APU MUST integrate as Resource Controller index 7 and route its interrupt exclusively to LP IRQ31 or HP PLIC source 10 according to owner. |
|
|
| `APU-MVP-011` | Hardware/software register, descriptor, microcode, and model definitions MUST remain independently handwritten and pass parity tests; no register generator is allowed. |
|
|
| `APU-MVP-012` | Compatible Common APB4, AXI4, AXI4-Stream, register, FIFO, round-robin, synchronizer, and warm-flush CDC components MUST be reused. |
|
|
| `APU-MVP-013` | LP/HP host software MUST remain freestanding at SDK boundaries and MUST NOT introduce hosted I/O, `malloc`, or `free`. |
|
|
|
|
### Target requirements
|
|
|
|
- Sequencer, primitive engines, KWS, SRAM banks, and DMA MUST be independently
|
|
clock-gateable when idle, subject to later physical implementation evidence.
|
|
- Microcode capacity, arithmetic lane count, SRAM bank geometry, and internal
|
|
pipelines MUST remain outside the public job/HAL ABI.
|
|
- Every normal completion, rejection, timeout, trap, xrun, handoff, and reset
|
|
MUST be diagnosable without a waveform.
|
|
- A commercial release MUST add full conformance, reusable VIP, coverage,
|
|
CDC/RDC, DFT/MBIST, PVT/MMMC, power, post-layout, and silicon evidence.
|
|
|
|
### Deferred work and non-goals
|
|
|
|
The following work is DEFERRED outside the active implementation phases of
|
|
this release and MUST NOT be silently inserted into an MVP phase:
|
|
|
|
- APU-P6 MPEG-1/2/2.5 Layer III MP3 decoding, its production microprogram,
|
|
reference/corpus setup, three-active-codec packing, PSNR and MP3 real-time
|
|
qualification; the Phase 6 slot remains reserved for an explicit future
|
|
refreeze and is not a release blocker;
|
|
- AAC, HE-AAC, Opus, Vorbis, Ogg-FLAC, ALAC, WMA, Dolby, DTS, LC3, or any
|
|
format beyond the three frozen entry points;
|
|
- encoding, transcoding, MPEG Layer I/II, more than two channels, object audio,
|
|
TDM, PDM, beamforming, AEC, or ANC;
|
|
- a general-purpose processor, DSP core, arbitrary microcode compiler, C/ELF
|
|
execution, runtime code download per job, or HP software decode fallback;
|
|
- hardware cache coherency, IOMMU, virtual contexts, preemption, or more than
|
|
one active decode job;
|
|
- an independent retained KWS power island, PCLK-independent cold wake, DVFS,
|
|
or quantified always-on power claim;
|
|
- microcode/model signatures, secure boot, encryption, anti-rollback, DRM, or
|
|
protected-content claims;
|
|
- ECC, repair, or production MBIST for APU SRAM; and
|
|
- a generic NPU or arbitrary TFLite/ONNX operator runtime.
|
|
|
|
## Selected Architecture
|
|
|
|
### Module hierarchy
|
|
|
|
```text
|
|
apb4_apu
|
|
apu_reg
|
|
apu_microcode_loader
|
|
apu_proof_memo (P9: 16 key SRAMs + one valid-bitmap SRAM)
|
|
apu_job_scheduler
|
|
apu_dma
|
|
apu_codec_sequencer
|
|
apu_control_store (4096 x 64, 32 KiB from the P5 capacity refreeze)
|
|
apu_scalar_registers (16 x 32)
|
|
apu_loop_stack
|
|
apu_bitstream_engine
|
|
apu_entropy_engine
|
|
apu_reconstruction_engine
|
|
apu_transform_engine
|
|
apu_resampler
|
|
apu_local_sram (112 KiB)
|
|
apu_kws_frontend
|
|
apu_kws_engine
|
|
apu_kws_coeff_loader (P9: LP-controlled APUC DMA/CRC/readback/lock)
|
|
apu_kws_coeff_store (P9: 15 coefficient/profile SRAMs)
|
|
apu_stream_router
|
|
```
|
|
|
|
There is no CPU inside this hierarchy. `apu_codec_sequencer` cannot issue a
|
|
system load/store, execute from AXI memory, address APB4, take a CPU interrupt,
|
|
or run a compiler-generated program. It fetches one validated 64-bit control
|
|
word per cycle from local control store and orchestrates fixed engines.
|
|
|
|
From the P5 capacity refreeze, total image/data storage is 144 KiB instead of
|
|
the earlier 128 KiB target. P3/P4 implemented capacities remain as reported in
|
|
their capability profiles:
|
|
|
|
| Region | Capacity | Use |
|
|
| --- | ---: | --- |
|
|
| control store | 32 KiB | 4096 64-bit instructions containing codec programs and common subroutines; P3/P4 retain 2048 words / 16 KiB. |
|
|
| codec table/scratch | 24 KiB | Huffman tables, MP3 reservoir/coefficient state, FLAC predictor/Rice state |
|
|
| compressed/PCM staging | 16 KiB | input and output DMA/stream buffers |
|
|
| KWS | 64 KiB | model weights, 49 by 10 history, and tiled activations |
|
|
| common/result reserve | 8 KiB | descriptors, counters, CRC, and bounded temporary state |
|
|
|
|
The regions are statically partitioned. Software discovers capacities through
|
|
capability registers but never physical bank count. The implementation uses
|
|
existing 4 KiB technology SRAM abstractions and records the actual macro map in
|
|
PPA evidence.
|
|
|
|
P9 retains these 144 KiB advertised regions. Auxiliary physical storage adds
|
|
32 KiB of existing verifier path stack, 68 KiB of macro-backed memo/valid
|
|
storage and 60 KiB of coefficients/profile constants: 304 KiB / 76 logical
|
|
4 KiB wrappers in the full macro-backed P9 APU. These auxiliary bytes are not
|
|
new APUM scratch, codec-addressable SRAM or system memory windows.
|
|
|
|
### Fixed engines
|
|
|
|
- Bitstream engine: 64-bit refill reservoir, 1..32-bit peek/get/skip, byte
|
|
alignment, frame sync, CRC8, and CRC16.
|
|
- Entropy engine: table-driven MP3 Huffman pair/quad, canonical symbol decode,
|
|
unary scan, Rice/Rice2 remainder, sign restoration, and bounded table index.
|
|
- Reconstruction engine: four initial 32x32-to-64 fixed-point MAC lanes,
|
|
rounding, shifts, saturation, MP3 requant/stereo, and FLAC fixed/LPC order
|
|
0..32 plus channel decorrelation. Lane count is implementation-private.
|
|
- Transform engine: MP3 IMDCT6/18, DCT32/polyphase synthesis, overlap/history,
|
|
and fixed coefficient-table access.
|
|
- Resampler/packer: deterministic fixed-point polyphase conversion, volume,
|
|
downmix, S16/S24 saturation, memory packing, and I2S packing.
|
|
|
|
The sequencer issues a kernel command and either continues independent scalar
|
|
work or waits for completion. Each kernel has a specified maximum latency and
|
|
cannot access outside its assigned local-memory range.
|
|
|
|
Previously delivered P4 primitives remain implemented and tested even where
|
|
their names or research rationale mention MP3. Their presence does not enable
|
|
format ID 1. Deferring MP3 does not remove these engines, shrink the 4096-word
|
|
control store or 112 KiB data store, or change the P5 instruction/transport ABI.
|
|
|
|
### Independent KWS
|
|
|
|
I2S RX feeds a dedicated KWS input FIFO, mono/downmix, 16 kHz resampling,
|
|
512-point fixed FFT/MFCC, and a 16-lane INT8/INT32 DS-CNN engine. Supported
|
|
operators are Conv2D, depthwise 3 by 3, pointwise 1 by 1, bias,
|
|
requantization/ReLU, the pinned 25 by 5 average pool, fully connected, and
|
|
INT8 Softmax. The source model's shape-only reshape is folded by the converter.
|
|
|
|
KWS evaluates a 49 by 10 INT8 window every 100 ms. Score threshold and 1..255
|
|
consecutive-hit debounce are programmable. KWS does not use codec microcode or
|
|
codec MAC lanes, so it remains live during file decode. Only SRAM arbitration,
|
|
PCLK, stream routing, IRQ collection, and lifecycle control are shared.
|
|
|
|
### Control and data flow
|
|
|
|
1. LP programs read/write ACLs and the `APUMC` bundle address/size/CRC.
|
|
2. Private DMA loads the WAV/FLAC bundle with the retained MP3 trap entry.
|
|
Hardware and the offline
|
|
verifier validate header, capabilities, control flow, ranges, loop bounds,
|
|
tables, and CRC before publishing valid.
|
|
3. Successful load automatically sets a hard-reset-cleared microcode lock.
|
|
HP cannot load or replace microcode.
|
|
4. LP similarly loads and locks one `APUM` KWS model, then may hand APU
|
|
ownership to HP.
|
|
5. The owner submits a direct job or advances a descriptor ring. The scheduler
|
|
selects the frozen codec entry, fetches compressed input, and starts the
|
|
sequencer.
|
|
6. PCM is written to memory or emitted through AXI4-Stream to I2S TX. Progress
|
|
advances only after successful AXI responses or stream handshakes.
|
|
7. Concurrent I2S RX KWS maintains its own FIFO and model context. Stable KWS
|
|
hits and codec/DMA events enter the aggregate sticky interrupt state.
|
|
|
|
There is one active decode job plus continuous KWS. Accepted AXI4 or
|
|
AXI4-Stream transfers are never withdrawn. Decode abort stops new work, drains
|
|
accepted traffic, terminates the sequencer, and flushes local codec state only
|
|
after drain.
|
|
|
|
## Interfaces
|
|
|
|
### APB4 configuration
|
|
|
|
The APU is a 32-bit APB4 slave at `0x1001_3000..0x1001_3fff`. Registers are
|
|
naturally aligned and follow the repository setup/access and response-retention
|
|
contract.
|
|
|
|
- Reads have no side effects except explicit snapshot results.
|
|
- RW registers honor byte strobes. Commands, addresses, sizes, CRCs, ring
|
|
control, and portals require `PSTRB=4'hf`.
|
|
- Unaligned/unmapped accesses, unsupported strobes, invalid direction,
|
|
active-configuration writes, or illegal commands complete with `PSLVERR`.
|
|
- Configuration is latched on job start or KWS enable.
|
|
- Command bits are pulses, not stored levels.
|
|
|
|
### Private AXI4 DMA
|
|
|
|
The APU provides one PCLK-domain 32-bit AXI4 master with 32-bit addresses,
|
|
one-bit ID/user, and ID zero. It occupies the unused third input of I/O Gateway
|
|
A and uses the existing PCLK-to-HP `axi4_async_bridge` and 32-to-64 upsizer.
|
|
It retains global data-master identity 3; the nine-master crossbar and
|
|
seven-bit global ID width preserve that identity.
|
|
|
|
Gateway A MUST replace its fixed-priority selection with a burst-boundary
|
|
Common round-robin arbiter among APU, SDIO0, and USB2. Ownership is retained
|
|
through terminal `B` or `RLAST`; a continuously eligible source cannot starve
|
|
while downstream traffic completes.
|
|
|
|
DMA behavior:
|
|
|
|
- one internal read and one internal write transaction may be active, although
|
|
the shared gateway may serialize addresses;
|
|
- aligned 4-byte addresses, arbitrary nonzero byte counts, and partial final
|
|
write strobes;
|
|
- 1..16-beat `INCR` bursts that never cross 4 KiB;
|
|
- 64-byte-aligned microcode/model images and 128-byte-aligned descriptors;
|
|
- `AxCACHE=0`, data-only attributes, and no executable system-memory access;
|
|
- reads from SRAM, SDRAM, QPI, OPI, or XPI; writes to SRAM, SDRAM, QPI, or OPI;
|
|
- inclusive local read/write base/limit ACLs, with reset denying all access;
|
|
- `SLVERR`, `DECERR`, bad ID, malformed `RLAST`, ACL overflow, timeout, or
|
|
bridge flush recorded against the active load/job; and
|
|
- abort blocks new addresses, drains accepted responses, then discards local
|
|
in-flight codec data.
|
|
|
|
The DMA no-progress timer runs only while an AXI request is presented or an
|
|
accepted AXI read/write/descriptor transaction is outstanding. A handshake on
|
|
`AW`, `W`, `B`, `AR`, or `R` is progress and reloads the full nonzero
|
|
`DMA_TIMEOUT` value. Merely holding `VALID`, moving data between local FIFOs,
|
|
or waiting on a codec/stream endpoint is not DMA progress. The first cycle with
|
|
an unaccepted address/data `VALID` or an accepted transaction starts the epoch.
|
|
Expiry blocks new AXI addresses, records error 17 against the owning direction
|
|
and address, and drains any accepted transaction before terminal completion.
|
|
The timer stops when no AXI request or response is pending and clears on abort,
|
|
soft reset, resource reset, or hard reset.
|
|
|
|
Gateway A has one fabric identity, so local first-error and per-client counters
|
|
are required for attribution. Handoff conservatively waits for APU, USB2, and
|
|
SDIO0 gateway traffic to become idle.
|
|
|
|
### AXI4-Stream
|
|
|
|
The APU input/output use 32-bit `axi4_stream_if` in PCLK with ID/destination/
|
|
user zero and `TKEEP/TSTRB=4'hf`.
|
|
|
|
- S16 stereo packs the earlier sample in `[15:0]` and later sample in
|
|
`[31:16]`, matching I2S.
|
|
- S24 uses one signed sample in `[23:0]` and sign extension in `[31:24]`.
|
|
- Mono playback is duplicated to I2S left/right; mono memory output remains
|
|
mono.
|
|
- Payload and sidebands remain stable under backpressure.
|
|
- `TLAST` marks the final PCM word of a finite decode job; continuous KWS does
|
|
not depend on `TLAST`.
|
|
|
|
TX producer and RX consumer are selected independently. Reset preserves the
|
|
existing central-DMA route. APU mode selects APU-to-I2S TX and I2S RX-to-KWS,
|
|
which may operate concurrently. Active-direction route changes are rejected.
|
|
No external pad is added; I2S retains audio-clock-domain sampling and CDC.
|
|
|
|
Phase 2 implements and verifies the production stream router and two 64-word
|
|
Common FIFOs through a test-only wrapper, but it has no production APU PCM
|
|
producer or KWS consumer. Consequently, in the SoC integration through Phase 2,
|
|
`CAPABILITY0.STREAMS` remains zero and any `STREAM_ROUTE` direction value 1
|
|
returns `PSLVERR`. Reset value 0 continues to select central DMA. The test-only
|
|
wrapper is in the verification filelist only, drives the production FIFO/router
|
|
interfaces directly, and creates no register, descriptor operation, capability,
|
|
or synthesized diagnostic path. TX value 1 becomes legal only when the first
|
|
codec stream producer is delivered; RX value 1 becomes legal only with KWS.
|
|
|
|
A TX direction is active when its route is APU and at least one of the endpoint
|
|
session-active input, a nonempty TX FIFO, or an asserted unaccepted output
|
|
`TVALID` is true. An RX direction is active when its route is APU and at least
|
|
one of the endpoint session-active input, a nonempty RX FIFO, or an accepted
|
|
but unretired input beat is true. A `STREAM_ROUTE` write that changes one
|
|
direction returns `PSLVERR` while that direction is active; changing only the
|
|
inactive direction or rewriting the same value is legal. Phase-2 production
|
|
endpoint session-active inputs are tied low.
|
|
|
|
`STREAM_WATERMARK` programs an RX/input high watermark in bits `[7:0]` and a
|
|
TX/output low watermark in bits `[15:8]`; `[31:16]` are reserved zero. Each
|
|
value is 0 (disabled) or 1..64 words. The input event occurs on an occupancy
|
|
crossing from below to greater-than-or-equal-to its threshold and rearms below
|
|
the threshold. The output event occurs on a crossing from above to
|
|
less-than-or-equal-to its threshold while TX is active and rearms above it.
|
|
The events set sticky IRQ bits 6 and 7. Setting a threshold to zero disables
|
|
future events and resets its crossing detector but does not clear an already
|
|
sticky IRQ; software clears that through `IRQ_STATE`. Hardware set wins a
|
|
same-cycle W1C.
|
|
|
|
## DMA and Interrupt Contract
|
|
|
|
### Direct and ring operation
|
|
|
|
Direct mode uses `JOB_*` registers. Ring mode uses 2..256 power-of-two entries.
|
|
Each descriptor is exactly 128 bytes and 128-byte aligned. Head is hardware
|
|
owned; tail is software owned.
|
|
|
|
Software writes payload, sets OWN last, executes `fence rw,rw`, advances tail,
|
|
and rings the doorbell. Hardware fetches only owned descriptors, writes all
|
|
results, clears OWN, advances head, then raises completion. An unowned head
|
|
stalls without consumption. An invalid owned entry completes with error and
|
|
advances head; stop-on-error prevents the next fetch. IOC overrides coalescing.
|
|
|
|
Phase 2 does not add a public diagnostic operation and does not make decode or
|
|
KWS executable. Because every public operation depends on later phases,
|
|
`START_DIRECT` and `RING_DOORBELL` continue to return `PSLVERR` until valid
|
|
locked microcode and the selected format/KWS capability are both present.
|
|
Phase-2 verification instead instantiates the production DMA and ring scheduler
|
|
behind a verification-only backend. The backend drives the internal transport
|
|
request/completion interface, exercises memory-to-memory direct transfers,
|
|
fetches public 128-byte descriptors, supplies deterministic result writeback,
|
|
and tests OWN-last, unowned stalls, invalid-owned completion, wrap, coalescing,
|
|
abort, and every bus error. It is excluded from behavioral/synthesis product
|
|
filelists and has no public opcode or runtime path. Thus successful P2
|
|
direct/ring verification does not pull microcode, primitives, codecs, or KWS
|
|
forward.
|
|
|
|
For non-IOC completions, an internal pending-completion count increments after
|
|
descriptor result writeback and OWN clear. A zero-to-one transition starts a
|
|
coalescing timeout epoch loaded from `RING_COALESCE[31:16]`; the timer decrements
|
|
once per PCLK cycle. A ring event is generated when the post-completion pending
|
|
count reaches `RING_COALESCE[7:0]` or the timer expires with a nonzero count.
|
|
Either event clears the pending count and stops the epoch. An IOC completion
|
|
immediately generates one ring event covering the IOC descriptor and all prior
|
|
pending completions, then clears the count/epoch regardless of the programmed
|
|
threshold. IRQ W1C does not reset or rearm the count/timer. Ring disable,
|
|
abort, soft/resource/hard reset, or stop-on-error terminal writeback clears the
|
|
pending count and timer. Both coalescing fields remain nonzero as already
|
|
required by the P1 ABI. If an error descriptor also has IOC, its terminal
|
|
writeback first generates the IOC ring event covering pending completions, then
|
|
stop-on-error halts and clears the coalescing state; the error IRQ is collected
|
|
independently.
|
|
|
|
### Descriptor ABI
|
|
|
|
| Word | Field | Direction and meaning |
|
|
| ---: | --- | --- |
|
|
| 0 | `CONTROL` | SW to HW: operation `[3:0]`, input format `[7:4]`, output mode `[9:8]`, downmix 10, resample 11, IOC 30, OWN 31. |
|
|
| 1 | `RESULT_STATUS` | HW to SW: done 0, error 1, aborted 2, error code `[8:3]`, stage `[12:9]`, AXI response `[14:13]`. |
|
|
| 2 | `INPUT_ADDRESS` | Aligned compressed-file or diagnostic PCM source. |
|
|
| 3 | `INPUT_LENGTH` | Nonzero source bytes. |
|
|
| 4 | `OUTPUT_ADDRESS` | Aligned PCM destination for decode; zero for stream output or operation1. |
|
|
| 5 | `OUTPUT_CAPACITY` | Destination bytes for decode; zero for stream output or operation1. |
|
|
| 6 | `INPUT_CONFIG` | Expected rate `[16:0]`, channels `[18:17]`, source bits/sample `[25:20]`; zero fields mean derive. |
|
|
| 7 | `OUTPUT_CONFIG` | Rate `[16:0]`, channels `[18:17]`, PCM format `[20:19]`. |
|
|
| 8 | `JOB_FLAGS` | Strict decode bit 0; all other V1 bits zero. |
|
|
| 9 | `KWS_CONFIG` | Memory-window threshold `[7:0]`, debounce `[15:8]`; zero for decode. |
|
|
| 10 | `RESULT_INPUT_USED` | Bytes consumed. |
|
|
| 11 | `RESULT_OUTPUT_BYTES` | PCM bytes written or streamed. |
|
|
| 12 | `RESULT_FRAMES` | PCM sample frames produced by decode; input sample frames consumed by operation1. |
|
|
| 13 | `RESULT_SOURCE_INFO` | Detected rate `[16:0]`, channels `[18:17]`, bits/sample `[24:19]`. |
|
|
| 14 | `RESULT_CYCLES` | Saturating job cycle count. |
|
|
| 15 | `RESULT_DETAIL` | Format-, microcode-, or primitive-specific diagnostic. |
|
|
| 16-17 | `COOKIE` | Opaque 64-bit value preserved. |
|
|
| 18-19 | `START_TIMESTAMP` | 64-bit PCLK cycle timestamp. |
|
|
| 20-21 | `FINISH_TIMESTAMP` | 64-bit PCLK cycle timestamp. |
|
|
| 22 | `KWS_RESULT` | Class `[7:0]`, score `[15:8]`, hit 16 for memory-window operation. |
|
|
| 23 | `MICROCODE_BUILD_ID` | Low 32 bits of the loaded `APUMC` build ID. |
|
|
| 24-31 | Reserved | Software writes zero; hardware writes/preserves zero. |
|
|
|
|
Operation 0 is file decode and operation 1 is one KWS memory window. Input
|
|
format 0 is WAV/PCM, 1 MP3 Layer III, and 2 native FLAC. Output mode 0 is
|
|
memory and 1 is I2S stream. PCM format 0 is interleaved S16_LE and 1 is
|
|
S24_32LE. All other V1 encodings fail validation.
|
|
|
|
Format ID 1 remains allocated for compatibility but MP3 decode (operation 0,
|
|
format 1) is unsupported throughout this release, including after P7 KWS is
|
|
enabled. `RS_APU_MP3` remains declared and HAL decode/submission returns
|
|
`RS_ENOTSUP` for it. A raw direct start returns `PSLVERR` without payload DMA
|
|
or result mutation; an owned ring entry completes code 3/stage 2/detail
|
|
`0x01000001` at its CONTROL address and follows existing writeback/OWN-clear
|
|
rules. This does not defer KWS operation 1. No host MP3 fallback is allowed.
|
|
MP3 format ID 1, capability bit 1, and format-1 parser-detail reasons
|
|
`0x0100..0x0140` remain reserved for future MP3 reactivation and may not be
|
|
reassigned. Those deferred parser details are not emitted in this release;
|
|
the existing unsupported result/stub detail `0x01000001` is unchanged.
|
|
|
|
### Interrupts
|
|
|
|
| Bit | Sticky event |
|
|
| ---: | --- |
|
|
| 0 | direct job done |
|
|
| 1 | ring/coalescing event |
|
|
| 2 | stable KWS hit |
|
|
| 3 | microcode load done |
|
|
| 4 | model load done |
|
|
| 5 | abort done |
|
|
| 6 | input watermark |
|
|
| 7 | output watermark |
|
|
| 8 | first error |
|
|
| 9 | stream underrun/overrun |
|
|
| 10 | sequencer trap/watchdog |
|
|
| 11 | P9 coefficient-load terminal completion; inspect KWS_COEFF_STATUS for success/failure. |
|
|
| 12-31 | reserved |
|
|
|
|
`IRQ_ENABLE` gates delivery, not collection. `IRQ_TEST` sets implemented state
|
|
only. `IRQ_STATE` is W1C; hardware set wins a simultaneous clear. `irq_o` is
|
|
the OR of enabled sticky state.
|
|
Bit 11 is implemented only with the P9 coefficient interface; earlier profiles
|
|
retain mask `0x000007ff` and reject it. The P9 mask is `0x00000fff`; LP/HP
|
|
interrupt routes and existing bit meanings do not change.
|
|
|
|
The APU is Resource Controller index 7. LP owner routes to APB-peripheral group
|
|
bit23 and Hazard3 IRQ31. HP owner suppresses LP delivery and routes to HP PLIC
|
|
source10. Reset masks both. Hardware never delivers one event to both owners.
|
|
|
|
## Register and Software ABI
|
|
|
|
### Register map
|
|
|
|
Unlisted offsets are reserved and return `PSLVERR`.
|
|
|
|
| Offset | Register | Access | Reset | Contract |
|
|
| ---: | --- | --- | ---: | --- |
|
|
| `0x000` | `IP_ID` | RO | `0x41505530` | ASCII `APU0`. |
|
|
| `0x004` | `IP_VERSION` | RO | implementation | APB V1.0 `0x00010000` for P1..P4 and pre-expansion P5; expanded pre-P9 profiles use V1.1 `0x00010001`; P9 coefficient-interface profiles use V1.2 `0x00010002`. |
|
|
| `0x008` | `CAPABILITY0` | RO | implementation | Bits 0..2 WAV/MP3/FLAC, 3 private DMA, 4 ring, 5 streams, 6 KWS, 7 sequencer, 8 resampler; P9 appends coefficient-load interface bit 9. P1 `0`; P2 `0x18`; P3 `0x98`; P4 `0x198`; P5 `0x1bd`; qualified pre-P9 KWS `0x1fd`; qualified P9 `0x3fd`. MP3 bit 1 remains zero. |
|
|
| `0x00c` | `CAPABILITY1` | RO | implementation | Control-store KiB `[7:0]`, data SRAM KiB `[15:8]`, max channels `[17:16]`, max source-rate kHz `[25:18]`; P1/P2 are `0`; P3 is `0x00000010`; P4 is `0x01827010`; expanded P5 onward is `0x01827020` (32/112/2/96). |
|
|
| `0x010` | `COMMAND` | WO | `0` | Start-direct 0, abort 1, soft-reset 2, ring-kick 3, microcode-load 4, model-load 5, clear-counters 6. |
|
|
| `0x014` | `STATUS` | RO | `0x00000100` | Microcode valid 0, model valid 1, busy 2, ring 3, decode 4, KWS listening 5, quiesced 6, aborting 7, idle 8, sequencer trapped 9. |
|
|
| `0x018` | `IRQ_STATE` | RW1C | `0` | Sticky events. |
|
|
| `0x01c` | `IRQ_ENABLE` | RW | `0` | Event enables. |
|
|
| `0x020` | `IRQ_TEST` | WO | `0` | Software event injection. |
|
|
| `0x024` | `ERROR_STATUS` | RW1C | `0` | Valid 0/W1C, code `[6:1]`, stage `[10:7]`, AXI response `[12:11]`, descriptor index `[20:13]`. |
|
|
| `0x028` | `ERROR_ADDRESS` | RO | `0` | First failing AXI/local/PC address. |
|
|
| `0x02c` | `ERROR_DETAIL` | RO | `0` | First format/opcode/primitive/model diagnostic. |
|
|
| `0x030` | `SEQUENCER_TIMEOUT` | RW idle | `0x0000ffff` | Nonzero maximum no-retirement cycles. |
|
|
| `0x034` | `STREAM_ROUTE` | RW idle | `0` | TX `[1:0]`: DMA0/APU1; RX `[3:2]`: DMA0/APU1. |
|
|
| `0x038` | `STREAM_STATUS` | RO | P1 `0`, P2+ `0x00000014` | Frozen live/sticky allocation below. |
|
|
| `0x03c` | `OWNER_STATUS` | RO | `0` | Resource owner `[1:0]`, owner lock 8, quiesce 9, reset request 10. |
|
|
| `0x040` | `READ_BASE` | RW idle/LP | `0xffffffff` | Inclusive local DMA read base. |
|
|
| `0x044` | `READ_LIMIT` | RW idle/LP | `0` | Base greater than limit denies all. |
|
|
| `0x048` | `WRITE_BASE` | RW idle/LP | `0xffffffff` | Inclusive local DMA write base. |
|
|
| `0x04c` | `WRITE_LIMIT` | RW idle/LP | `0` | Inclusive write limit. |
|
|
| `0x050` | `DMA_TIMEOUT` | RW idle | `0x0000ffff` | Nonzero no-progress timeout. |
|
|
| `0x054` | `ABI_DIGEST` | RO | `0` until MVP | CRC32 digest over the complete frozen V1 tables; partial P1..P7 implementations report zero. |
|
|
| `0x058` | `SEQUENCER_STATUS` | RO | `0` | PC low `[10:0]`, class `[14:11]`, opcode `[18:15]`, wait 19, loop-active 20; APB V1.1 appends PC bit 11 at bit 21. |
|
|
| `0x05c` | `SEQUENCER_RETIRED` | RO | `0` | Saturating instructions retired in current frame/block. |
|
|
| `0x060` | `STREAM_WATERMARK` | RW idle | `0` | RX/input high `[7:0]`, TX/output low `[15:8]`, reserved `[31:16]=0`; zero disables, otherwise 1..64. Added in P2. |
|
|
| `0x080` | `MC_IMAGE_ADDRESS` | RW idle/LP | `0` | 64-byte-aligned `APUMC` address. |
|
|
| `0x084` | `MC_IMAGE_SIZE` | RW idle/LP | `0` | Exact nonzero bundle bytes. |
|
|
| `0x088` | `MC_EXPECTED_CRC` | RW idle/LP | `0` | Expected payload CRC32, equal to header. |
|
|
| `0x08c` | `MC_STATUS` | RO | `0` | Busy 0, valid 1, header error 2, range error 3, control-flow error 4, table error 5, CRC error 6, capability error 7; `[31:8]` reserved zero. |
|
|
| `0x090` | `MC_ABI` | RO | `0` | Loaded APUMC/ISA version: V1.0 `0x00010000` or V2.0 `0x00020000`, according to the validated image. Independent of APB IP_VERSION. |
|
|
| `0x094` | `MC_BUILD_ID_LO` | RO | `0` | Build ID low. |
|
|
| `0x098` | `MC_BUILD_ID_HI` | RO | `0` | Build ID high. |
|
|
| `0x09c` | `MC_LOCK` | RO | `0` | Lock bit 0 sets automatically after successful load; `[31:1]` reserved zero; hard reset clears. |
|
|
| `0x0a0` | `MC_ACTUAL_CRC` | RO | `0` | Observed microcode payload CRC32. |
|
|
| `0x0a4` | `MC_LOAD_COUNT` | RO | `0` | Saturating successful-load count. |
|
|
| `0x100` | `JOB_CONTROL` | RW idle | `0` | Descriptor word0 operation/format/output/downmix/resample without OWN/IOC. |
|
|
| `0x104` | `JOB_INPUT_ADDRESS` | RW idle | `0` | Direct input address. |
|
|
| `0x108` | `JOB_INPUT_LENGTH` | RW idle | `0` | Direct input bytes. |
|
|
| `0x10c` | `JOB_OUTPUT_ADDRESS` | RW idle | `0` | Direct output address. |
|
|
| `0x110` | `JOB_OUTPUT_CAPACITY` | RW idle | `0` | Direct output capacity. |
|
|
| `0x114` | `JOB_INPUT_CONFIG` | RW idle | `0` | Descriptor word6. |
|
|
| `0x118` | `JOB_OUTPUT_CONFIG` | RW idle | `0` | Descriptor word7. |
|
|
| `0x11c` | `JOB_FLAGS` | RW idle | `0` | Descriptor word8. |
|
|
| `0x120` | `JOB_STATUS` | RO | `0` | Frozen live/sticky allocation below. |
|
|
| `0x124` | `JOB_INPUT_USED` | RO | `0` | Result input bytes. |
|
|
| `0x128` | `JOB_OUTPUT_BYTES` | RO | `0` | Result output bytes. |
|
|
| `0x12c` | `JOB_FRAMES` | RO | `0` | Result PCM frames. |
|
|
| `0x130` | `JOB_SOURCE_INFO` | RO | `0` | Detected source geometry. |
|
|
| `0x134` | `JOB_CYCLES` | RO | `0` | Saturating job cycles. |
|
|
| `0x138` | `JOB_DETAIL` | RO | `0` | Diagnostic detail. |
|
|
| `0x180` | `RING_BASE` | RW idle | `0` | 128-byte-aligned descriptor base. |
|
|
| `0x184` | `RING_SIZE` | RW idle | `0` | 2..256 entries, power of two. |
|
|
| `0x188` | `RING_HEAD` | RO | `0` | Hardware index. |
|
|
| `0x18c` | `RING_TAIL` | RW | `0` | Software index. |
|
|
| `0x190` | `RING_CONTROL` | RW idle | `0` | Enable 0, stop-on-error 1. |
|
|
| `0x194` | `RING_STATUS` | RO | P1 `0`, P2+ `0x00000004` | Frozen live/sticky allocation below. |
|
|
| `0x198` | `RING_COMPLETED` | RO | `0` | Saturating completion count. |
|
|
| `0x19c` | `RING_COALESCE` | RW idle | `0x00010001` | Count `[7:0]`, nonzero timeout `[31:16]`. |
|
|
| `0x1a0` | `RING_DOORBELL` | WO | `0` | Write one to rescan. |
|
|
| `0x200` | `KWS_MODEL_ADDRESS` | RW idle/LP | `0` | 64-byte-aligned `APUM` address. |
|
|
| `0x204` | `KWS_MODEL_SIZE` | RW idle/LP | `0` | Exact model bytes. |
|
|
| `0x208` | `KWS_MODEL_EXPECTED_CRC` | RW idle/LP | `0` | Expected payload CRC32. |
|
|
| `0x20c` | `KWS_CONTROL` | RW idle | `0` | Enable 0, memory-window 1, clear-history pulse 2. |
|
|
| `0x210` | `KWS_CONFIG` | RW idle | `0x00000380` | Threshold `[7:0]` 128, debounce `[15:8]` 3. |
|
|
| `0x214` | `KWS_STATUS` | RO | `0` | Listening, inference busy, history full, hit, overrun, model valid/locked. |
|
|
| `0x218` | `KWS_RESULT` | RO | `0` | Class `[7:0]`, score `[15:8]`, stable hit 16. |
|
|
| `0x21c` | `KWS_TIMESTAMP_LO` | RO | `0` | Detection timestamp low. |
|
|
| `0x220` | `KWS_TIMESTAMP_HI` | RO | `0` | Detection timestamp high. |
|
|
| `0x224` | `KWS_FRAME_COUNT` | RO | `0` | Accepted feature frames. |
|
|
| `0x228` | `KWS_INFERENCE_COUNT` | RO | `0` | Completed inferences. |
|
|
| `0x22c` | `KWS_HIT_COUNT` | RO | `0` | Stable hits. |
|
|
| `0x230` | `KWS_OVERRUN_COUNT` | RO | `0` | Dropped/late windows. |
|
|
| `0x234` | `KWS_MODEL_STATUS` | RO | `0` | Busy, valid/lock, header/range/size/CRC/operator errors. |
|
|
| `0x238` | `KWS_MODEL_ACTUAL_CRC` | RO | `0` | Observed payload CRC32. |
|
|
| `0x23c` | `KWS_INPUT_CONFIG` | RW disabled/idle | `0x0104bb80` | P7 append: rate `[16:0]`, physical channels `[18:17]`, precision `[25:20]`; see P7 capture rules. |
|
|
| `0x240` | `KWS_COEFF_ADDRESS` | RW idle/LP | `0` | P9: 64-byte-aligned APUC DMA source. |
|
|
| `0x244` | `KWS_COEFF_SIZE` | RW idle/LP | `0` | P9: exact 61504-byte APUC image size. |
|
|
| `0x248` | `KWS_COEFF_EXPECTED_CRC` | RW idle/LP | `0` | P9: expected APUC payload CRC32. |
|
|
| `0x24c` | `KWS_COEFF_COMMAND` | WO | `0` | P9: full-word value 1 starts coefficient loading. |
|
|
| `0x250` | `KWS_COEFF_STATUS` | RO | `0` | P9: busy, valid, lock and terminal validation errors. |
|
|
| `0x254` | `KWS_COEFF_ACTUAL_CRC` | RO | `0` | P9: finalized SRAM-readback CRC32. |
|
|
| `0x258` | `KWS_COEFF_ID_LO` | RO | `0` | P9: published coefficient ID bits 31:0. |
|
|
| `0x25c` | `KWS_COEFF_ID_HI` | RO | `0` | P9: published coefficient ID bits 63:32. |
|
|
| `0x260` | `KWS_COEFF_CAPACITY` | RO | `0x0000f000` | P9: auxiliary coefficient payload capacity in bytes. |
|
|
| `0x300` | `PERF_CONTROL` | RW | `0` | Enable 0, clear pulse 1, snapshot pulse 2. |
|
|
| `0x304` | `PERF_STATUS` | RO | `0` | Snapshot valid and overflow summary. |
|
|
| `0x308..0x354` | `PERF_*` | RO snapshot | `0` | Ten 64-bit pairs: active cycles, input/output bytes, decoded frames, DMA read/write stalls, stream stalls, sequencer instructions, KWS cycles, and faults. |
|
|
|
|
P2 freezes these status layouts. Reserved bits read zero and writes to every
|
|
status register return `PSLVERR`.
|
|
|
|
| `STREAM_STATUS` bits | Semantics |
|
|
| ---: | --- |
|
|
| 0 | `TX_ACTIVE`, live according to the active-direction definition in the stream contract. |
|
|
| 1 | `RX_ACTIVE`, live according to the active-direction definition in the stream contract. |
|
|
| 2 | `TX_FIFO_EMPTY`, live; reset one from P2 onward. |
|
|
| 3 | `TX_FIFO_FULL`, live. |
|
|
| 4 | `RX_FIFO_EMPTY`, live; reset one from P2 onward. |
|
|
| 5 | `RX_FIFO_FULL`, live. |
|
|
| 6 | `TX_UNDERRUN`, sticky until IRQ-state stream-xrun W1C or reset. |
|
|
| 7 | `RX_OVERRUN`, sticky until IRQ-state stream-xrun W1C or reset. |
|
|
| 15:8 | Saturating low-byte count of TX words accepted by I2S since counter clear/reset. |
|
|
| 23:16 | Saturating low-byte count of RX words accepted from I2S since counter clear/reset. |
|
|
| 31:24 | Reserved zero. |
|
|
|
|
The two xrun bits clear together when software W1C-clears IRQ bit 9. A new xrun
|
|
in that cycle wins and leaves the corresponding status/IRQ state set.
|
|
|
|
| `JOB_STATUS` bits | Semantics |
|
|
| ---: | --- |
|
|
| 0 | `BUSY`, live while a direct or ring-owned job has not reached terminal writeback. |
|
|
| 1 | `DONE`, sticky terminal success. |
|
|
| 2 | `ERROR`, sticky terminal failure. |
|
|
| 3 | `ABORTED`, sticky terminal abort. |
|
|
| 4 | `DIRECT_ACTIVE`, live while the current job came from direct registers. |
|
|
| 5 | `INPUT_PENDING`, live while input AXI/stream work is outstanding. |
|
|
| 6 | `OUTPUT_PENDING`, live while output AXI/stream work is outstanding. |
|
|
| 7 | `WRITEBACK_PENDING`, live while descriptor/direct results have not retired. |
|
|
| 13:8 | Terminal six-bit error code. |
|
|
| 17:14 | Terminal four-bit stage. |
|
|
| 19:18 | Terminal AXI response. |
|
|
| 31:20 | Reserved zero. |
|
|
|
|
`DONE` denotes success and is mutually exclusive with `ERROR`. `ABORTED` may
|
|
coexist with `ERROR` when drain encounters a higher-priority fault. Terminal
|
|
sticky/result fields clear when a new valid internal/public job is accepted or
|
|
on soft/resource/hard reset; they do not clear on status read.
|
|
|
|
| `RING_STATUS` bits | Semantics |
|
|
| ---: | --- |
|
|
| 0 | `ACTIVE`, live after scheduler start until disabled, aborted, or stopped. |
|
|
| 1 | `STALLED_UNOWNED`, live while head points to an unowned descriptor. |
|
|
| 2 | `EMPTY`, live when head equals tail and no descriptor/writeback is pending; reset one from P2 onward. |
|
|
| 3 | `ERROR`, sticky after a descriptor/ring error. |
|
|
| 4 | `WRAPPED`, sticky after head wraps to zero. |
|
|
| 5 | `COALESCE_PENDING`, live while pending-completion count is nonzero. |
|
|
| 6 | `WRITEBACK_PENDING`, live while result/OWN-clear is outstanding. |
|
|
| 7 | `STOPPED_ON_ERROR`, sticky when stop-on-error halts after terminal writeback. |
|
|
| 15:8 | Live pending-completion count used by coalescing. |
|
|
| 23:16 | Last descriptor index whose result writeback and OWN clear completed. |
|
|
| 31:24 | Reserved zero. |
|
|
|
|
Ring sticky fields, pending count, last index, and coalescing epoch clear on a
|
|
legal ring-enable transition from zero to one or on soft/resource/hard reset.
|
|
Status reads and IRQ W1C do not clear them.
|
|
|
|
Capability bits describe implemented hardware, not whether a codec job is
|
|
currently legal. P2 reports `CAPABILITY0=0x00000018` for private DMA and ring,
|
|
while format, streams, KWS, sequencer, and resampler bits remain zero;
|
|
`CAPABILITY1=0`. P3 reports `CAPABILITY0=0x00000098` for private DMA, ring, and
|
|
the sequencer, and `CAPABILITY1=0x00000010` for the 16 KiB control store. P3
|
|
continues to report zero for every format, stream, KWS, resampler, data-SRAM,
|
|
channel, and sample-rate field. P4 reports `CAPABILITY0=0x00000198` for private
|
|
DMA, ring, sequencer, and the implemented resampler primitive, and
|
|
`CAPABILITY1=0x01827010` for 16 KiB control store, 112 KiB local data SRAM,
|
|
two-channel primitive capacity, and 96 kHz maximum source-rate capacity. P4
|
|
format bits 0..2, streams bit 5, and KWS bit 6 remain zero because no public
|
|
codec or stream session exists. A caller must require both the requested
|
|
format/KWS bit and the necessary engine/model state before submitting. The P2
|
|
stream router remains unadvertised through P4 because its production endpoints
|
|
remain unavailable. `ABI_DIGEST`
|
|
is zero for every partial Phase1..7 build and becomes the nonzero CRC32 over
|
|
the complete canonical APB V1 register/field/job-descriptor, supported
|
|
`APUMC` V1/V2, `APUM`, opcode,
|
|
format/IRQ/error tables only in the Phase8 supported MVP. For this release,
|
|
the digest includes reserved MP3 identifiers and the P5 rejection/stub contract
|
|
but excludes the inactive P6 design archive. A zero digest means
|
|
prototype/incomplete ABI and is not a compatibility hash for a subset.
|
|
|
|
The P8 digest input is canonical ASCII JSON over sections `discovery`, `apb`,
|
|
`kws_model`, `formats`, `apumc`, `apum`, `isa`, and `mp3_stub`. Object keys are
|
|
recursively sorted, separators are literal comma and colon with no whitespace,
|
|
integers are JSON decimal numbers, non-ASCII text is escaped, and the byte stream
|
|
has no terminal newline. Apply reflected CRC-32/ISO-HDLC to the complete byte
|
|
stream. The checked-in tool, handwritten RTL constant, handwritten C constant,
|
|
and parity test must agree on the exact nonzero result `0xf5005d7c`.
|
|
|
|
Expanded P5 keeps `CAPABILITY0=0x000001bd` and primitive mask `0x001fffff`,
|
|
but advertises `CAPABILITY1=0x01827020` and `IP_VERSION=0x00010001` for the
|
|
32 KiB store and appended PC-high status bit. This hardware discovery is
|
|
constant even while a legacy V1 image is loaded. Format, TX/RX, KWS, data-SRAM,
|
|
channel, rate, IRQ, ownership, and job behavior are otherwise unchanged.
|
|
|
|
Hardware set wins same-cycle W1C. Snapshot captures all 64-bit counters
|
|
atomically; software reads low then high.
|
|
|
|
`MICROCODE_LOAD` and `MODEL_LOAD` require LP owner, quiesced/idle state,
|
|
valid ACLs, and a clear corresponding lock; KWS must also be disabled for model
|
|
load. P3 makes `MICROCODE_LOAD` legal under those conditions, but does not make
|
|
any decode or stream transport public; `MODEL_LOAD` remains rejected until its
|
|
later phase. `START_DIRECT` requires valid locked
|
|
microcode and a validated direct job whose requested format/KWS capability is
|
|
set. `RING_KICK` requires an enabled valid ring plus valid locked microcode and
|
|
a supported operation at head. `ABORT` requires active work. `SOFT_RESET` and
|
|
`CLEAR_COUNTERS` require idle. Therefore P2 and P3 reject public start and
|
|
doorbell, and reject `STREAM_ROUTE` value 1 in either direction, while accepting
|
|
and validating their configuration registers. The P3 dummy-program sequencer
|
|
launch path is verification-only and creates no public command, descriptor
|
|
operation, route, capability, or ABI. Violations return `PSLVERR` without
|
|
changing state.
|
|
|
|
### `APUMC` microcode bundle ABI
|
|
|
|
#### Versioned P5 control-store expansion
|
|
|
|
The selected P5 capacity remedy is a 4096-word, 64-bit control store. The
|
|
reported compacted 2437-word trial was already 389 words over the old limit
|
|
and still omitted cross-frame FLAC resampling and complete long-Rice paths.
|
|
That report is sizing evidence, not a complete-codec acceptance result. The
|
|
expanded store leaves 1659 words relative to that incomplete trial; the final
|
|
complete image must still demonstrate that it fits. No compact opcode,
|
|
dynamic-kernel operand, parser/CRC shortcut in RTL, host decode, overlay, or
|
|
runtime code replacement is authorized by this refreeze.
|
|
|
|
APB register ABI and APUMC binary ABI have independent versions. APB V1.1 is
|
|
an additive status/capacity extension. APUMC V2.0 versions the widened PC and
|
|
branch operands so legacy images retain their exact V1 validation rules.
|
|
|
|
| Target / image | APB `IP_VERSION` | `CAPABILITY1` | Header word 1 / loaded `MC_ABI` | Instruction count / PC width |
|
|
| --- | --- | --- | --- | --- |
|
|
| Historical P3 | `0x00010000` | `0x00000010` | `0x00010000` only | 1..2048 / 11 bits |
|
|
| Historical P4 | `0x00010000` | `0x01827010` | `0x00010000` only | 1..2048 / 11 bits |
|
|
| Pre-expansion P5 compatibility image | Historical hardware remains `0x00010000` | Historical hardware remains `0x01827010` | `0x00010000` | 1..2048 / 11 bits |
|
|
| Expanded P5, legacy image loaded | `0x00010001` | `0x01827020` | `0x00010000` | 1..2048 / 11-bit validation on the 12-bit engine |
|
|
| Expanded P5, V2 image loaded | `0x00010001` | `0x01827020` | `0x00020000` | 1..4096 / 12 bits |
|
|
|
|
Expanded P5 must load both exact header versions. Unknown versions fail with
|
|
the existing loader header-error tuple, locating header word 1 and reporting
|
|
its observed value. A V1 image with count 2049..4096, a high descriptor PC bit,
|
|
or branch immediate bit 11 set still fails V1 validation even on the expanded
|
|
hardware. A V2 image is legal with fewer than 2049 instructions too; image size
|
|
must never be used to infer the encoding. Older P3/P4/pre-expansion P5 loaders
|
|
reject V2 at the header before publishing valid or fetching its instructions.
|
|
|
|
Version-related loader failures keep code 9, stage 1, response/index zero:
|
|
unknown version sets MC_STATUS header-error and uses address
|
|
`MC_IMAGE_ADDRESS+4`, detail header word 1; invalid count sets range-error
|
|
and uses `MC_IMAGE_ADDRESS+12`, detail header word 3. Invalid PC/reserved bits
|
|
in entry word 0 or 1 set range-error and locate that entry word with its
|
|
observed 32-bit value. A branch's nonzero reserved immediate bits set
|
|
control-flow-error and use its full instruction source address plus the
|
|
existing `trap_detail(1)` encoding. These are the same category precedence
|
|
and locator rules as before; the selected version supplies only new bounds
|
|
and masks. V2 does not create a new error code or IRQ.
|
|
|
|
The 64-byte header, three 32-byte entry descriptors, 64-bit instruction format,
|
|
opcode/predicate IDs, primitive masks, scratch/table fields, CRC algorithm and
|
|
coverage, build ID, and MP3 stub contents are retained. Only the versioned
|
|
instruction-count, PC fields and branch immediates below expand. The 128-byte
|
|
public job/ring descriptor does not change. No image can switch ISA versions
|
|
while executing, and lock/reset/admission/publication semantics are unchanged.
|
|
|
|
All multibyte bundle fields and instructions are little-endian. The bundle
|
|
starts with this exact 64-byte header:
|
|
|
|
| Word | Field |
|
|
| ---: | --- |
|
|
| 0 | magic `0x41504d43` (`APMC`) |
|
|
| 1 | combined APUMC/ISA ABI: major `[31:16]`, minor `[15:0]`; V1.0 `0x00010000` or V2.0 `0x00020000` under the target matrix above |
|
|
| 2 | total bundle bytes |
|
|
| 3 | instruction count, 1..2048 for V1 or 1..4096 for V2 |
|
|
| 4 | 64-byte-aligned instruction offset |
|
|
| 5 | table-payload offset, 4-byte aligned |
|
|
| 6 | table-payload bytes |
|
|
| 7 | entry-descriptor offset, 32-byte aligned |
|
|
| 8 | entry count; V1 and V2 require exactly 3 |
|
|
| 9 | required primitive mask, equal to the OR of all entry primitive masks |
|
|
| 10 | maximum declared local scratch bytes |
|
|
| 11 | CRC32/ISO-HDLC over all bytes after the header |
|
|
| 12 | build ID bits `[31:0]` |
|
|
| 13 | build ID bits `[63:32]` |
|
|
| 14-15 | reserved zero |
|
|
|
|
The header total must equal `MC_IMAGE_SIZE` and be at least 160 bytes. The
|
|
instruction byte count is exactly instruction count multiplied by eight. The
|
|
header, descriptor array, instruction array, and table payload must lie wholly
|
|
inside the total, must not overlap, and address arithmetic must not wrap. A
|
|
zero-byte table payload is represented by word 6 equal to zero; word 5 remains
|
|
range checked and aligned but is otherwise ignored. Bytes not occupied by one
|
|
of those regions are padding and must be zero. `MC_EXPECTED_CRC`, header
|
|
word 11, and the CRC32/ISO-HDLC calculated over bundle bytes 64 through the end
|
|
in increasing byte-address order must all agree. CRC parameters are reflected
|
|
polynomial `0xedb88320` (normal form `0x04c11db7`), initial value
|
|
`0xffffffff`, and final XOR `0xffffffff`. Any other word-1 value, reserved bit,
|
|
entry count, alignment, size, range, overlap, or CRC relation is invalid.
|
|
|
|
The descriptor array contains three 32-byte, eight-word entries. Header word 1
|
|
selects exactly one of the following PC allocations; there is no mixed-layout
|
|
array. Unlisted fields below retain the same meaning in both versions.
|
|
|
|
| Word | Bit allocation and units |
|
|
| ---: | --- |
|
|
| 0 | format ID `[3:0]`; V1 entry PC `[14:4]`, reserved `[31:15]`; V2 entry PC `[15:4]`, reserved `[31:16]`; all reserved bits zero |
|
|
| 1 | V1 first PC `[10:0]`, last PC `[26:16]`, reserved `[15:11]` and `[31:27]`; V2 first PC `[11:0]`, last PC `[27:16]`, reserved `[15:12]` and `[31:28]`; all reserved bits zero |
|
|
| 2 | scratch base byte offset `[16:0]`; `[31:17]` reserved zero |
|
|
| 3 | scratch size in bytes `[16:0]`; `[31:17]` reserved zero |
|
|
| 4 | maximum loop count `[15:0]`; `[31:16]` reserved zero |
|
|
| 5 | maximum retired instructions per frame/block `[23:0]`; `[31:24]` reserved zero |
|
|
| 6 | required primitive mask `[31:0]` |
|
|
| 7 | table-relative byte offset `[15:0]`; table bytes `[31:16]` |
|
|
|
|
Word 0 reserved masks are `0xffff8000` (V1) and `0xffff0000` (V2).
|
|
Word 1 reserved masks are `0xf800f800` (V1) and `0xf000f000` (V2).
|
|
Words 2..7 retain masks `0xfffe0000`, `0xfffe0000`, `0xffff0000`,
|
|
`0xff000000`, `0xffe00000` (reserved primitive bits), and zero respectively;
|
|
implemented-mask checks are additional to the word-6 reserved mask. V2 word 0
|
|
is `format_id | (entry_pc<<4)` and word 1 is
|
|
`first_pc | (last_pc<<16)`, without truncating any of the 12 PC bits. Entry
|
|
format IDs/order remain 0/1/2. For PCs below 2048 these words have exactly
|
|
the same values in V1 and V2; the header version still governs all checks.
|
|
|
|
PC fields are 64-bit instruction indices, not byte addresses. Descriptor array
|
|
indices 0, 1, and 2 have format IDs 0, 1, and 2 for WAV, MP3, and FLAC
|
|
respectively. For each entry, first PC is less than or equal to entry PC, entry
|
|
PC is less than or equal to last PC, and last PC is less than the header
|
|
instruction count. Scratch base and size are four-byte aligned, do not wrap,
|
|
and lie within the advertised local data SRAM. Maximum
|
|
loop count is 1..65535 and maximum retired count is nonzero. Table offset and
|
|
size are four-byte aligned and select a non-wrapping range inside the global
|
|
table payload. Word 10 of the header equals the greatest scratch end declared
|
|
by any entry.
|
|
|
|
P3 has no local data SRAM or primitive engine. It therefore accepts only
|
|
scratch base/size zero, table offset/size zero, header table bytes zero, and
|
|
header/entry primitive masks zero. Its required three entries may contain only
|
|
class-0 control and class-1 scalar instructions. A nonzero scratch/table field,
|
|
primitive mask, or class-2 through class-6 instruction fails load validation;
|
|
P3 never publishes table bytes. P4 adds the local table/SRAM and primitive
|
|
capabilities needed to admit those already frozen encodings. This restriction
|
|
does not pull a codec, table engine, or P4 storage into P3.
|
|
|
|
Primitive mask bits are fixed as follows. Bits 21..31 are reserved zero. Every
|
|
instruction's listed primitive must appear in its entry mask, every entry mask
|
|
must be a subset of the implemented mask, and the header mask is exactly the
|
|
OR of the three entry masks.
|
|
|
|
| Bit | Primitive | Bit | Primitive |
|
|
| ---: | --- | ---: | --- |
|
|
| 0 | bitstream reservoir | 11 | fixed predictor |
|
|
| 1 | CRC | 12 | LPC |
|
|
| 2 | Huffman | 13 | channel decorrelate |
|
|
| 3 | Rice | 14 | resampler |
|
|
| 4 | local memory/table | 15 | PCM pack |
|
|
| 5 | local FIFO | 16 | DMA input |
|
|
| 6 | requantize | 17 | DMA output |
|
|
| 7 | stereo processing | 18 | stream output |
|
|
| 8 | IMDCT6 | 19 | frame commit/job result |
|
|
| 9 | IMDCT18 | 20 | event |
|
|
| 10 | DCT32/polyphase | | |
|
|
|
|
Instructions are little-endian 64-bit words:
|
|
|
|
```text
|
|
63 60 59 56 55 52 51 48 47 44 43 40 39 32 31 0
|
|
+---------+---------+---------+---------+---------+---------+----------+-----------+
|
|
| class | opcode | pred | dst | src0 | src1 | aux | immediate |
|
|
+---------+---------+---------+---------+---------+---------+----------+-----------+
|
|
```
|
|
|
|
The sequencer has 16 32-bit GPRs, three comparison flags (`EQ`, signed `LT`,
|
|
and unsigned `LT`), four return-stack entries, and four loop slots. Saved
|
|
return PCs and loop-start PCs are 11 bits in P3/P4 and 12 bits in expanded P5;
|
|
V1 execution still checks the 11-bit range. All
|
|
are cleared at entry launch and on soft, resource, or hard reset. Every GPR is
|
|
writable. GPR writes become visible to the next retired instruction. `CMP` is
|
|
the only instruction that changes comparison flags. Arithmetic `ADD` and `SUB`
|
|
wrap modulo 2^32; only `SAT` saturates. Variable shifts use the low five bits
|
|
of `src1`. Default next PC is current PC plus one.
|
|
|
|
Predicate encodings are exact:
|
|
|
|
| `pred` | Condition |
|
|
| ---: | --- |
|
|
| 0 | always |
|
|
| 1 | comparison `EQ` |
|
|
| 2 | not comparison `EQ` |
|
|
| 3 | comparison signed `LT` |
|
|
| 4 | not comparison signed `LT` |
|
|
| 5 | comparison unsigned `LT` |
|
|
| 6 | not comparison unsigned `LT` |
|
|
| 7 | descriptor input exhausted and bit reservoir empty |
|
|
| 8 | input FIFO nonempty |
|
|
| 9 | output FIFO not full |
|
|
| 10 | fixed-kernel completion latch set |
|
|
| 11 | no transport outstanding and the last transport command succeeded |
|
|
| 12-15 | invalid |
|
|
|
|
A false predicate is a one-cycle semantic NOP: it retires, increments the
|
|
per-frame retired count, and advances PC by one without other side effects.
|
|
Encoding and operand legality are still checked by the loader regardless of
|
|
the predicate. Unless an opcode says otherwise, reserved operand fields must
|
|
be zero. Register fields required by an opcode are 0..15; an opcode that
|
|
produces multiple registers states the tighter `dst` limit.
|
|
|
|
Opcode classes are:
|
|
|
|
| Class | Operations |
|
|
| ---: | --- |
|
|
| 0 | `NOP`, `END`, `TRAP`, forward conditional jump/call, `RET`, loop setup/back, bounded wait |
|
|
| 1 | move/immediate, add/sub, and/or/xor, logical/arithmetic shift, compare, min/max, saturate |
|
|
| 2 | bitstream refill/peek/get/skip/align, frame sync, CRC8, CRC16 |
|
|
| 3 | Huffman symbol/pair/quad, unary scan, Rice/Rice2, sign restore |
|
|
| 4 | bounded local load/store/table read, FIFO pop/push |
|
|
| 5 | requant, stereo, IMDCT6/18, DCT32/polyphase, fixed/LPC, decorrelate, resample, PCM pack |
|
|
| 6 | input refill, output commit/stream, DMA wait, frame commit, job result, event |
|
|
| 7-15 | invalid in V1 |
|
|
|
|
Within each class, V1 opcode numbers are fixed:
|
|
|
|
| Class | Opcode allocation |
|
|
| ---: | --- |
|
|
| 0 | 0 NOP, 1 END, 2 TRAP, 3 JUMP_FWD, 4 CALL_FWD, 5 RET, 6 LOOP_SETUP, 7 LOOP_BACK, 8 WAIT |
|
|
| 1 | 0 MOV, 1 MOVI, 2 ADD, 3 SUB, 4 AND, 5 OR, 6 XOR, 7 SHL, 8 SHR, 9 SAR, 10 CMP, 11 MIN, 12 MAX, 13 SAT |
|
|
| 2 | 0 REFILL, 1 PEEK, 2 GET, 3 SKIP, 4 ALIGN, 5 FRAME_SYNC, 6 CRC8, 7 CRC16 |
|
|
| 3 | 0 HUFF_SYMBOL, 1 HUFF_PAIR, 2 HUFF_QUAD, 3 UNARY, 4 RICE4, 5 RICE5, 6 SIGN_RESTORE |
|
|
| 4 | 0 LD32, 1 ST32, 2 TABLE8, 3 TABLE16, 4 TABLE32, 5 FIFO_POP, 6 FIFO_PUSH |
|
|
| 5 | 0 REQUANT, 1 STEREO, 2 IMDCT6, 3 IMDCT18, 4 DCT32_POLY, 5 FIXED, 6 LPC, 7 DECORRELATE, 8 RESAMPLE, 9 PCM_PACK |
|
|
| 6 | 0 INPUT_REFILL, 1 OUTPUT_COMMIT, 2 OUTPUT_STREAM, 3 DMA_WAIT, 4 FRAME_COMMIT, 5 JOB_RESULT, 6 EVENT |
|
|
|
|
Unallocated opcodes in every valid class are illegal. Class-specific use of
|
|
`dst`, `src0`, `src1`, `aux`, and `immediate` is frozen below. A use not listed
|
|
is rejected rather than ignored.
|
|
|
|
#### Control and scalar semantics
|
|
|
|
| Class.op | Operands and execution |
|
|
| --- | --- |
|
|
| `0.0 NOP` | `dst/src0/src1/aux/immediate=0`; no effect. |
|
|
| `0.1 END` | all operand fields zero; when true, stalls until accepted kernel/transport/writeback work has drained, then terminates and commits the latched `JOB_RESULT`; code zero is success and a nonzero code is terminal error. If none was latched, the committed result is zero/success. A drained engine/transport fault traps instead. |
|
|
| `0.2 TRAP` | `dst/src0/src1/aux=0`; when true, traps with `immediate` as `ERROR_DETAIL`. |
|
|
| `0.3 JUMP_FWD` | V1 uses `immediate[10:0]` in 1..2047; V2 uses `immediate[11:0]` in 1..4095; higher immediate bits and other operands are zero. Target is `PC+1+delta` and must be inside the entry program range. |
|
|
| `0.4 CALL_FWD` | same target rule as `JUMP_FWD`; pushes `PC+1`, then branches; a fifth nested call traps. |
|
|
| `0.5 RET` | all operands zero and predicate must be always; pops and branches; empty stack traps. |
|
|
| `0.6 LOOP_SETUP` | predicate always; `aux[1:0]` selects an inactive loop slot, `aux[7:2]=0`, count is `R[src0][15:0]`, and other fields are zero. Count must be nonzero and no greater than the descriptor maximum; the slot records count and `PC+1` as its loop-start PC. |
|
|
| `0.7 LOOP_BACK` | predicate always; `aux[1:0]` selects the active slot. V1 uses nonzero distance `immediate[10:0]` in 1..2047; V2 uses `immediate[11:0]` in 1..4095; higher immediate bits and other operands are zero. `PC+1-distance` must equal the slot's recorded loop-start. Count greater than one is decremented and branches there; count one clears the slot and falls through. Inactive slot, underflow, or target mismatch/range failure traps. |
|
|
| `0.8 WAIT` | predicate always; `aux` source 0 DMA, 1 kernel, 2 input-FIFO ready, 3 output-FIFO ready, 4 TX-stream accepted/idle, or 5 ring writeback complete; all other operands zero. It stalls without retiring until true. Other sources are invalid. |
|
|
| `1.0 MOV` | `R[dst]=R[src0]`; `src1/aux/immediate=0`. |
|
|
| `1.1 MOVI` | `R[dst]=immediate`; `src0/src1/aux=0`. |
|
|
| `1.2 ADD` | `R[dst]=R[src0]+R[src1]` modulo 2^32; `aux/immediate=0`. |
|
|
| `1.3 SUB` | `R[dst]=R[src0]-R[src1]` modulo 2^32; `aux/immediate=0`. |
|
|
| `1.4 AND` | `R[dst]=R[src0]&R[src1]`; `aux/immediate=0`. |
|
|
| `1.5 OR` | `R[dst]=R[src0]|R[src1]`; `aux/immediate=0`. |
|
|
| `1.6 XOR` | `R[dst]=R[src0]^R[src1]`; `aux/immediate=0`. |
|
|
| `1.7 SHL` | `R[dst]=R[src0]<<R[src1][4:0]`; `aux/immediate=0`. |
|
|
| `1.8 SHR` | logical right shift by `R[src1][4:0]`; `aux/immediate=0`. |
|
|
| `1.9 SAR` | signed arithmetic right shift by `R[src1][4:0]`; `aux/immediate=0`. |
|
|
| `1.10 CMP` | sets `EQ`, signed `LT`, and unsigned `LT` from `R[src0]` versus `R[src1]`; `dst/aux/immediate=0`. |
|
|
| `1.11 MIN` | `aux[0]` selects unsigned 0 or signed 1 minimum of `R[src0]` and `R[src1]`; `aux[7:1]=0`, `immediate=0`. |
|
|
| `1.12 MAX` | `aux[0]` selects unsigned 0 or signed 1 maximum; `aux[7:1]=0`, `immediate=0`. |
|
|
| `1.13 SAT` | saturates `R[src0]` to a width selected by `aux[4:0]`: 0 means 32, or literal 8, 16, or 24; `aux[5]` selects unsigned 0 or signed 1, `aux[7:6]=0`, `src1/immediate=0`; result is zero- or sign-extended into `R[dst]`. |
|
|
|
|
`WAIT` source 0 is true when no private AXI command/beat/response is pending and
|
|
the last DMA command succeeded; a latched DMA error traps instead. Source 1 is
|
|
true when the kernel completion latch is set, source 2 when the input FIFO is
|
|
nonempty, source 3 when the output FIFO is not full, source 4 when no
|
|
microcode-issued stream payload remains unaccepted, and source 5 when no ring
|
|
writeback remains pending. Source 0 or 5 requires the relevant DMA primitive,
|
|
source 1 requires the entry's kernel primitive, sources 2/3 require local FIFO,
|
|
and source 4 requires stream output. P3 zero-mask dummy programs therefore
|
|
cannot contain `WAIT`.
|
|
|
|
#### Bitstream, entropy, and local-data semantics
|
|
|
|
| Class.op | Operands and execution |
|
|
| --- | --- |
|
|
| `2.0 REFILL` | `immediate[5:0]` is 1..32 required valid bits; stalls until present or descriptor EOF and writes the valid-bit count to `R[dst]`; EOF itself does not trap. Other operands are zero. |
|
|
| `2.1 PEEK` | width is `immediate[5:0]`, 1..32; writes the next bits to `R[dst]` without consuming. Insufficient bits at EOF trap as truncated stream. Other operands are zero. |
|
|
| `2.2 GET` | same as `PEEK`, then consumes the bits. |
|
|
| `2.3 SKIP` | width is `immediate[5:0]`, 1..32; consumes without a result; insufficient bits trap. Other operands are zero. |
|
|
| `2.4 ALIGN` | all operands zero; consumes 0..7 bits to reach the next input byte. |
|
|
| `2.5 FRAME_SYNC` | byte-aligned scan for a masked 8..16-bit value: pattern `R[src0][15:0]`, mask `R[src1][15:0]`, width `aux[4:0]`, maximum scan bytes `immediate[15:0]` 1..65535; `R[dst]` receives skipped bytes and the matching byte remains at the head. No match before limit/EOF traps. Upper aux/immediate bits are zero. |
|
|
| `2.6 CRC8` | updates accumulator `R[src0][7:0]` with byte `R[src1][7:0]` using the MSB-first polynomial `0x07`, initial/final XOR zero, and writes the eight-bit result to `R[dst]`; no reservoir side effect; `aux/immediate=0`. |
|
|
| `2.7 CRC16` | updates accumulator `R[src0][15:0]` with byte `R[src1][7:0]` using the MSB-first polynomial `0x8005`, initial/final XOR zero, and writes the 16-bit result to `R[dst]`; no reservoir side effect; `aux/immediate=0`. |
|
|
| `3.0 HUFF_SYMBOL` | canonical table starts at entry-table byte offset `R[src0]`, contains `R[src1]` entries, and has maximum code length `aux[4:0]` 1..24; consumes a code and writes its 16-bit symbol to `R[dst]`; `immediate=0`. |
|
|
| `3.1 HUFF_PAIR` | same lookup fields as `HUFF_SYMBOL`; decoded symbol nibbles are written to `R[dst]` and `R[dst+1]`, so `dst<=14`. |
|
|
| `3.2 HUFF_QUAD` | same lookup fields; four decoded one-bit values are written to `R[dst..dst+3]`, so `dst<=12`. |
|
|
| `3.3 UNARY` | `aux[0]` selects zeros-until-one 0 or ones-until-zero 1; `immediate[15:0]` is a nonzero maximum; consumes the terminator and writes the run length to `R[dst]`; source fields and upper bits are zero. |
|
|
| `3.4 RICE4` | parameter `k=R[src0][3:0]`; for `k<15`, reads zero-run quotient `q`, its one terminator, and `k` remainder bits, then maps `u=(q<<k)|remainder` to signed `(u>>1) ^ -(u&1)` in `R[dst]`. For `k=15`, reads `R[src1][5:0]` bits (1..32) as a two's-complement residual. `aux/immediate=0`. |
|
|
| `3.5 RICE5` | as `RICE4`, with `k=R[src0][4:0]`, escape value 31, and the same 1..32-bit raw width. |
|
|
| `3.6 SIGN_RESTORE` | base magnitude is `R[src0]` and linbits count is `R[src1][4:0]`; nonzero magnitude consumes linbits to form `magnitude+extra`, then one sign bit and writes its positive value for sign 0 or two's-complement negative for sign 1 to `R[dst]`. Zero magnitude consumes neither and returns zero; `aux/immediate=0`. |
|
|
| `4.0 LD32` | loads `R[dst]` from descriptor scratch base plus `R[src0]+sign_extend(immediate[15:0])`; `src1/aux` and upper immediate bits are zero. |
|
|
| `4.1 ST32` | stores `R[src1]` to the same scratch address calculation; `dst/aux` and upper immediate bits are zero. |
|
|
| `4.2 TABLE8` | loads and zero-extends table element at entry table base plus `R[src0]+R[src1]`; `aux/immediate=0`. |
|
|
| `4.3 TABLE16` | as `TABLE8`, with index `R[src1]*2`; address must be two-byte aligned. |
|
|
| `4.4 TABLE32` | as `TABLE8`, with index `R[src1]*4`; address must be four-byte aligned. |
|
|
| `4.5 FIFO_POP` | `aux=0` selects the input-byte FIFO; stalls while empty, writes a little-endian 32-bit word to `R[dst]` and literal valid-byte count 1..4 `[2:0]` plus last flag bit 8 to `R[dst+1]`; `dst<=14`, sources/immediate zero, and all other sideband bits are zero. |
|
|
| `4.6 FIFO_PUSH` | `aux=0` selects the PCM-output FIFO; stalls while full, pushes little-endian `R[src0]` with literal valid-byte count 1..4 `[2:0]` and last flag bit 8 from `R[src1]`; other sideband bits must be zero and trap before push otherwise; `dst/immediate=0`. |
|
|
|
|
A `PEEK` or `GET` result is right-aligned in the destination; the earliest bit
|
|
in the MSB-first reservoir becomes result bit `width-1`. CRC results and Huffman
|
|
symbols are zero-extended to 32 bits. A canonical Huffman table entry is one 32-bit word with symbol `[15:0]`, code
|
|
length `[20:16]` in 1..24, and `[31:21]` zero, in canonical-code order. All
|
|
entries are ordered first by increasing length and then increasing canonical
|
|
code; the first code of each length is derived by the canonical prefix rule.
|
|
An invalid prefix or exhausted bounded table traps as entropy/decode failure.
|
|
All reservoir reads use the codec-defined most-significant-bit-first order.
|
|
Local loads/stores are little-endian, must be naturally aligned, stay within
|
|
the active entry scratch range, and must not access the read-only table range.
|
|
Table reads must stay
|
|
inside the active entry table slice. Range checks include the complete access
|
|
and trap before any partial side effect.
|
|
|
|
#### Kernel and transport semantics
|
|
|
|
Only one fixed-kernel request may be outstanding. For class 5, the values in
|
|
`R[src0]`, `R[src1]`, and pre-issue `R[dst]` are input, coefficient/state, and
|
|
output byte offsets relative to the descriptor scratch base. The low 16 bits
|
|
of `immediate` are a nonzero element/block count and upper bits are zero. Issue
|
|
stalls until accepted, retires on acceptance, clears the kernel-done latch, and
|
|
completion sets that latch and replaces `R[dst]` with the produced element
|
|
count. `dst` is pending between acceptance and completion; any instruction
|
|
that would read or overwrite a pending GPR stalls. An unsuccessful kernel
|
|
completion traps at the next retirement boundary with error code 8, or code 22
|
|
for reported FIFO/local/arithmetic overflow. A dynamic range/alignment failure
|
|
traps before issue.
|
|
|
|
| Class.op | `aux` and operation |
|
|
| --- | --- |
|
|
| `5.0 REQUANT` | shift `[4:0]`, round-to-nearest bit 5, output width `[7:6]`: 0 S16, 1 S24, 2 S32, 3 invalid. |
|
|
| `5.1 STEREO` | mode `[1:0]`: independent, left-side, side-right, or mid-side; `[7:2]=0`. |
|
|
| `5.2 IMDCT6` | six-point transform blocks; `aux=0`. |
|
|
| `5.3 IMDCT18` | eighteen-point transform blocks; `aux=0`. |
|
|
| `5.4 DCT32_POLY` | 32-point/polyphase subband blocks; `aux=0`. |
|
|
| `5.5 FIXED` | predictor order `aux[2:0]` 0..4; `[7:3]=0`. |
|
|
| `5.6 LPC` | predictor order `aux[5:0]` 1..32; `[7:6]=0`. |
|
|
| `5.7 DECORRELATE` | channel mode `[1:0]` as `STEREO`; `[7:2]=0`. |
|
|
| `5.8 RESAMPLE` | coefficient profile `aux[3:0]` 0..15; `[7:4]=0`; count is input frames. |
|
|
| `5.9 PCM_PACK` | format `[1:0]`: 0 S16_LE, 1 S24_32LE, 2..3 invalid; mono-duplicate bit 2; `[7:3]=0`. |
|
|
|
|
The class-5 opcode requires its correspondingly named primitive bit, except
|
|
`STEREO` requires bit 7 and `DECORRELATE` requires bit 13. Class-2 operations
|
|
require bitstream bit 0, with CRC operations additionally requiring bit 1.
|
|
Huffman operations require bits 0 and 2; unary/Rice/sign operations require
|
|
bits 0 and 3. Local accesses require bit 4 and FIFO accesses require bit 5.
|
|
|
|
| Class.op | Operands and execution |
|
|
| --- | --- |
|
|
| `6.0 INPUT_REFILL` | scratch-relative destination byte offset `R[src0]`, nonzero requested bytes `R[src1]`, returned transferred bytes `R[dst]`; `aux/immediate=0`; uses only the active descriptor input cursor and requires primitive bit 16. |
|
|
| `6.1 OUTPUT_COMMIT` | scratch-relative source byte offset `R[src0]`, nonzero bytes `R[src1]`, returned committed bytes `R[dst]`; `aux/immediate=0`; uses only the active descriptor memory-output cursor and requires bit 17. |
|
|
| `6.2 OUTPUT_STREAM` | same operands as `OUTPUT_COMMIT`, through the active TX stream, and requires bit 18. |
|
|
| `6.3 DMA_WAIT` | all operands except `dst` zero; waits for transport quiescence, writes zero on success, and traps on the latched transport error. The entry must declare every DMA/stream primitive that may be outstanding. |
|
|
| `6.4 FRAME_COMMIT` | saturating-adds input-used `R[src0]` and output-produced `R[src1]` to job counters, saturating-increments frame count, then resets the per-frame retired counter; `dst/aux/immediate=0`; requires bit 19. |
|
|
| `6.5 JOB_RESULT` | latches terminal code `R[src0][5:0]`, detail `R[src1]`, and stage `aux[3:0]` without terminating; `R[src0][31:6]`, `dst`, `immediate`, and `aux[7:4]` must be zero, and codes 23..63 trap as an illegal runtime value; requires bit 19. |
|
|
| `6.6 EVENT` | sets sticky IRQ state selected by nonzero `immediate[10:0]`; only bits 6 and 7 may be one; all register/aux fields and upper immediate bits are zero; requires bit 20. |
|
|
|
|
Transport operations never accept a raw system address from microcode. They
|
|
advance only the active validated descriptor cursor and inherit its ACL,
|
|
4 KiB-boundary, burst, timeout, abort, and first-error rules. At most one
|
|
microcode read command and one write/stream command may be outstanding. An
|
|
input/output opcode stalls until its command is admitted, retires on admission,
|
|
marks `dst` pending, and writes the completed byte count on successful
|
|
completion. A read or overwrite of that pending GPR stalls. `DMA_WAIT` and
|
|
`FRAME_COMMIT` stall until every applicable pending command has completed; a
|
|
latched failure traps instead. All these stalls count toward the no-retirement
|
|
watchdog.
|
|
|
|
#### Control-flow, watchdog, and trap rules
|
|
|
|
Only `LOOP_BACK` may branch backward. The loader proves all direct targets,
|
|
fall-throughs, returns, and loop-back targets remain inside the entry's
|
|
inclusive program range; call depth never exceeds four; each loop slot has one
|
|
setup and one matching back edge; loop intervals are disjoint or properly
|
|
nested rather than crossing; and every reachable path reaches `END` or `TRAP`.
|
|
Runtime rechecks dynamic return, loop, local, table, and transport ranges before
|
|
side effects.
|
|
|
|
The no-retirement counter clears on entry launch and each retired instruction,
|
|
increments once per running cycle with no retirement, and traps after exactly
|
|
`SEQUENCER_TIMEOUT` consecutive such cycles. A legal timeout value is nonzero.
|
|
The per-frame counter starts at zero and counts every retired instruction,
|
|
including predicate-false instructions. If the next instruction would exceed
|
|
the descriptor maximum, it traps before instruction side effects; `END` may be
|
|
the last allowed retirement. `FRAME_COMMIT` resets the counter only after its
|
|
counter/result update commits. Falling through program-last PC or control-store
|
|
word 2047 for V1, or word 4095 for V2, traps. Branch/call/loop/return targets
|
|
are checked before assignment to the PC: V2 arithmetic uses at least 13 bits
|
|
to detect underflow, overflow and a target of 4096 rather than wrapping it to
|
|
zero. The width change does not permit arbitrary backward branches, increase
|
|
call depth, add loop slots, alter loop counts, or change watchdog budgets.
|
|
`END`/`TRAP` may legally occupy the final loaded word, including V2 PC 4095.
|
|
|
|
An asynchronous P2 transport error is sampled at the next retirement boundary,
|
|
then fetch and new commands stop while accepted transfers drain. Trap reason
|
|
allocations are 1 illegal encoding, 2 PC/program range, 3 call stack, 4 loop,
|
|
5 local/table range, 6 unavailable/undeclared primitive, 7 no-retirement
|
|
watchdog, 8 per-frame retirement budget, 9 engine/transport fault, and 10
|
|
explicit `TRAP`; 0 and 11..255 are reserved. A trap sets sticky
|
|
`STATUS.SEQUENCER_TRAPPED` and IRQ bit 10. IRQ bit 10 clears only by its W1C or
|
|
reset. A trap leaves a previously loaded `MC_STATUS.VALID` and `MC_LOCK` set
|
|
because the bundle itself remains loaded.
|
|
|
|
For the table below, `PC` is the trapping control-store word index (11 bits
|
|
for V1, 12 for V2). The 32-bit `trap_detail(reason)` keeps its V1 allocation:
|
|
reason `[7:0]`, **PC low 11 bits** `[18:8]`, class `[22:19]`, opcode
|
|
`[26:23]`, and `aux[4:0]` `[31:27]`. Every primary non-AXI trap sets
|
|
`ERROR_STATUS.VALID=1`, AXI response `0`, descriptor index `0`, and
|
|
`ERROR_ADDRESS=zero_extend(PC)<<3`. APUMC entry indices are not job/ring
|
|
descriptor indices and therefore never enter `ERROR_STATUS.DESCRIPTOR_INDEX`.
|
|
|
|
`ERROR_ADDRESS` always uses the full PC, including V2 bit 11: PC 2048 reports
|
|
`0x00004000` and PC 4095 reports `0x00007ff8`, including explicit reason-10
|
|
TRAP. No bit of reason/class/opcode/aux is stolen to extend `ERROR_DETAIL`.
|
|
For loader instruction diagnostics, the address remains the absolute bundle
|
|
address `MC_IMAGE_ADDRESS + instruction_offset + 8*PC`, using the full PC;
|
|
`trap_detail` there also retains the low-11-bit PC field. Reason 9 still
|
|
preserves an existing causative AXI/engine tuple; its address must not be
|
|
reinterpreted as a PC. Software uses retained SEQUENCER_STATUS for that case.
|
|
|
|
| Trap reason | `ERROR_STATUS` code | Stage | AXI response | Descriptor index | `ERROR_ADDRESS` | `ERROR_DETAIL` |
|
|
| ---: | ---: | ---: | ---: | ---: | --- | --- |
|
|
| 1 illegal encoding | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(1)` |
|
|
| 2 PC/program range | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(2)` |
|
|
| 3 call stack | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(3)` |
|
|
| 4 loop | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(4)` |
|
|
| 5 local/table range | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(5)` |
|
|
| 6 unavailable/undeclared primitive | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(6)` |
|
|
| 7 no-retirement watchdog | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(7)` |
|
|
| 8 per-frame retirement budget | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(8)` |
|
|
| 9 non-AXI engine semantic failure | 8 | 6 for reconstruction/transform; 7 for resampler/PCM | 0 | 0 | `PC<<3` | `trap_detail(9)` |
|
|
| 9 non-AXI FIFO/local/arithmetic overflow | 22 | stage of the failing engine, 6 or 7 | 0 | 0 | `PC<<3` | `trap_detail(9)` |
|
|
| 9 AXI/DMA/stream cause | unchanged causative code 15..19 | unchanged causative stage | unchanged causative value | unchanged causative value | unchanged causative address | unchanged causative detail |
|
|
| 9 without a valid causative error | 11 | 11 | 0 | 0 | `PC<<3` | `trap_detail(9)` |
|
|
| 10 explicit `TRAP` | 11 | 11 | 0 | 0 | `PC<<3` | the instruction's 32-bit immediate |
|
|
|
|
Reason 9 is secondary when an AXI/DMA/stream first-error tuple has already
|
|
been captured: it sets sequencer trap status and IRQ bit 10 but does not alter
|
|
that tuple. A reason-9 assertion without a causative error is an internal
|
|
sequencer trap and uses the fail-closed row above. If another global terminal
|
|
condition and a sequencer trap coincide, hard reset, forced resource reset,
|
|
AXI write, AXI read, DMA timeout, RX overrun, and TX underrun retain their
|
|
existing order above the trap; the trap outranks forced abort. Every applicable
|
|
sticky event still sets.
|
|
|
|
Under APB V1.0, `SEQUENCER_STATUS` bits `[31:21]` remain reserved zero. APB
|
|
V1.1 appends `PC_HIGH` at bit 21 (reset zero), with `[31:22]` reserved zero;
|
|
PC-low, class, opcode, wait, and loop-active keep their original bit positions.
|
|
The V1.1 reserved mask is `0xffc00000`, versus V1.0 `0xffe00000`. Decode the
|
|
full PC as `(status & 0x7ff) | (((status >> 21) & 1) << 11)`; legacy V1
|
|
execution has PC_HIGH zero. While running, PC, class,
|
|
opcode, wait, and loop-active are live for the current instruction. Wait is one
|
|
for any current-instruction stall, including explicit wait, pending-GPR,
|
|
kernel, DMA, FIFO, or backpressure stall. The terminal readback rules are:
|
|
|
|
| Event | `SEQUENCER_STATUS` after the event | `SEQUENCER_RETIRED` after the event |
|
|
| --- | --- | --- |
|
|
| `END`, with either a zero or nonzero latched terminal result | Retains the terminal `END` PC/class/opcode and the wait/loop-active values sampled immediately before retirement. | Retains the saturating current-frame count including the retired `END`. |
|
|
| Trap, including watchdog | Retains the trapping current-instruction PC/class/opcode and its wait/loop-active values when the trap was recognized. | Retains the count before the non-retired trapping instruction or stall. |
|
|
| Accepted abort with an active sequencer | Further retirement stops; retains the current-instruction tuple sampled when abort was accepted through terminal abort completion. | Retains the count sampled when abort was accepted. |
|
|
| Accepted abort without an active sequencer | Remains unchanged. | Remains unchanged. |
|
|
| Soft reset | Clears to zero when the reset is applied. | Clears to zero. |
|
|
| Normally drained or forced resource reset | Clears to zero when resource-reset state is applied after drain. | Clears to zero. |
|
|
| Hard/PCLK reset | Clears immediately to reset value zero. | Clears immediately to reset value zero. |
|
|
|
|
`END`, trap, and abort snapshots persist through status reads,
|
|
`ERROR_STATUS`/IRQ W1C, `CLEAR_COUNTERS`, and microcode load. The next accepted
|
|
entry launch clears `SEQUENCER_RETIRED` to zero and initializes
|
|
`SEQUENCER_STATUS` to entry PC with class/opcode/wait/loop-active zero until the
|
|
first instruction fetch updates it. `STATUS.SEQUENCER_TRAPPED` clears on that
|
|
launch or on soft/resource/hard reset; `END` and abort do not set it. The P3
|
|
verification-only launch follows the same rules and creates no public launch
|
|
mechanism.
|
|
|
|
PC_HIGH participates in the same atomic running/terminal snapshot as PC-low:
|
|
END/trap/abort retain it; accepted launch initializes it from the new entry
|
|
PC; soft/resource/hard reset clears it; IRQ/error W1C and counter clear do not
|
|
alter it. `SEQUENCER_RETIRED`, all first-error precedence, trap reasons, and
|
|
terminal retention rules are otherwise unchanged. Readers requiring a stable
|
|
PC while running read the single 32-bit status word rather than combining
|
|
separately sampled status and ERROR_ADDRESS from different events.
|
|
|
|
#### P3 loader, status, and control store
|
|
|
|
`MC_STATUS` reset is zero. `BUSY` bit 0 is live, `VALID` bit 1 is retained
|
|
state, bits 2..7 are sticky terminal validation errors, and bits 8..31 are
|
|
reserved zero. `STATUS.MICROCODE_VALID` is an exact mirror of
|
|
`MC_STATUS.VALID`. A legal load start clears `VALID`, bits 2..7, `MC_ABI`,
|
|
build ID, and `MC_ACTUAL_CRC`, then sets `BUSY`. A prior successful load has
|
|
automatically set `MC_LOCK`, so the clear-lock admission rule prevents it from
|
|
being overwritten. Busy, valid, and terminal-error states are mutually
|
|
exclusive.
|
|
|
|
The loader first validates header/ranges sufficiently to bound DMA, may then
|
|
write the private control store while the sequencer is held idle and `VALID=0`,
|
|
and publishes the new image atomically only after full validation and CRC.
|
|
Success in one PCLK edge clears `BUSY`, sets `VALID` and `MC_LOCK`, writes
|
|
`MC_ABI` from the accepted header word 1 (`0x00010000` for P3/P4/V1 or
|
|
`0x00020000` for an expanded-P5 V2 image), build ID and actual CRC,
|
|
saturating-increments
|
|
`MC_LOAD_COUNT`, and sets sticky IRQ bit 3. Load-done IRQ and count occur only
|
|
on successful publication; the count saturates at `0xffffffff`. A failed
|
|
attempt clears `BUSY`, keeps `VALID` and lock clear, does not increment the
|
|
count, does not set IRQ bit 3, and makes any partially written store
|
|
inaccessible; the next attempt overwrites it.
|
|
|
|
Load admission also requires 64-byte-aligned `MC_IMAGE_ADDRESS`, nonzero
|
|
`MC_IMAGE_SIZE`, and a non-wrapping complete source range inside the local read
|
|
ACL. Admission failure returns `PSLVERR` without setting `BUSY` or changing
|
|
loader state. Once admitted, validation-error categories are exact: header is
|
|
bad magic/ABI/header reserved/total/entry count; range is offset, alignment,
|
|
overlap, instruction-count, PC, scratch, or arithmetic range; control-flow is
|
|
instruction encoding, predicate, operand-reserved, branch/call/loop, or
|
|
termination proof; table is global/entry table layout or content, including
|
|
any nonzero P3 table field; capability is an unsupported primitive mask,
|
|
class-2..6 instruction in P3, or header/entry mask mismatch; CRC is the final
|
|
three-way CRC mismatch. A nonzero P3 scratch field is a range error.
|
|
|
|
Every non-AXI loader validation failure sets `ERROR_STATUS.VALID=1`, stage 1,
|
|
AXI response 0, descriptor index 0, and the code/address/detail tuple below,
|
|
subject to the global immutable-first-error rule. Loader diagnostics use an
|
|
absolute DMA source byte address, `MC_IMAGE_ADDRESS + bundle byte offset`.
|
|
APUMC entry indices do not use the job/ring descriptor-index field.
|
|
|
|
| Loader category | `MC_STATUS` bit | Error code | `ERROR_ADDRESS` | `ERROR_DETAIL` |
|
|
| --- | ---: | ---: | --- | --- |
|
|
| Header | 2 | 9 | Address of the first offending header word, or the aligned 32-bit word containing the first nonzero padding byte. | Observed little-endian 32-bit word at `ERROR_ADDRESS`. |
|
|
| Range | 3 | 9 | Address of the first header/entry field participating in the failed range relation. | Observed little-endian 32-bit field value. |
|
|
| Control flow | 4 | 9 | Address of the first offending 64-bit instruction: `MC_IMAGE_ADDRESS + instruction_offset + (PC<<3)`. | `trap_detail(1)` for encoding/predicate/reserved-operand failure, `trap_detail(2)` for target/fall-through/termination failure, `trap_detail(3)` for call/return proof failure, or `trap_detail(4)` for loop proof failure. |
|
|
| Table | 5 | 9 | Address of the first nonzero P3 table field: header word 5, header word 6, then entry-descriptor word 7 in entry-index order. | Observed little-endian 32-bit field value. |
|
|
| Capability | 7 | 10 | Address of header word 9, an entry word 6, or an instruction, whichever is the first offending item under the order below. | `header_mask XOR (entry0_mask OR entry1_mask OR entry2_mask)` for a mask mismatch; `observed_mask AND NOT implemented_mask` for an unsupported-mask failure; `trap_detail(6)` for a class-2..6 instruction rejected by P3. |
|
|
| CRC | 6 | 10 | Address of header word 11, `MC_IMAGE_ADDRESS+0x2c`. | `MC_ACTUAL_CRC`. |
|
|
|
|
For header, range, and table categories, “first” means lowest bundle byte
|
|
offset. For a range relation with more than one participating field, the
|
|
lowest-addressed participant owns the diagnostic. Control-flow instructions
|
|
are checked by entry index 0, 1, 2 and then increasing PC; a proof failure
|
|
without a unique instruction uses that entry's entry PC, and the lower entry
|
|
index wins a tie. For capability checking, header-mask mismatch precedes
|
|
unsupported header-mask bits; header word 9 then precedes entry word 6 in entry
|
|
order, which precedes instructions in that same entry/PC order. These locator
|
|
rules apply after the already frozen category precedence and do not change
|
|
which `MC_STATUS` bit wins.
|
|
|
|
Exactly one validation-error bit is set on failure using precedence header,
|
|
range, control-flow, table, capability, then CRC. Header/range/control-flow/
|
|
table failures use code 9; capability/CRC failures use code 10. An AXI
|
|
read/protocol failure records code 15 and sets no validation-error bit. All
|
|
failure classes set sticky first-error IRQ bit 8 under the global first-error
|
|
rules. `MC_ACTUAL_CRC` is zero on early-validation or AXI failure;
|
|
header/range failures are early. For an admitted range-safe image, the loader
|
|
continues through the complete payload before reporting control-flow, table,
|
|
capability, or CRC failure, and `MC_ACTUAL_CRC` contains the computed value,
|
|
including on CRC mismatch.
|
|
A later legal load start clears the loader error bits. Clearing `ERROR_STATUS`
|
|
or IRQ state does not clear `MC_STATUS`. Idle `CLEAR_COUNTERS` clears
|
|
`MC_LOAD_COUNT` but not valid, lock, ABI/build/CRC, or loader errors. Hardware
|
|
terminal updates win any same-cycle software clear elsewhere.
|
|
|
|
Hard/PCLK reset has highest precedence and clears all loader state, valid,
|
|
lock, ABI/build/CRC, and load count without an IRQ. Resource reset is next: if
|
|
a load is active, it blocks new DMA, drains accepted traffic, cancels the load,
|
|
clears all `MC_STATUS` bits plus lock/ABI/build/CRC, leaves the count unchanged,
|
|
suppresses load-done IRQ, and records forced lifecycle error 21 because the
|
|
accepted load was canceled. Idle-only soft reset cannot be accepted while
|
|
loader `BUSY`. A software abort accepted during a load uses the existing P2
|
|
block-new-and-drain behavior, then cancels publication, clears all `MC_STATUS`
|
|
bits plus lock/ABI/build/CRC, leaves the count unchanged, suppresses IRQ bit 3,
|
|
and sets abort-done IRQ bit 5. A successfully drained abort records no first
|
|
error; a drain fault or timeout uses the existing global error and precedence
|
|
rules. When no load is active, soft or normally drained resource reset clears
|
|
loader error bits while preserving valid, lock, ABI/build/CRC, and load count.
|
|
Terminal precedence is hard reset, resource reset, accepted abort, load
|
|
failure, then load success.
|
|
|
|
The P3/P4 control store is exactly 2048x64 (16 KiB), with the mapping below;
|
|
expanded P5 uses the separately frozen 4096x64 mapping. Both have synchronous
|
|
one-PCLK-cycle sequencer fetches, no architecturally visible reset contents,
|
|
and are fetchable only when valid. With `HAVE_SRAM_MACRO=YES`, the P3/P4 store
|
|
is implemented as four
|
|
`tc_sram_1024x32` instances: two depth banks by low/high 32-bit halves; loader
|
|
writes the halves and sequencer fetches the combined word, with mutually
|
|
exclusive loader/fetch ownership. If a selected PDK advertises the macro but
|
|
cannot elaborate that mapping, elaboration must fail.
|
|
|
|
For P3/P4 with `HAVE_SRAM_MACRO=NO`, including the supported ICS55 profile,
|
|
`apu_control_store` selects a portable inferred synchronous
|
|
`logic [63:0] mem [0:2047]` implementation with identical admission, latency,
|
|
byte/word ordering, and loader/fetch exclusion. It must not instantiate an
|
|
unconnected macro wrapper. This path is functional and synthesis-compatibility
|
|
evidence only; it is not an SRAM-macro, PPA, or tapeout claim.
|
|
|
|
Expanded P5 uses eight `tc_sram_1024x32` instances: four depth banks selected
|
|
by word-address `[11:10]`, each with low/high 32-bit halves, and row `[9:0]`.
|
|
Both halves form one 64-bit control word; loader writes, loader verification
|
|
reads, and sequencer fetch retain the same exclusive ownership and one-cycle
|
|
synchronous read behavior. The selected bank is registered with each read so
|
|
the 2047/2048 boundary cannot return the preceding bank's data. The no-macro
|
|
path is `logic [63:0] mem [0:4095]` with identical word ordering and latency.
|
|
Memory contents need not reset. Header version, loaded instruction count,
|
|
valid/lock state, and entry bounds gate every fetch: an accepted V1 image
|
|
cannot access the upper half or stale words from an earlier image.
|
|
|
|
Every loader/scanner/sequencer/fetch/return/loop PC path and saved verifier
|
|
state must carry 12 bits on expanded P5. An instruction count or end sentinel
|
|
must represent 4096 without truncation (at least 13 bits); the payload length
|
|
must represent 32768 instruction bytes. Loader proof storage scales from 2048
|
|
to 4096 pending path records for V2, retaining the V1 limit for V1 validation;
|
|
the offline verifier's maximum-instruction-count-times-64 bound becomes 262144 for
|
|
V2 versus 131072 for V1. Exceeding a proof bound remains a control-flow loader
|
|
failure, never a reason to skip paths. Internal proof-record layouts are not
|
|
APUMC fields, but all saved PCs must round-trip bit 11. Proof workspace is
|
|
implementation overhead and must be reported separately from the advertised
|
|
control/data capacities.
|
|
|
|
No local-data partition, primitive latency, PCLK frequency, reset ownership,
|
|
CDC/RDC crossing, DMA interface, or atomic table/control-store publication
|
|
rule changes. `MC_LOAD_COUNT` and loader IRQ count one complete publication,
|
|
not a bank or halfword. A late CRC/range/proof failure or an abort after an
|
|
upper-bank write still publishes neither code nor tables. Existing soft/
|
|
resource-reset lock retention and hard-reset invalidation apply to all banks.
|
|
|
|
`apu-mcasm` is the single assembler/verifier and produces the binary, symbols,
|
|
control-flow/loop report, primitive manifest, deterministic trace input, and
|
|
canonical ABI-input manifest. A separate Python interpreter executes the exact
|
|
enabled ISA for BAM and microcode/RTL differential tests. In P3 both tools
|
|
execute class 0/1 and reject class 2..6 under the P3 target capabilities; later
|
|
phases extend execution without changing these encodings. No partial tool-table
|
|
fingerprint is exposed as the public `ABI_DIGEST`, which remains zero through
|
|
P7. Neither tool accepts C, ELF, RV32, dynamic linking, or runtime code
|
|
generation.
|
|
|
|
For the capacity migration, `--target p3` and `--target p4` continue to emit
|
|
APUMC V1 and enforce 2048 words. `--target p5` emits APUMC V2 by default and
|
|
enforces 4096 words. The assembler adds an explicit `--mc-abi 1.0` or
|
|
`--mc-abi 2.0` selector; p3/p4 with 2.0 is rejected. `--target p5 --mc-abi 1.0`
|
|
is the retained legacy P5 build path, including its 2048-word rejection. Parser
|
|
and interpreter select the exact PC/operand limits from header word 1, then
|
|
check the requested target's allowed primitives. Python helpers must take the
|
|
version explicitly or derive it from this target default; no global widening
|
|
may silently relax V1 checks.
|
|
|
|
All generated reports record APB compatibility, APUMC version, actual/maximum
|
|
instruction words, byte size, free words, entry ranges, branch-delta maxima,
|
|
source/coefficient hashes, bundle SHA-256 and CRC, and proof high-water. The
|
|
canonical ABI manifest includes both descriptor/operand variants and the
|
|
additive PC_HIGH field. RTL/C definitions remain independently handwritten and
|
|
parity-tested; no generator is introduced. A source binary is rebuilt with the
|
|
selected version, not patched in place; header/size/CRC/build-ID provenance
|
|
must correspond to the exact resulting bytes. Existing legacy fixture bytes
|
|
remain fixed.
|
|
|
|
#### P4 primitive and local-SRAM profile
|
|
|
|
P4 implements primitive-mask bits 0..15, so its implemented primitive mask is
|
|
exactly `0x0000ffff`. It admits classes 0..5 and rejects class 6 and classes
|
|
7..15 at load time. Within class 0, `WAIT` sources 1 (kernel), 2 (input FIFO),
|
|
and 3 (output FIFO) are admitted; sources 0, 4, and 5 remain unavailable.
|
|
Primitive bits 16..20, every class-6 transport opcode, and public
|
|
transport-driven entry launch remain deferred. Each entry mask may be any
|
|
subset of `0x0000ffff`, but every admitted instruction must have all of its
|
|
required bits in that entry mask and the header mask remains the exact OR of
|
|
the three entry masks.
|
|
|
|
The assembler, parser, reference interpreter, RTL package, and handwritten C
|
|
mirror expose a separate P4 target with this mask and class admission. The P3
|
|
target remains mask zero/class 0..1 and is not widened retroactively. P4 adds
|
|
no opcode, predicate, primitive-bit number, descriptor field, or APUMC header
|
|
field.
|
|
|
|
P4 reports `CAPABILITY0=0x00000198` and `CAPABILITY1=0x01827010` as defined in
|
|
the register table. Format bits, streams, and KWS stay zero; `ABI_DIGEST` stays
|
|
zero. Consequently `START_DIRECT`, `RING_DOORBELL`, and `STREAM_ROUTE` value 1
|
|
remain fail-closed. P4 exercises primitive programs only through the
|
|
verification-only launch and data-injection path, which adds no public command,
|
|
operation, address, interrupt, or route.
|
|
|
|
The P4 112 KiB local-data address space is byte addressed and fixed:
|
|
|
|
| Local byte range | Size | P4 ownership and access |
|
|
| --- | ---: | --- |
|
|
| `0x00000..0x05fff` | 24 KiB | Active-bundle table followed by per-entry codec scratch. |
|
|
| `0x06000..0x07fff` | 8 KiB | Input staging, internal and verification-only until class 6 is enabled. |
|
|
| `0x08000..0x09fff` | 8 KiB | Output staging, internal and verification-only until class 6 is enabled. |
|
|
| `0x0a000..0x19fff` | 64 KiB | Reserved for P7 KWS; inaccessible in P4. |
|
|
| `0x1a000..0x1bfff` | 8 KiB | Primitive scoreboard, FIFO metadata, and bounded internal result state; not microcode addressable. |
|
|
|
|
Let `T` be header word 6, the table-payload byte count. P4 requires
|
|
`0<=T<=0x6000` and four-byte alignment, and copies
|
|
`bundle[header_word5+i]` exactly to local byte address `i` for `0<=i<T`.
|
|
Entry table slices may overlap because they are read-only, but each must be
|
|
wholly inside `[0,T)`. Each nonempty entry
|
|
scratch range must be wholly inside `[T,0x6000)`, must not wrap, and must not
|
|
overlap its table slice; scratch ranges belonging to different entries may
|
|
overlap because only one codec entry can execute. Header word 10 remains the
|
|
greatest declared scratch end and must be at most `0x6000`. A zero-table,
|
|
zero-scratch P3-compatible bundle remains legal in P4.
|
|
|
|
For P4 load diagnostics, `T` or entry-table-slice failure sets
|
|
`MC_STATUS.TABLE_ERROR`, code 9/stage 1, and locates header word 6 or the first
|
|
failing entry word 7. Scratch/base/end/header-word-10 failure sets
|
|
`MC_STATUS.RANGE_ERROR`, code 9/stage 1, and locates the first participating
|
|
field. A mask bit above 15, class-6 instruction, or unavailable `WAIT` source
|
|
sets `MC_STATUS.CAPABILITY_ERROR`, code 10/stage 1, using the already frozen
|
|
mask/instruction locator and detail. Classes 7..15 remain illegal V1 encodings
|
|
and use `MC_STATUS.CONTROL_FLOW_ERROR`. All are non-AXI loader tuples with
|
|
response/index zero and retain the existing category precedence.
|
|
|
|
The loader owns the local-data port while loading and writes only `[0,T)`.
|
|
Control-store words and table bytes are a single publication unit: both remain
|
|
inaccessible while `MC_STATUS.VALID=0`, and the existing successful-load edge
|
|
publishes both before setting lock/IRQ/count. Header, descriptor, instruction,
|
|
table, or CRC failure; load abort; hard reset; or forced resource reset during
|
|
load leaves both unpublished. Physical SRAM contents need not be cleared.
|
|
After successful publication, the table is read-only and survives sequencer
|
|
trap, job abort, soft reset, and normally drained resource reset exactly with
|
|
the locked control store. Only hard reset invalidates that retained bundle.
|
|
|
|
Scratch, staging, FIFO, and internal-result contents have no architectural
|
|
reset value. Each accepted entry launch starts a new mutable-data epoch: its
|
|
scratch range, both staging ranges, both primitive FIFOs, and internal result
|
|
state are logically invalid until written in that epoch. A read of an invalid
|
|
word traps with reason 5 before data is consumed; a successful `ST32`, injector
|
|
write, or kernel write marks only the written SRAM words valid, while FIFO
|
|
push marks only its new entry valid. Abort and soft, resource, or hard reset
|
|
invalidate all mutable epochs and flush both FIFOs. This may use validity
|
|
metadata rather than physically clearing SRAM, but stale
|
|
bits must never affect a result or become externally visible. The P4
|
|
verification-only injector may initialize scratch/FIFO data and validity for a
|
|
test launch; it is excluded from product filelists and public ABI.
|
|
|
|
`apu_local_sram` presents one active codec-side 32-bit, byte-write-enabled port
|
|
with a one-PCLK-cycle synchronous read. With `HAVE_SRAM_MACRO=YES`, local
|
|
address bits select 28 existing `tc_sram_1024x32` instances: banks 0..9 are
|
|
codec table/scratch/staging, banks 10..25 are the disabled P4 KWS partition,
|
|
and banks 26..27 are internal common/result state. With
|
|
`HAVE_SRAM_MACRO=NO`, it selects an inferred synchronous
|
|
`logic [31:0] mem [0:28671]` implementation with identical ordering, latency,
|
|
and byte masks; it must not instantiate an unavailable macro wrapper. Loader
|
|
access is exclusive. Outside loading, the one outstanding fixed kernel owns
|
|
the SRAM port until completion; otherwise class-4 sequencer access owns it.
|
|
This makes arbitration bounded and prevents a scalar/local instruction from
|
|
perturbing an accepted kernel's latency. The inferred path is compatibility
|
|
evidence, not SRAM-macro, PPA, or tapeout evidence. P7 may enable a separate
|
|
KWS client on banks 10..25 without sharing codec banks or changing this P4
|
|
address/latency contract; common-bank contention remains governed by its later
|
|
phase.
|
|
|
|
P4 implements two 64-entry, 41-bit primitive FIFOs using the existing Common
|
|
`stream_fifo`: payload is data `[31:0]`, valid-byte count `[34:32]`, reserved
|
|
`[39:35]=0`, and last `[40]`. They implement class-4 `FIFO_POP/PUSH` and remain
|
|
separate from the already frozen P2 stream-router FIFOs. They run in PCLK, add
|
|
no CDC/RDC boundary, and have only the verification producer/consumer in P4;
|
|
class 6 later connects production transport.
|
|
|
|
##### P4 bit-accurate numerical contract
|
|
|
|
Scratch samples are little-endian signed two's-complement 32-bit integers.
|
|
Fractional coefficients are signed Q2.30 words. A signed multiply produces the
|
|
exact 64-bit product; a dot product accumulates in signed 72 bits. Exceeding
|
|
the signed 72-bit range traps as code 22 before the affected output is made
|
|
valid. `RNE(x,s)` divides signed integer `x` by `2^s` and rounds the magnitude
|
|
to nearest with an exact half going to an even quotient, then restores the
|
|
sign; `RNE(x,0)=x`. An unrounded right shift is a two's-complement arithmetic
|
|
shift, rounding toward negative infinity. `SATb(x)` clamps to
|
|
`[-2^(b-1),2^(b-1)-1]`. All formulas below use these operations and contain no
|
|
floating-point or implementation-dependent intermediate.
|
|
|
|
`R[src1]` points to an opcode-specific parameter block in entry scratch. A
|
|
32-bit reference word in such a block uses bit 31 as table select: zero means
|
|
scratch-relative byte offset `[16:0]` with `[30:17]=0`, and one means
|
|
entry-table-relative byte offset `[15:0]` with `[30:16]=0`. References are
|
|
four-byte aligned, the complete referenced range is checked before issue, and
|
|
table-selected ranges are read-only. State and history references must select
|
|
scratch; input/output array references must also select scratch. Coefficient
|
|
and scale references may select table or scratch. Coefficients are therefore
|
|
explicit operands rather than hidden RTL constants. Static coefficient banks
|
|
originate in CRC-covered APUMC data; dynamic scales or predictors may be
|
|
written to scratch by microcode. Hardware, assembler, interpreter, and BAM
|
|
consume identical words. Codec-specific static values are selected with the
|
|
P5 bundles, or a future explicitly reactivated P6 bundle, without changing
|
|
the P4 arithmetic contract.
|
|
|
|
For the class-5 table, `N=immediate[15:0]`, `P` is the transform or predictor
|
|
order defined by the opcode, and the pre-issue value of `R[dst]` is the
|
|
scratch-relative output base:
|
|
|
|
| Opcode | Parameter block and exact output |
|
|
| --- | --- |
|
|
| `REQUANT` | Word 0 references `N` Q2.30 scales. For element `i`, `product=input[i]*scale[i]`; aux bit 5 selects `RNE(product,30+shift)` or arithmetic shift by `30+shift`, where shift is aux `[4:0]`. Apply `SAT16`, `SAT24`, or `SAT32` from aux `[7:6]`, sign-extend to 32 bits, and write `N` outputs. |
|
|
| `STEREO` | Word 0 references the second `N`-sample input. Inputs are planar `A` and `B`; output is planar left then right. Modes produce `(A,B)`, `(A,A-B)`, `(A+B,B)`, or `mid=(A*2)+(B&1); ((mid+B)>>1,(mid-B)>>1)` for independent, left-side, side-right, or mid-side. Signed 64-bit intermediates are clamped with `SAT32`; result count is `2N`. |
|
|
| `IMDCT6` / `IMDCT18` | Word 0 references a row-major Q2.30 matrix `C[2P][P]`, with `P=6` or 18. For every block and `0<=n<2P`, output `SAT32(RNE(sum(k=0..P-1,input[k]*C[n][k]),30))`. There is no hidden scale; results contain `12N` or `36N` samples. |
|
|
| `DCT32_POLY` | Words 0/1 reference Q2.30 `C[32][32]` and `W[16][32]`; word 2 references signed-32 `history[16][32]`; word 3 holds phase `[3:0]` and has other bits zero. Compute `v[n]=SAT32(RNE(sum(k=0..31,input[k]*C[n][k]),30))`, replace `history[phase][n]`, then output `SAT32(RNE(sum(m=0..15,history[(phase-m)&15][j]*W[m][j]),30))` for `j=0..31`; advance phase modulo 16 and write it back to word 3 per block. Result count is `32N`. |
|
|
| `FIXED` | Word 0 references a newest-first signed-32 history with `P=aux[2:0]` in 0..4. Predictor is 0, `s1`, `2s1-s2`, `3s1-3s2+s3`, or `4s1-6s2+4s3-s4`. Add each signed-32 residual, require the exact signed-64 result to fit signed 32 bits, write it, and update history. Result count is `N`. |
|
|
| `LPC` | Word 0 references `P=aux[5:0]` signed-32 coefficients, word 1 references newest-first signed-32 history, and word 2 is a sign-extended predictor shift in -31..31. Accumulate `sum(j=0..P-1,coeff[j]*history[j])` in signed 72 bits; arithmetic-shift right for nonnegative shift or exact-shift left for negative shift, add the residual, require signed-32 range, write, and update history. Result count is `N`. |
|
|
| `DECORRELATE` | Word 0 references the second planar input and uses the four `STEREO` equations, but any result outside signed 32 bits traps rather than saturates. Result count is `2N`. |
|
|
| `RESAMPLE` | Words 0/1/2 reference the full-band, two-thirds-band, and half-band coefficient banks; each bank is Q2.30 `H[32][16]`. Mutable words 3/4 hold 64-bit `next_output_num`, words 5/6 hold 64-bit `input_base_index`, and word 7 is channel count 1 or 2. The exact rational/phase/filter rules below produce interleaved signed-32 frames and update both 64-bit state values. Result count is produced frames. |
|
|
| `PCM_PACK` | Word 0 is signed Q2.30 gain and word 1 is input channels 1 or 2; `N` counts input frames. For each input sample use `RNE(sample*gain,30)`, then `SAT16` or `SAT24`. S16_LE emits two little-endian bytes; S24_32LE emits the sign-extended 24-bit result in a four-byte little-endian word. Mono-duplicate is legal only for one input channel and emits two equal channels. Result count is emitted bytes. |
|
|
|
|
The 16 `RESAMPLE` profile ratios are output/input in lowest terms:
|
|
|
|
| Profile | Ratio `L/M` | Coefficient bank | Profile | Ratio `L/M` | Coefficient bank |
|
|
| ---: | ---: | --- | ---: | ---: | --- |
|
|
| 0 | `1/1` exact bypass | none | 8 | `6/1` | full-band |
|
|
| 1 | `1/2` | half-band | 9 | `8/1` | full-band |
|
|
| 2 | `80/147` | half-band | 10 | `12/1` | full-band |
|
|
| 3 | `160/147` | full-band | 11 | `320/147` | full-band |
|
|
| 4 | `3/2` | full-band | 12 | `640/147` | full-band |
|
|
| 5 | `2/1` | full-band | 13 | `1280/147` | full-band |
|
|
| 6 | `3/1` | full-band | 14 | `2/3` | two-thirds-band |
|
|
| 7 | `4/1` | full-band | 15 | `4/3` | full-band |
|
|
|
|
Profile 0 copies exactly `N` interleaved frames, adds `N` to both
|
|
`next_output_num` and `input_base_index`, and reports `N` frames. For profiles
|
|
1..15, source frame indices are absolute. At invocation, `R[src0]` addresses
|
|
frame `input_base_index` and its buffer must also contain seven valid history
|
|
frames before it and nine valid look-ahead frames after the `N` frames. While
|
|
`floor(next_output_num/L)<input_base_index+N`, let
|
|
`i=floor(next_output_num/L)` and remainder `r=next_output_num mod L`. Phase is
|
|
the nearest-even integer to `32*r/L`; phase 32 is represented as phase 0 with
|
|
`i` incremented. For every channel, output
|
|
`SAT32(RNE(sum(t=0..15,sample[i+t-7]*H[phase][t]),30))`, then add `M` to
|
|
`next_output_num`. After the invocation add `N` to `input_base_index`.
|
|
Both state values start at zero; the first seven history frames and final nine
|
|
look-ahead frames are explicit valid zeros supplied by microcode. A profile
|
|
cannot change within a job; a new job reinitializes both state values. The three
|
|
coefficient banks are APUMC data and have no hidden normalization or scale;
|
|
the active P5 bundle provides its codec-quality values while P4 BAM
|
|
compares the exact supplied Q2.30 words.
|
|
|
|
##### P4 latency and fault bounds
|
|
|
|
Latency is counted in PCLK cycles from accepted execute/issue through retire or
|
|
kernel-done, inclusive. The bounds assume required local words are valid and a
|
|
required FIFO word/space is present. Time waiting for external FIFO data or
|
|
space is instead covered by `SEQUENCER_TIMEOUT`. `B` is scanned bytes, `E` is
|
|
Huffman entries (1..4096), `q` is a Rice quotient limited to 65535, `k` is the
|
|
Rice parameter/raw width, `maximum_run` is the `UNARY` immediate, `S` is
|
|
emitted PCM samples, and `O`/`C` are resampler output frames/channels.
|
|
|
|
An entropy request with `E` outside 1..4096, a unary run beyond its declared
|
|
maximum, or a Rice quotient above 65535 traps as invalid entropy before a
|
|
result is written. EOF before the required entropy bits is a truncated-stream
|
|
fault rather than a latency-bound exception.
|
|
|
|
| Primitive/opcode | Maximum PCLK cycles |
|
|
| --- | ---: |
|
|
| `REFILL` | 3 |
|
|
| `PEEK`, `GET`, `SKIP`, `ALIGN`, `CRC8`, `CRC16` | 1 |
|
|
| `FRAME_SYNC` | `2+2B` |
|
|
| `HUFF_SYMBOL`, `HUFF_PAIR`, `HUFF_QUAD` | `2+24+E` |
|
|
| `UNARY` | `2+maximum_run` |
|
|
| `RICE4`, `RICE5` | `4+q+k`; escape path `4+raw_width` |
|
|
| `SIGN_RESTORE` | `3+linbits` |
|
|
| `LD32`, `TABLE8`, `TABLE16`, `TABLE32` | 2 |
|
|
| `ST32`, ready `FIFO_POP`, ready `FIFO_PUSH` | 1 |
|
|
| `REQUANT` | `8+4N` |
|
|
| `STEREO`, `DECORRELATE` | `8+4N` |
|
|
| `IMDCT6` | `8+94N` |
|
|
| `IMDCT18` | `8+706N` |
|
|
| `DCT32_POLY` | `8+2304N` |
|
|
| `FIXED` | `8+(P+4)N` |
|
|
| `LPC` | `8+(2P+5)N` |
|
|
| `RESAMPLE` profile 0 | `8+2NC` |
|
|
| `RESAMPLE` profiles 1..15 | `8+2NC+36OC` |
|
|
| `PCM_PACK` | `8+5S` |
|
|
|
|
`N`, output size, every referenced array, and each latency expression must fit
|
|
32-bit unsigned arithmetic and the active scratch range before issue. A bound
|
|
violation traps before a write. A conforming implementation may complete
|
|
earlier but never later under the stated ready-data conditions. The interpreter
|
|
and RTL expose identical completion cycles in the P4 latency corpus.
|
|
|
|
P4 extends reason-9 causative errors without changing P3 behavior: frame-sync
|
|
failure captures code 4/stage 4; required-bit exhaustion captures code 5 with
|
|
stage 4 for class 2 or stage 5 for class 3; and invalid Huffman/unary/Rice
|
|
content or a frozen entropy bound violation captures code 7/stage 5. These
|
|
non-AXI tuples use response/index zero, `ERROR_ADDRESS=PC<<3`, and
|
|
`ERROR_DETAIL=trap_detail(9)` before setting the existing secondary reason-9
|
|
trap. CRC opcodes only calculate values; codec checksum policy remains in the
|
|
codec phases. Local range/validity faults use reason 5. Class-5 semantic and
|
|
overflow faults retain the already frozen code 8 or 22 and stage 6/7 mapping.
|
|
|
|
#### P5 public codec and transport profile
|
|
|
|
This section freezes P5 against the reviewed P4 interfaces present at
|
|
`57ffd03216502804f1108041184fdd6e6a328217`. It specifies the production
|
|
controller that replaces the tied-off job, FIFO, and TX-session connections;
|
|
it does not declare that controller already implemented.
|
|
|
|
| P5 discovery/admission | Exact value or rule |
|
|
| --- | --- |
|
|
| `CAPABILITY0` | `0x000001bd`: WAV 0, FLAC 2, DMA 3, ring 4, TX streams 5, sequencer 7, resampler 8. MP3 1 and KWS 6 remain zero. |
|
|
| `CAPABILITY1` | Expanded P5: `0x01827020`, 32 KiB control, 112 KiB data, two channels, 96 kHz maximum source rate. |
|
|
| Implemented primitive mask | `0x001fffff`, bits 0..20; reserved bits 21..31 remain zero. |
|
|
| ISA target | Add `p5` to the assembler/parser/interpreter and hardware capability validation. Classes 0..6 and all six existing `WAIT` sources are admitted subject to entry masks. Existing `p3` and `p4` targets retain their masks and behavior. |
|
|
| Public job | Operation 0 with format 0 WAV or 2 FLAC; one active job, direct or ring. MP3, KWS operation 1, and model load remain unavailable. |
|
|
| Stream route | TX 0/1 legal; RX only 0 legal. Bit 5 means at least one implemented stream direction, not permission for RX/KWS. RX 1 and reserved direction values return `PSLVERR`. |
|
|
| ABI identity | Expanded P5 APB V1.1, `IP_VERSION=0x00010001`; new release bundles use APUMC V2.0 / `MC_ABI=0x00020000` and legacy V1 images remain loadable. Existing APB offsets, job descriptor, 64-bit instruction positions/opcodes, and topology stay fixed. `ABI_DIGEST=0` through P7. |
|
|
|
|
Direct acceptance snapshots all job fields, requires owner/unblocked/idle,
|
|
locked valid microcode, a supported format, valid ranges and output geometry,
|
|
and no enabled active ring. Rejected direct starts cause no payload DMA and
|
|
leave result state unchanged. Ring doorbell requires an enabled valid ring,
|
|
owner/unblocked state, locked microcode, and no direct job; it does not inspect
|
|
the head format during the APB transfer. Each invalid owned descriptor,
|
|
including MP3/KWS, completes with the existing P2 error/writeback/OWN-clear
|
|
sequence. Thus an unsupported ring head cannot prevent its own rejection
|
|
writeback. Direct and ring configuration words retain their existing layouts.
|
|
Buffers and the complete 128-byte descriptor must fit the relevant ACL;
|
|
input/output and descriptor/result memory may not overlap. Shared storage must
|
|
remain immutable/non-cacheable or explicitly cache-maintained while owned.
|
|
|
|
##### Production entry context and class-6 movement
|
|
|
|
GPRs still start at zero. Before the first instruction, after the P4 mutable
|
|
epoch clear, the controller writes the following 64-byte context into the
|
|
last 64 bytes of the active entry's scratch range. This is a microprogram ABI
|
|
inside existing scratch, not a new APB register window. The P5 WAV/FLAC bundle
|
|
reserves it; kernels and transport data buffers may not overlap it. `LD32` and
|
|
`ST32` use the existing scratch-relative addressing to access it.
|
|
|
|
| Word | Value/owner |
|
|
| ---: | --- |
|
|
| 0..3 | Controller writes descriptor `CONTROL` without OWN/IOC, `INPUT_CONFIG`, `OUTPUT_CONFIG`, and `JOB_FLAGS`; microcode reads only. |
|
|
| 4 | Microcode's cumulative parsed input bytes, initially zero; monotonically increasing and at most `INPUT_LENGTH`. |
|
|
| 5 | Microcode's diagnostic byte offset from input start, initially zero; may equal `INPUT_LENGTH` for EOF. |
|
|
| 6 | Microcode's detected `SOURCE_INFO` in the existing result layout, initially zero; written after header validation and constant thereafter. |
|
|
| 7 | Microcode final-output marker, bit 0 only; initially zero. It marks the next output command as the final one and is consumed/cleared when that command is accepted. |
|
|
| 8 | Controller writes `INPUT_LENGTH`; microcode reads only. |
|
|
| 9 | Controller writes `OUTPUT_CAPACITY`; microcode reads only. |
|
|
| 10 | Controller writes current private-DMA input cursor after each refill completion; microcode reads only. |
|
|
| 11 | Controller writes completed transport output bytes after each output completion; microcode reads only. |
|
|
| 12..15 | Reserved zero. |
|
|
|
|
The controller owns transport cursors and checks context bounds when consumed.
|
|
APUMC loader validation retains all P4 table/scratch range rules. Job dispatch
|
|
additionally requires a WAV/FLAC entry with at least 64 scratch bytes; a
|
|
generic primitive-only bundle may still load but cannot run a public codec
|
|
job without this space. Only released, verified P5 microprograms define codec
|
|
semantics; load CRC/lock is not authentication of an arbitrary program.
|
|
|
|
`INPUT_REFILL` has exactly one source: the active descriptor input cursor. Its
|
|
requested count is a multiple of four in 4..256, and its scratch destination
|
|
is four-byte aligned and has space for the request. Actual bytes are
|
|
`min(request, INPUT_LENGTH-cursor)`. The controller buffers an entire request
|
|
in the P4 input staging region at `0x06000` before publishing it; on success
|
|
it copies the actual bytes to scratch, zeroes unused lanes of the final local
|
|
word, and queues the same bytes in the primitive input FIFO. Completion and
|
|
cursor increment occur once both copies have been accepted. Source bytes are
|
|
not reread or decoded by LP/HP. Zero actual bytes completes with zero without
|
|
issuing AXI; it sets the EOF state and emits no zero-byte FIFO item.
|
|
|
|
Refill admission reserves enough free FIFO entries for the entire actual
|
|
request, as well as the read-command slot, and waits for an active fixed
|
|
kernel to complete before claiming SRAM. A reservation need not wait for the
|
|
reservoir to empty. The primitive FIFO's `last` is set only on the item ending
|
|
the descriptor input, not on each 256-byte refill. Valid-byte counts remain
|
|
literal 1..4 and byte order is increasing address. `FIFO_POP` and bitstream
|
|
refill consume one shared FIFO; the microprogram must not use `FIFO_POP`
|
|
while the bitstream reservoir holds unconsumed bits. Scratch copies are for
|
|
CRC/header inspection and do not implicitly consume the reservoir.
|
|
The parser tracks available bits and schedules explicit refills before an
|
|
operation would exhaust queued input. Long unary/Rice tokens spanning refill
|
|
boundaries are decoded with bounded bit-read/refill microcode loops; issuing
|
|
an entropy primitive that stalls waiting for its own not-yet-issued refill
|
|
is forbidden in the released bundle. This needs no autonomous host refill.
|
|
|
|
`OUTPUT_COMMIT` and `OUTPUT_STREAM` both take authoritative bytes from the
|
|
specified scratch range; their byte count is 1..256 and a multiple of a
|
|
complete destination PCM sample frame. The scratch base is four-byte aligned.
|
|
They first copy those bytes into output staging at `0x08000`, then enqueue
|
|
them into the primitive output FIFO, then drain that FIFO to private AXI DMA
|
|
or to the P2 TX router respectively. Output-command admission requires this
|
|
FIFO empty. `FIFO_PUSH` remains executable for primitive programs, but an
|
|
output command with older manually pushed entries is a reason-5 contract
|
|
fault; it may not discard or substitute those entries. During transport's
|
|
FIFO ownership, manual pushes stall. SRAM and FIFO payloads are not two
|
|
alternative public output modes.
|
|
|
|
Only one read and one output command may be pending. Local SRAM ownership is
|
|
loader exclusive, then an already accepted fixed kernel, then a transport
|
|
copy, then a class-4 request; newly eligible kernel/transport/local requests
|
|
use round robin and cannot preempt an accepted operation. Each transport copy
|
|
is at most 64 words. Transport waits outside a running kernel do not change
|
|
P4's accepted-kernel latency guarantee. The DMA owner remains held until done
|
|
through the P2 channel/response drain, including ring fetch and writeback.
|
|
|
|
Output-memory cursor advances only by bytes from bursts with successful B
|
|
responses. `OUTPUT_COMMIT` returns its requested count only after all B
|
|
responses succeed. `OUTPUT_STREAM` returns only after the last word of that
|
|
command crosses the router-to-I2S handshake, not merely the primitive FIFO
|
|
or router enqueue. Source/context data cannot be modified while its command
|
|
is pending; unrelated mutable words may still be used. Existing GPR-pending,
|
|
`DMA_WAIT`, and `WAIT` semantics apply.
|
|
`WAIT 4` includes the router FIFO and unaccepted TX word; `WAIT 5` observes
|
|
ring result/OWN writeback. It is initially true before a writeback begins and
|
|
is not a prerequisite for the running entry's own future writeback.
|
|
|
|
The final-output context marker asserts `TLAST` only on the final I2S word of
|
|
the marked command. Memory output consumes the marker without an external
|
|
`TLAST`. A marked command forbids later output commands in that job. Empty
|
|
audio emits no word or `TLAST`. A nonempty successful stream job must have
|
|
exactly one final marker. The microprogram checks EOF/container end using
|
|
look-ahead before releasing the final PCM frame. There is no fabricated
|
|
`TLAST` on a previously accepted word when a job aborts or fails.
|
|
|
|
`FRAME_COMMIT` retires once per destination PCM sample frame, never once per
|
|
compressed FLAC frame or DMA command. Its source0/source1 values add logical
|
|
input-used/output-produced deltas and it increments the existing frame counter
|
|
by one. Source1 equals destination bytes per frame, including mono-to-stereo
|
|
duplication for I2S; input deltas may be zero during upsampling. Hardware
|
|
also tracks physical successful bytes independently, so commits cannot exceed
|
|
transported bytes. On normal `END`, logical output bytes/frames must equal
|
|
physical bytes/complete PCM frames; mismatch is a contract failure. Parsed
|
|
input context word 4 supplies final input-used, including header/trailing
|
|
chunks not associated with the last PCM frame, and must not be less than the
|
|
committed input-used. `FRAME_COMMIT` continues to reset the per-frame retired
|
|
watchdog budget. `EVENT` retains IRQ bits 6/7 semantics; it does not replace
|
|
the router's watermark detectors.
|
|
|
|
On failure or abort, results report parsed input context word 4, the physical
|
|
successful output prefix, and complete PCM frames in that prefix. A burst
|
|
with failing B is excluded from that prefix even though some destination
|
|
bytes may physically have changed. No rollback of AXI or accepted audio is
|
|
promised. Successful DMA byte counters count each wire transfer once;
|
|
sequencer commits and local staging copies do not double-count them. Loader
|
|
and ring traffic retain their existing counter attribution. `JOB_CYCLES`
|
|
saturates from job acceptance through terminal drain/result construction;
|
|
ring finish timestamp precedes OWN clear, as in the P2 scheduler.
|
|
|
|
Abort/resource block-new stops instruction retirement and new transfers.
|
|
An output command is not issued to AXI until its complete payload is in
|
|
staging; its accepted W/B work drains even if mutable epochs are invalidated.
|
|
A presented unaccepted stream word remains stable and drains, as do already
|
|
queued router words. Unpresented staging/primitive-FIFO data may be discarded
|
|
after the command's outstanding obligations are tracked. Resource reset is
|
|
applied only after drain; hard/PCLK reset retains the P2 warm-flush rules.
|
|
If the sink/fabric never responds, idle/abort-done must not falsely assert.
|
|
AXI response/protocol and DMA-timeout precedence remains unchanged. New
|
|
codec errors enter below the existing AXI/DMA/xrun causes, below a sequencer
|
|
trap, and above forced abort on the same cycle; otherwise the first captured
|
|
error remains immutable. Empty/full primitive FIFOs alone are backpressure,
|
|
not audio xrun. The P2 router's real I2S xrun events retain codes 18/19.
|
|
On successful END, any prefetched-but-unparsed input tail is discarded after
|
|
all read responses drain; it is not counted as parsed input and cannot carry
|
|
into the next entry epoch. This includes relaxed trailing bytes.
|
|
|
|
##### P5 WAV and native-FLAC file profiles
|
|
|
|
Files are finite, contiguous DMA inputs of at most `0x7fffffff` bytes. These
|
|
limits are the P5 acceptance subset; a valid file outside them is unsupported,
|
|
not malformed. WAV syntax uses the Microsoft
|
|
[RIFF rules](https://learn.microsoft.com/en-us/windows/win32/xaudio2/resource-interchange-file-format--riff-)
|
|
and [PCM/extensible format definitions](https://learn.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible).
|
|
Native FLAC syntax is [RFC 9639](https://datatracker.ietf.org/doc/html/rfc9639);
|
|
the bounded profile and error policy below override any freedom it gives a
|
|
decoder. LP/HP neither parse these files for the APU nor provide decoded PCM.
|
|
|
|
| WAV property | P5 rule |
|
|
| --- | --- |
|
|
| Container | Exactly little-endian `RIFF`, 32-bit size, `WAVE`; no RF64, RIFX, WAVE64, compressed WAVE, or leading tags. Compute `riff_end=8+size` with checked wide arithmetic. It must be at least 12 and not exceed input length. |
|
|
| Required chunks | Exactly one `fmt ` before exactly one `data`. Chunk headers are eight bytes; every chunk payload and its odd-size pad must fit `riff_end`. `data` before `fmt `, duplicate required chunks, overlapping/wrapped sizes, or a partial final chunk header fail. |
|
|
| PCM `fmt ` | Tag 1; length 16, or length 18 with `cbSize=0`. Channels 1/2, integer rate 8000..96000 Hz, bits 8/16/24/32. `blockAlign=channels*(bits/8)` and `avgBytesPerSec=rate*blockAlign` must match exactly. |
|
|
| Extensible `fmt ` | Tag `0xfffe`; length 40, `cbSize=22`, PCM subtype GUID `00000001-0000-0010-8000-00aa00389b71`. Valid bits must equal container bits, both from 8/16/24/32. Mono channel mask is 0 or `0x4`; stereo is 0 or `0x3`. Float subtype, other masks, and padded-valid-bit variants are unsupported. |
|
|
| Unknown chunks | Skip bounded payloads by consuming input; do not interpret `LIST`, `JUNK`, `fact`, `bext`, or embedded metadata. At most 1024 chunks and 1 MiB total skipped payload plus padding, including chunks after `data`. |
|
|
| Alignment/padding | Odd chunk lengths have exactly one pad byte; strict mode requires zero, relaxed mode accepts any value. Missing required pad is truncated input. `data` size must be a multiple of blockAlign, including a valid zero-length data chunk. |
|
|
| End | Parse remaining chunks through `riff_end`. Strict requires `riff_end==INPUT_LENGTH`; relaxed ignores bytes beyond riff_end and sets warning bit 1. `RESULT_INPUT_USED=riff_end` on success. |
|
|
| Sample representation | Eight-bit samples are unsigned with bias 128; 16/24/32-bit samples are signed little-endian two's complement. No host conversion or dither. |
|
|
|
|
| Native FLAC property | P5 rule |
|
|
| --- | --- |
|
|
| Signature/metadata | `fLaC` at byte zero; first metadata block is exactly one 34-byte STREAMINFO. At most 128 metadata blocks and 1 MiB total metadata payload. A terminating last-metadata flag is mandatory. Types 1..6 are bounded opaque skips; reserved types 7..126 are unsupported; type 127 and duplicate STREAMINFO are malformed. |
|
|
| Geometry | 1/2 channels, 16/24 bits/sample, rate 8000..96000 Hz. Nonzero total-samples is a required exact end count; zero means unknown until EOF. Nonzero min/max frame-byte hints must be ordered; STREAMINFO min/max block sizes must be legal and contain each nonfinal frame's block size. |
|
|
| Workspace bound | Maximum coded block is 4096 samples for mono or 2048 for stereo. Maximum encoded frame is 65536 bytes. A larger advertised maximum or frame/block is unsupported before PCM from that frame is released. This explicitly excludes common 4096-sample stereo files in P5; broader block support needs a later memory/streaming design. |
|
|
| Frame header | Accept fixed- and variable-blocking strategies, all RFC block-size codes 1..15 and sample-rate codes 0..14 when the decoded values fit the profile. Code 0 block size, code 15 sample rate, reserved bits/bit-depth codes, and invalid UTF-8-style frame/sample numbers fail. A file keeps one blocking strategy. Numbers start at zero and advance contiguously; final short blocks, including 1..15 samples, are allowed. |
|
|
| Property changes | Rate, bit depth, and channel count must match STREAMINFO and stay constant. Channel assignment may vary per frame among independent/left-side/side-right/mid-side; mono uses independent only. All expected nonzero `INPUT_CONFIG` fields must match the detected source. |
|
|
| Subframes | Constant, verbatim, fixed order 0..4, LPC order 1..32; predictor order is no larger than block size. LPC coefficient precision 1..15 and signed shift -16..15 are accepted. Restore predictor warmups and residuals exactly; side subframes use the required extra bit. |
|
|
| Wasted bits | Accept any legal wasted-bit count leaving at least one coded bit. Restore wasted bits before stereo decorrelation and check the final nominal sample range. Invalid counts or reconstruction overflow fail. |
|
|
| Residuals | Rice and Rice2 with legal partition order 0..15, block divisibility, first-partition warmup subtraction, and exact sample count. Honor P4's quotient limit 65535; a legal larger quotient is unsupported. Escape raw width 0 represents an all-zero residual partition and is synthesized by microcode without issuing the P4 raw-width primitive; raw widths 1..31 use sign extension. |
|
|
| Integrity | Mandatory header CRC8 and frame CRC16, initialized zero with the existing P4 polynomials, in both strict modes. All subframe-to-footer pad bits must be zero. Decode and validate the full frame before releasing any of its PCM. No resynchronization, concealment, or checksum bypass. |
|
|
| MD5 | STREAMINFO MD5 is retained as metadata but not computed by P5. Zero and nonzero MD5 fields are accepted; success always sets warning bit 0, MD5 unchecked. Strict does not turn on an absent MD5 engine. External reference tests may verify MD5; APU success does not assert whole-file MD5 verification. |
|
|
| End/truncation | With a known sample count, stop at exactly that count; a final frame may not exceed it. Strict rejects trailing bytes; relaxed ignores trailing bytes and sets warning bit 1. With unknown count, only exact EOF after a valid frame is success; incomplete next headers/frames fail in either mode. Empty streams are accepted only at the metadata end with total-samples zero. |
|
|
|
|
The P5 released bundle uses at most 6144 table bytes and reserves at least
|
|
18432 scratch bytes for each supported entry, wholly within the existing
|
|
`0x00000..0x05fff` workspace. Up to 16384 scratch bytes hold one full decoded
|
|
FLAC frame; at least 2048 remain for input copies, predictor state, parameter
|
|
blocks, resampling tiles, CRC and job context. Process resampling in tiles of
|
|
at most eight source frames so expansion up to 12:1 fits that remainder.
|
|
Predictor reconstruction uses at most 64 residual samples per kernel request,
|
|
preserving history across requests. Required P5 bundles bound each kernel's
|
|
ready-data latency below the existing default `SEQUENCER_TIMEOUT=0xffff` and
|
|
prove their maximum retired count between commits (including metadata skip)
|
|
fits the entry's 24-bit budget. No artificial FRAME_COMMIT may be used to
|
|
reset a watchdog before producing an output PCM frame.
|
|
This is a release-bundle packing requirement, not a reduction of P4 loader
|
|
capacity. The staging regions and P7 KWS reservation retain their P4 addresses.
|
|
WAV processes at most 256 source PCM frames per validation block, using a
|
|
smaller tile when needed. A terminal container/metadata error can occur after
|
|
earlier valid audio has already been emitted; its prefix is retained.
|
|
For resampling across FLAC frames, retain only the bounded history and pending
|
|
end tile while decoding the next full frame into the main planar buffer; do
|
|
not allocate a second full-frame buffer or read unverified next-frame samples.
|
|
On a next-frame CRC error, pending unissued output may be discarded. Accumulate
|
|
small packed tiles until an output command can carry 256 bytes, except at
|
|
final output or remaining capacity, so I2S startup prefill can complete without
|
|
waiting on a shorter nonfinal command's sink handshake.
|
|
|
|
##### P5 PCM, rate, and completion policy
|
|
|
|
For source precision `b`, normalize signed source integer `s` to signed Q1.31
|
|
with the exact integer `s*2^(32-b)` (WAV unsigned eight-bit first subtracts
|
|
128). Stereo-to-mono is `RNE(left+right,1)` using a signed 33-bit sum in that
|
|
domain, followed by signed-32 saturation. Bit 10 in CONTROL authorizes this
|
|
reduction; it is illegal when not doing stereo-to-mono. Mono-to-stereo is exact
|
|
duplication and does not use bit 10. Output channel zero means derive from
|
|
source for memory, and two for I2S. Memory permits 1/2 output channels; I2S
|
|
requires two physical slots. To request downmixed audio on I2S, select one
|
|
logical output channel with bit 10, then duplicate it into the two slots.
|
|
|
|
CONTROL bit 11 zero requires output rate zero (derive) or exactly source
|
|
rate. With bit 11 one, rate must explicitly be 48000 or 96000 Hz and the
|
|
reduced output/source ratio must match a P4 profile, including profile 0 for
|
|
equal rates. Other ratios are unsupported; no nearest-rate choice is made.
|
|
Memory pass-through accepts every source rate in the file profile; I2S output
|
|
must resolve to 48 or 96 kHz. Its width/rate are configured through the existing
|
|
I2S HAL before submission. The APU does not write I2S registers; the driver
|
|
requires matching I2S format and stream-TX configuration and an idle central
|
|
DMA TX path before enabling APU TX route.
|
|
|
|
The shipped P5 resampler tables are three fixed 32-phase/16-tap Q2.30 banks.
|
|
Their values are uniquely defined by the following offline formula, not by
|
|
host floating-point defaults. For cutoff `c=1,2/3,1/2`, phase `p=0..31`, and
|
|
tap `t=0..15`, let `x=t-7-p/32`, `sinc(z)=sin(pi*z)/(pi*z)` with sinc(0)=1,
|
|
`w(t)=(1-cos(2*pi*(t+1/2)/16))/2`, and `a(t)=c*sinc(c*x)*w(t)`.
|
|
Round `2^30*a(t)/sum(a)` to nearest-even to obtain each coefficient; add the
|
|
integer residual `2^30-sum(coefficients)` to tap 7. Coefficient generation
|
|
must resolve rounding using increased precision/interval bounds, emit all
|
|
1536 little-endian signed words, and compare independently generated words
|
|
before shipping. The binary is covered by the APUMC CRC/build manifest. P4
|
|
arithmetic, profile mapping, phase rounding, history/look-ahead, and saturation
|
|
are unchanged. Identity bypass is exact; nonidentity conversion is not a
|
|
lossless-output claim.
|
|
|
|
After downmix/resampling, convert Q1.31 to signed output precision by
|
|
arithmetic right shift 16 for S16 or 8 for S24, then saturation. There is no
|
|
dither or implicit gain. Before using `PCM_PACK`, microcode has already made
|
|
that shift and sets packer gain to `0x40000000`. Thus native 16/24-bit FLAC
|
|
pass-through at matching precision/rate/channels is bit-exact, and changing
|
|
precision has a deterministic amplitude-preserving result. Stereo S16 uses
|
|
one full 32-bit I2S word per frame; stereo S24 uses two sign-extended words.
|
|
`TKEEP=TSTRB=0xf`; all other I2S sidebands are zero except final `TLAST`.
|
|
|
|
Output capacity is enforced before issuing each command, with checked
|
|
`cursor+bytes` arithmetic; only whole destination PCM frames may be issued.
|
|
Memory output requires nonzero capacity and four-byte-aligned address. Stream
|
|
output uses address/capacity zero. In either mode total output bytes must fit
|
|
32 bits; detect a prospective overflow as code 22/stage 8 before issue rather
|
|
than allowing a cursor to wrap.
|
|
If the entire next command cannot fit, issue no byte from it and terminate
|
|
with code 8/capacity detail. The released microprogram must shorten a tile to
|
|
the remaining whole-frame capacity first, then report exhaustion if more
|
|
audio remains. A known too-small capacity need not prevent earlier valid
|
|
frames from being returned. Input format errors never publish a partly
|
|
decoded or CRC-unverified FLAC frame; transport faults may leave partial
|
|
output from an already verified frame. Success is distinct from partial
|
|
prefix plus terminal error.
|
|
|
|
Memory success waits for every output B response. Stream success waits for
|
|
the final router-to-I2S handshake and an empty APU TX router, not for the last
|
|
sample to leave the DAC pin. The stream session remains active until that
|
|
drain, so route changes still use the P2 active-direction rule. Software that
|
|
needs audible completion must separately drain I2S before disabling it.
|
|
Empty jobs need no final beat. IRQ, ring coalescing/IOC, result writeback and
|
|
OWN-last release follow P2; direct completion uses IRQ bit 0, ring uses bit 1.
|
|
`JOB_FLAGS[0]` affects only the explicitly stated padding/trailing-byte checks;
|
|
it never disables bounds, codec CRC, overflow, or output-capacity checks.
|
|
|
|
##### P5 format diagnostics and unsupported MP3 entry
|
|
|
|
Codec `RESULT_DETAIL`, `JOB_DETAIL`, and codec `ERROR_DETAIL` use format ID
|
|
`[31:24]`, warnings `[23:16]`, and reason `[15:0]`. Warnings are bit 0 MD5
|
|
unchecked (FLAC only), bit 1 relaxed trailing bytes ignored, bit 2 relaxed
|
|
nonzero WAV pad accepted; bits 3..7 are zero. Warnings describe checks actually
|
|
skipped, including on a later failure. All unspecified reason values are
|
|
reserved. On success reason/code are zero. On a codec error the tuple has
|
|
VALID=1, AXI response=0, direct descriptor index=0 or the owning ring index,
|
|
and `ERROR_ADDRESS=INPUT_ADDRESS+context_word5`, with checked arithmetic.
|
|
The location is the first byte of the failing field/chunk/frame, or exactly
|
|
one-past-input for truncation. W1C, existing first-error preservation and P3
|
|
loader/trap tuples remain unchanged.
|
|
|
|
| Reason | Meaning | Code / stage |
|
|
| ---: | --- | --- |
|
|
| `0x0001` | Unsupported operation/format | 3 / 2 |
|
|
| `0x0002` | Unsupported rate/channels/precision or expected-input mismatch | 3 / 4 |
|
|
| `0x0003` | Unsupported valid encoding/container/metadata type | 3 / 4 |
|
|
| `0x0004` | File/chunk/metadata/block/frame/Rice quotient profile limit | 3 / 4 (container/block) or 5 (Rice) |
|
|
| `0x0010` | Bad file signature | 4 / 4 |
|
|
| `0x0011` | RIFF size/wrap or malformed container extent | 4 / 4 |
|
|
| `0x0012` | Missing/duplicate/misordered required chunk | 4 / 4 |
|
|
| `0x0013` | Chunk data length not frame-aligned or invalid chunk extent | 4 / 4 |
|
|
| `0x0014` | Invalid PCM format fields/alignment/byte rate | 4 / 4 |
|
|
| `0x0015` | Invalid STREAMINFO | 4 / 4 |
|
|
| `0x0016` | Invalid FLAC metadata structure | 4 / 4 |
|
|
| `0x0017` | Invalid/reserved frame header | 4 / 4 |
|
|
| `0x0018` | Midstream geometry/blocking-strategy change | 4 / 4 |
|
|
| `0x0019` | Forbidden nonzero pad bits/strict pad byte | 4 / 4 |
|
|
| `0x001a` | Invalid/noncontiguous frame or sample number | 4 / 4 |
|
|
| `0x001b` | Strict trailing bytes | 4 / 4 |
|
|
| `0x0020` | Required bytes/bits missing | 5 / 4 for class 2/parser; 5 / 5 for entropy |
|
|
| `0x0030`, `0x0031` | Header CRC8, frame CRC16 mismatch | 6 / 4 |
|
|
| `0x0032` | Nonzero STREAMINFO total differs at complete-frame EOF or is exceeded | 4 / 4 |
|
|
| `0x0040` | Malformed entropy/partition encoding | 7 / 5 |
|
|
| `0x0041` | Invalid wasted-bit count | 7 / 5 |
|
|
| `0x0042` | Invalid Rice escape/partition sample count | 7 / 5 |
|
|
| `0x0043` | Reconstruction or restored sample out of range | 22 / 6 |
|
|
| `0x0050` | Unsupported output rate/channel/flag combination | 3 / 0 |
|
|
| `0x0051` | Destination capacity exhausted | 8 / 8 |
|
|
| `0x0052` | Invalid context/cursor/commit/final-marker contract | 11 / 11; uses existing sequencer reason-9 trap detail, not codec detail |
|
|
|
|
Structural APB rejections still return `PSLVERR` without inventing a new
|
|
codec result. For unsupported ring descriptors, reason 1 uses descriptor
|
|
CONTROL address rather than an input-file address. Transport/primitive/trap
|
|
errors keep their existing P2/P3/P4 tuple (including PC addresses), and the
|
|
job result copies that detail. The format table applies to microcode parser
|
|
`JOB_RESULT` failures, not a reinterpretation of those lower-level failures.
|
|
For output capacity reason `0x0051`, use `OUTPUT_ADDRESS+output_cursor` for
|
|
memory (response zero, stage 8, owning job index). A total-byte overflow on
|
|
stream uses address zero and code 22/stage 8 with `trap_detail(9)`; on memory
|
|
it uses the checked next destination address, saturating at `0xffffffff` if
|
|
that address itself overflows. Invalid context reason `0x0052` uses the
|
|
existing reason-9 fallback code 11/stage 11/index zero/PC address.
|
|
When multiple parser checks at the same position fail, structural extent and
|
|
reserved-bit errors precede unsupported-profile checks, then CRC checks;
|
|
the first check in field order otherwise wins.
|
|
|
|
The released P5 APUMC uses V2.0 and still contains exactly three entries.
|
|
Instruction word 0 is always `0x0200000001000001` (unconditional class-0 TRAP, detail
|
|
`0x01000001`). The MP3 entry at descriptor index 1 has the exact eight words
|
|
`[0x00000001, 0, 0, 0, 1, 1, 0, 0]`: entry/first/last PC zero, zero scratch,
|
|
table and primitive mask, maximum loop/retired one. A verification-only
|
|
launch of it produces code 11/stage 11/response 0/index 0/address 0/detail
|
|
`0x01000001`, retired zero. Public MP3 requests are rejected with unsupported
|
|
format before reaching that trap. WAV and FLAC entries start after PC 0;
|
|
their masks contain the primitives they declare and may share read-only
|
|
tables and scratch as already allowed. The header mask is the OR of entries,
|
|
not forcibly `0x001fffff`; the implemented mask advertises hardware capacity.
|
|
|
|
<details>
|
|
<summary>Deferred APU-P6 design archive — not current-release requirements</summary>
|
|
|
|
#### P6 MP3 profile, compatibility, and capacity
|
|
|
|
Status: DEFERRED. Everything in this archive through the following closing
|
|
details marker, including its capability/target, active-MP3 entry, packing and
|
|
MP3 decode rules, is retained for future design reference only. It is not
|
|
normative for the current release and cannot authorize implementation or
|
|
advertising MP3. Reactivation requires an explicit refreeze. The current
|
|
release uses the P5 WAV/FLAC image and MP3 stub, with MP3 capability bit 1 zero.
|
|
|
|
This refreeze is grounded in code baseline
|
|
`836371663feff6554ee923bb63a6a42978f4d777`. Its P5 microassembly contains
|
|
4073 instructions, leaving 23 of the 4096 words unused. This establishes
|
|
that appending a decoder to the current layout is not a credible capacity
|
|
plan; it does not establish a size for a reorganized complete P6 bundle.
|
|
|
|
| P6 property | Archived proposal (inactive for this release) |
|
|
| --- | --- |
|
|
| Discovery | `CAPABILITY0=0x000001bf`, `CAPABILITY1=0x01827020`, `IP_VERSION=0x00010001`, `ABI_DIGEST=0`. MP3 bit 1 becomes implemented; KWS bit 6 remains zero. |
|
|
| Image and ISA | Add target `p6`, default APUMC V2 / `MC_ABI=0x00020000`, mask `0x001fffff`, existing classes 0..6 and 12-bit PC/branches. Preserve p3/p4/p5 targets and V1 rejection/compatibility rules. p6 may explicitly read/emit V1 within its 2048-word limit; the production P6 release is V2. |
|
|
| Job and route | Operation 0, formats 0 WAV, 1 MP3, 2 FLAC, direct/ring, memory or TX stream. RX route 1, KWS, model loading and other formats remain unavailable. No new register offset, IRQ, resource index, system master, pad, clock or CDC/RDC allocation. |
|
|
| Resident image | One boot-loaded, validated and hard-reset-locked three-entry bundle contains all three real decoder entries. It replaces the P5 release image as a whole; MP3 entry 1 is no longer the P5 trap stub. No per-job reload, overlay, host parsing/decoding, C/DSP core, or unlocked code bank is introduced. |
|
|
| Hard limits | 4096 total 64-bit words including every entry/common routine/padding; 32 KiB control store and 112 KiB data store. P4/P5 local partitions and published PCM/transport/HAL semantics are retained. No implicit 8192-word expansion or new ISA operand mode is authorized. |
|
|
| Allowed compaction | The P6 emitter may regenerate, relocate, share routines and tables, change register allocation, tile kernels, and remove provably unreachable/duplicate instructions. It may not delete supported P5 paths, weaken diagnostics, change P4 arithmetic, or move parser decisions into RTL. No fixed fraction of the store is reserved for MP3; the only code budget is the complete 4096-word image. |
|
|
|
|
Before changing production RTL or advertising P6 capability, implementation
|
|
must produce a complete three-format microassembly packing report and a local
|
|
table/scratch live-range report, covering MP3 and every P5 path. The current
|
|
4073-word layout is not immutable inside the new image; the committed P5 image
|
|
and its builder/fixtures remain reproducible compatibility artifacts. Passing
|
|
P6 means the new image also passes the P5 corpus with identical PCM, parsed
|
|
input/output/frame accounting, acceptance/rejection, and semantic error tuple.
|
|
Build IDs, code PCs, retired counts and cycle measurements naturally describe
|
|
the new image; their definitions and PC-to-symbol diagnostics stay unchanged.
|
|
Packing is the first bounded implementation milestone, not an artifact this
|
|
documentation-only refreeze claims to have produced. Preflight must distinguish
|
|
a decision-complete contract from an unproven packing result and make the
|
|
packing gate visible before authorizing downstream production changes.
|
|
|
|
The packing gate must include all MP3 parsing, reservoir/Huffman/scalefactor,
|
|
requantization/reorder/antialias/stereo, long/start/short/stop IMDCT, overlap,
|
|
polyphase synthesis, output/resampling and error paths. P5 coefficient banks
|
|
and its FLAC workspace cannot simply be displaced by MP3 tables. MP3 may
|
|
reuse scratch between nonoverlapping lifetimes, generate coefficients there
|
|
with the existing arithmetic, and use explicit table/bit-reader routines;
|
|
it cannot reinterpret the P4 canonical-Huffman, REQUANT, or DCT32_POLY opcode
|
|
semantics as a different hardwired MP3 operation. The report must show the
|
|
actual lowering to existing primitives and its numerical/latency evidence.
|
|
The existing 24 KiB combined codec table/scratch ceiling applies to the
|
|
complete bundle, not independently to each static table image.
|
|
|
|
If those complete packing reports exceed code or data limits, return
|
|
`SPEC_CONFLICT` before downstream implementation; do not claim that this
|
|
refreeze proves the three decoders fit. Increasing capacity or changing the
|
|
ISA requires a separate explicit architectural refreeze. This is an evidence
|
|
gate with an exact budget, not permission to omit unimplemented branches.
|
|
|
|
P6 hardware continues to accept supported legacy images. It must recognize
|
|
the exact P5 entry-1 trap descriptor/body already specified and reject a public
|
|
MP3 job against that stub before executing it: direct start returns PSLVERR
|
|
with no job mutation; an owned ring entry completes code 3/stage 2/detail
|
|
`0x01000001` at its CONTROL address. WAV/FLAC jobs remain legal. Release
|
|
software uses the manifest of the loaded image when selecting formats;
|
|
CAPABILITY0 describes hardware and alone does not certify arbitrary loaded
|
|
microcode. The P5 verification-only stub launch keeps its original trap tuple.
|
|
|
|
##### P6 file, header, and metadata rules
|
|
|
|
P6 accepts finite elementary Layer III streams, at most `0x7fffffff` input
|
|
bytes, with the following exact subset. Bitstream constants are cross-checked
|
|
against the pinned independent decoder sources in the P6 reference section;
|
|
ID3 framing follows [ID3v2.3](https://id3.org/id3v2.3.0) and
|
|
[ID3v2.4](https://id3.org/id3v2.4.0-structure). Reference decoder tolerance does
|
|
not override the rejection rules here.
|
|
|
|
| Field or structure | Accepted values and required handling |
|
|
| --- | --- |
|
|
| Leading ID3 | Zero to four consecutive ID3v2.2/2.3/2.4 tags at byte zero, revision 0. Each has a complete 10-byte header and four synchsafe size bytes with high bits zero. Total skipped tag bodies, headers and footers must be at most 1 MiB. There is no arbitrary junk search before the first audio frame. |
|
|
| ID3 flags | v2.2 allowed mask `0xc0`; v2.3 `0xe0`; v2.4 `0xf0`. Other flag bits fail. Tag body is an opaque skip of the declared on-disk bytes, including unsynchronisation, compression and any extended header; no ID3 text/CRC/decryption semantics are claimed. v2.4 footer bit `0x10` adds 10 bytes beyond header+body and requires `3DI` plus identical version/flags/size fields. Other versions have no footer. Checked range arithmetic precedes the skip. |
|
|
| MPEG version | Header version bits 3 MPEG-1, 2 MPEG-2, 0 MPEG-2.5; value 1 is reserved and fails. Layer bits must be 1 (Layer III); Layers I/II are unsupported. |
|
|
| Bitrate | Indices 1..14 use the exact tables below. Index 0 (free format) is always unsupported, even if a reference can infer its frame length; index 15 is malformed. No scan-ahead free-format heuristic. |
|
|
| Sample rate | Index 0/1/2 uses the exact table below; index 3 is malformed. Version and rate are constant for the entire job. |
|
|
| Channels/mode | Modes 0 stereo, 1 joint stereo, 2 dual channel produce two channels; mode 3 produces one. Stereo/dual/joint may switch without changing channel count. A mono/stereo transition is rejected. Both joint-stereo extension bits (intensity and MS) are supported; extension bits are ignored outside joint mode. |
|
|
| Other header bits | Padding 0/1 and bitrate may change per frame (CBR/VBR/ABR accepted). Protection may change; zero means the two-byte CRC is present. Private/copyright/original bits are accepted without affecting output. Emphasis 0 is supported, 1/3 are unsupported, and reserved 2 is malformed. |
|
|
| Frame byte count | MPEG-1: `floor(144000*bitrate_kbps/rate_hz)+padding`; MPEG-2/2.5: `floor(72000*bitrate_kbps/rate_hz)+padding`. The count includes header/CRC/side-info and must fit the input and be at least their sum. Maximum supported frame length is 1441 bytes. |
|
|
| Side-info size | MPEG-1: 17 bytes mono, 32 stereo; MPEG-2/2.5: 9 mono, 17 stereo. Two granules/frame for MPEG-1, one for MPEG-2/2.5; every granule/channel represents 576 samples. |
|
|
| Geometry changes | Reject version/rate/channel-count changes at the first differing header field. Expected nonzero INPUT_CONFIG rate/channels must match. MP3 has no encoded PCM bit depth: P6 reports decoded source precision 24; expected bits is zero or 24, otherwise unsupported. |
|
|
| End tags | One final 128-byte ID3v1 block beginning `TAG` is accepted and consumed in either strict mode. No APE or midstream ID3 parsing. Other trailing bytes are rejected in strict mode and ignored only after at least one complete audio frame in relaxed mode. A partial sync/header or a valid next header whose frame is truncated is always an error, not relaxed trailing junk. |
|
|
| VBR metadata | Xing/Info/VBRI/LAME ancillary bytes do not supply authoritative duration, seek points, gain, encoder delay, padding, or frame count. Their containing MPEG frames are decoded/count normally. No gapless trim or ReplayGain is applied; actual validated frame headers determine accounting. |
|
|
|
|
| MPEG family | Bitrate indices 1..14, kbit/s | Rate indices 0,1,2, Hz | Samples/channel/frame |
|
|
| --- | --- | --- | ---: |
|
|
| MPEG-1 | 32,40,48,56,64,80,96,112,128,160,192,224,256,320 | 44100,48000,32000 | 1152 |
|
|
| MPEG-2 | 8,16,24,32,40,48,56,64,80,96,112,128,144,160 | 22050,24000,16000 | 576 |
|
|
| MPEG-2.5 | 8,16,24,32,40,48,56,64,80,96,112,128,144,160 | 11025,12000,8000 | 576 |
|
|
|
|
At least one complete audio frame is required; a tag-only or empty MP3 input
|
|
returns malformed/no-audio. Frame boundaries follow the computed byte count.
|
|
There is no silent resynchronization, concealment, skipped bad frame, or
|
|
property-dependent restart inside a job.
|
|
At an expected initial audio header, a nonempty remainder shorter than four
|
|
bytes is truncated input. After a valid frame, a short suffix beginning with
|
|
`0xff` and matching the available MPEG sync/version/layer bits is a truncated
|
|
header; other short suffixes follow the strict/relaxed trailing-byte rule.
|
|
A recognized `ID3` or `TAG` prefix with insufficient bytes for its required
|
|
header/block is truncated in both modes. These checks precede a relaxed skip.
|
|
|
|
##### P6 side-info, reservoir, and integrity rules
|
|
|
|
Let `P` be the cumulative number of main-data slot bytes in all preceding
|
|
frames, excluding their header, optional CRC and side-info. Let `M` be the
|
|
current frame's main-data slot count and `B=main_data_begin`. MPEG-1 B is a
|
|
9-bit value 0..511; MPEG-2/2.5 B is 8 bits 0..255. The current coded data
|
|
starts at byte `P-B` of that main-data-only stream. At job start history and
|
|
overlap are zero/empty, so the first frame requires B=0. Retain the last 511
|
|
main-data slot bytes plus current frame slots, at most 1952 bytes. Headers,
|
|
ID3 and CRC bytes never become reservoir bytes. Reset/abort or the next job
|
|
clears this history; it is never shared between ring jobs.
|
|
|
|
Require B no larger than actual retained history. The start bit must not
|
|
precede the previous frame's consumed main-data end bit, and the sum of all
|
|
`part2_3_length` values must end no later than `8*(P+M)`. Ancillary gaps and
|
|
byte-alignment stuffing between coded frame payloads are allowed. A reference
|
|
decoder that substitutes silence on reservoir underflow does not define P6
|
|
behavior: P6 terminates without PCM from the affected frame.
|
|
|
|
Side-info is parsed in transmitted granule/channel order. Each big_values is
|
|
0..288; each part2_3 length is a 12-bit bit budget, not a byte count. Reject
|
|
reserved codebook selections 4/14 and region boundaries outside 576 lines.
|
|
Table 0 produces zero pairs without consuming Huffman bits. Window switching
|
|
requires block_type 1/2/3; mixed_block is legal only with short block type 2.
|
|
Support long/start/short/stop and mixed blocks, MPEG-1 scfsi/preflag,
|
|
MPEG-2/2.5 scalefactor-compress and intensity rules, scalefac_scale,
|
|
subblock_gain, both count1 tables, all nonreserved pair codebooks and linbits.
|
|
Scalefactor bits are charged against part2_3 before Huffman data. Pair/quad
|
|
decoding cannot publish past line 575 or consume another part's bit budget;
|
|
remaining uncoded lines are zero and legal count1 termination/stuffing is
|
|
handled without reading beyond that budget. Truncated physical input and a
|
|
budget violation are distinct errors.
|
|
|
|
When protection is zero, read the stored big-endian CRC16 immediately after
|
|
the four-byte header. Compute MSB-first CRC with initial `0xffff`, polynomial
|
|
`0x8005`, no final XOR, over the header's final 16 bits (bitrate index through
|
|
emphasis), followed by all side-info bits in transmitted order. Exclude the
|
|
stored CRC and main-data bytes. CRC checking is mandatory in strict and
|
|
relaxed modes. It is MPEG error protection, not a whole-audio checksum.
|
|
The existing CRC16 primitive can use this nonzero initial accumulator;
|
|
its opcode behavior does not change.
|
|
|
|
No PCM from a frame is issued until its complete physical byte range,
|
|
side-info, CRC (when present), reservoir range and compressed-sample decode
|
|
have passed. Earlier valid output remains on later failure. Synthesis history
|
|
may be updated speculatively only if it cannot affect another job after an
|
|
error. Source bit extraction may use bounded scalar/table routines on the
|
|
saved reservoir; the original input FIFO is not rewound or fed duplicate
|
|
header bytes. The P5 explicit refill/cursor/EOF contract remains unchanged.
|
|
|
|
##### P6 PCM, counts, and first-offender diagnostics
|
|
|
|
MP3 decoding includes requantization, short-block reorder, alias reduction,
|
|
joint-stereo reconstruction, windowed IMDCT/overlap-add, frequency inversion
|
|
and synthesis polyphase filtering, in MPEG order. Intermediate representations
|
|
and coefficient realization must lower to the existing fixed-point primitives
|
|
and are qualified by the bit-accurate lowering report and the numerical gates
|
|
below. No synthesis stage or frequency band may be dropped to meet capacity.
|
|
Decoded samples enter the P5 post-processing path as signed Q1.31. Native
|
|
S24_32 output is the arithmetic right shift by 8 with saturation; S16 is the
|
|
right shift by 16. P5 downmix, duplication, resampling, capacity, TLAST, and
|
|
whole-output-frame rules are inherited exactly.
|
|
The reported precision 24 describes the canonical decoded PCM representation;
|
|
already normalized MP3 Q1.31 samples must not be shifted left again as if they
|
|
were raw 24-bit input samples.
|
|
|
|
Count every decoded MPEG frame including Xing/Info/VBRI-containing frames.
|
|
Native source sample-frame count is 1152 per MPEG-1 frame or 576 per lower
|
|
rate frame. No leading synthesis delay, encoder padding, or final samples
|
|
are trimmed, and no extra overlap tail is flushed beyond that count.
|
|
`JOB_FRAMES`/descriptor RESULT_FRAMES count destination PCM sample frames
|
|
after P5 rate conversion, not MPEG frames or channel samples. SOURCE_INFO
|
|
contains rate, 1/2 channels, and precision 24. INPUT_USED is the parsed physical
|
|
file prefix including accepted ID3 tags and frame bytes, never reservoir
|
|
rereads or prefetched bytes. Relaxed ignored trailing junk is excluded. Output
|
|
bytes/partial output and all direct/ring completion ordering remain P5 rules.
|
|
|
|
For MP3 parser failures, DETAIL `[31:24]=1`, `[23:16]` is warnings, and
|
|
`[15:0]` is the reason below. Warning bit 1 means relaxed trailing bytes were
|
|
ignored; other MP3 warning bits are zero. On success reason is zero. Each row
|
|
sets ERROR_STATUS valid=1, response=0, direct index=0 or owning ring index,
|
|
with the specified code/stage. Addresses below are absolute input addresses:
|
|
`F` is the current four-byte MPEG header address, `S=F+4+crc_bytes`, and a
|
|
field address is the byte containing the first transmitted bit of that field.
|
|
For reservoir-derived entropy bits, retain their original physical-byte
|
|
provenance across frames; do not report a scratch pointer as an input address.
|
|
|
|
| Reason | Failure | Code / stage | First-offender address |
|
|
| --- | --- | --- | --- |
|
|
| `0x0100` | Unsupported ID3 major/revision | 3 / 4 | Tag start + 3 |
|
|
| `0x0101` | Reserved ID3 flags | 4 / 4 | Tag start + 5 |
|
|
| `0x0102` | Nonsynchsafe ID3 size | 4 / 4 | First size byte with bit 7 set |
|
|
| `0x0103` | ID3 count/1 MiB limit or extent arithmetic overflow | 3 / 4 for limit, 4 / 4 for overflow | Offending tag start |
|
|
| `0x0104` | ID3v2.4 footer mismatch | 4 / 4 | First differing footer byte |
|
|
| `0x0110` | Missing sync/no audio/invalid reserved version | 4 / 4 | F (no audio: parsed tag end) |
|
|
| `0x0111` | Unsupported layer | 3 / 4 | F + 1 |
|
|
| `0x0112` | Free-format bitrate index 0 | 3 / 4 | F + 2 |
|
|
| `0x0113` | Bitrate index 15 or rate index 3 | 4 / 4 | F + 2 |
|
|
| `0x0114` | Unsupported/reserved emphasis | 3 / 4 for 1/3, 4 / 4 for 2 | F + 3 |
|
|
| `0x0115` | Frame shorter than its mandatory structures | 4 / 4 | F + 2 |
|
|
| `0x0116` | Version/rate/channel-count change | 4 / 4 | First changed field in header byte order |
|
|
| `0x0117` | Expected source-geometry mismatch | 3 / 4 | First offending version/rate/mode field; expected precision mismatch uses F |
|
|
| `0x0120` | Mandatory ID3/header/side-info/frame bytes missing | 5 / 4 | INPUT_ADDRESS + INPUT_LENGTH |
|
|
| `0x0121` | Strict unrecognized trailing bytes | 4 / 4 | First trailing byte |
|
|
| `0x0130` | Side-info big_values/window/codebook/region invalid | 7 / 5 | First invalid transmitted field |
|
|
| `0x0131` | Reservoir history underflow | 7 / 5 | S (main_data_begin field) |
|
|
| `0x0132` | Reservoir overlap or summed part2_3 range violation | 7 / 5 | S for overlap; first part2_3_length field making the sum exceed available bits otherwise |
|
|
| `0x0133` | Scalefactor/entropy part budget invalid | 7 / 5 | Start of that part's first undecodable code, mapped to physical input |
|
|
| `0x0134` | Illegal Huffman prefix/line count | 7 / 5 | First offending code's original physical byte |
|
|
| `0x0140` | Stored MPEG CRC mismatch | 6 / 4 | F + 4 |
|
|
|
|
Within a frame, validate complete header and its range, then side-info field
|
|
legality, then MPEG CRC, then reservoir bounds, then scalefactors/entropy. A
|
|
missing mandatory byte outranks checks that require that missing structure;
|
|
an already invalid earlier header is reported without reading later bytes.
|
|
Within side-info use transmitted bit order and granule/channel order. Global
|
|
AXI/DMA/xrun/trap/abort precedence and immutable-first-error capture remain
|
|
unchanged. Primitive/kernel overflow, sequencer faults, and output-capacity
|
|
errors retain P4/P5 tuples and PC_HIGH handling; they are not relabeled as
|
|
one of these parser reasons. HAL status mapping treats format 1 explicitly:
|
|
MP3 uses CAPABILITY0 bit 1 and these codes, not the previous non-WAV-to-FLAC
|
|
fallback. Existing job/result structures and API signatures are retained.
|
|
|
|
</details>
|
|
|
|
### `APUM` KWS model ABI
|
|
|
|
This is the first byte-level definition of APUM 1.0; no P1..P5 implementation
|
|
accepts an APUM image. All multibyte fields are little-endian, offsets are byte
|
|
offsets, signed integers are two's complement, and padding/reserved bytes MUST
|
|
be zero. APUM is not a TFLite FlatBuffer and is independent of APUMC and APB
|
|
versions. P7 accepts only the graph/quantization below, not a general NPU graph.
|
|
|
|
#### APUM header and layout
|
|
|
|
The image base is 64-byte aligned. The header is exactly 64 bytes. The image
|
|
is exactly 32768 bytes: 12 operator records at `0x0040`, 13 tensor records at
|
|
`0x0340`, zero padding at `0x04e0..0x04ff`, parameters at `0x0500..0x768f`,
|
|
and zero tail padding at `0x7690..0x7fff`. There are no external pointers,
|
|
compressed parameters, optional sections, alias records, or variable shapes.
|
|
|
|
| Header byte | Type | Field / required P7 value |
|
|
| ---: | --- | --- |
|
|
| `0x00` | u32 | Magic `0x4d555041` (bytes `APUM`). |
|
|
| `0x04` | u32 | APUM ABI `0x00010000`. |
|
|
| `0x08` | u32 | Total image bytes `32768`. |
|
|
| `0x0c` | u32 | Operator-set ID `1`. |
|
|
| `0x10` | u32 | MFCC rows `[15:0]=49`, coefficients `[31:16]=10`. |
|
|
| `0x14` | u32 | Classes `[15:0]=12`, operator count `[31:16]=12`. |
|
|
| `0x18` | u32 | Parameter bytes `29072`, starting at fixed offset `0x0500`. |
|
|
| `0x1c` | u32 | Scratch reservation `32768` bytes, separate from image bytes. |
|
|
| `0x20` | u32 | Quantization profile ID `1`, defined below. |
|
|
| `0x24` | u32 | CRC-32/ISO-HDLC over bytes `[64,32768)`, including padding. |
|
|
| `0x28` | u64 | Model ID `0xce4f70006843eaae`; first eight SHA-256 digest bytes of the pinned TFLite, interpreted little-endian. |
|
|
| `0x30` | u32 | Default threshold `[7:0]=128`, debounce `[15:8]=3`, upper bits zero. |
|
|
| `0x34` | u32 | Tensor count `13`. |
|
|
| `0x38` | u32 | Scratch-layout ID `1`. |
|
|
| `0x3c` | u32 | Reserved zero. |
|
|
|
|
CRC uses reflected polynomial `0xedb88320`, initial state `0xffffffff`, bytes
|
|
in increasing address order, and final XOR `0xffffffff` (`123456789` gives
|
|
`0xcbf43926`). The header CRC word and `KWS_MODEL_EXPECTED_CRC` MUST both equal
|
|
the observed payload CRC. Header fields are validated separately; neither CRC
|
|
nor the truncated model ID authenticates an image. The complete upstream SHA
|
|
and generated-image SHA belong in the host release manifest.
|
|
|
|
An independent freeze-time in-memory packing of the pinned model under these
|
|
rules gives the following golden values. The implementation converter MUST
|
|
reproduce them; these are computed bytes, not a claimed RTL/converter test.
|
|
|
|
| Golden object | Required value |
|
|
| --- | --- |
|
|
| Payload CRC / production expected CRC | `0xb9034b22` |
|
|
| Complete 32768-byte APUM SHA-256 | `87861b5f866182969e34917b4bf57cab61cd2245c3ab9b933797209322e3ce63` |
|
|
| Parameters `[0x0500,0x7690)` SHA-256 | `0e4eb210d247a45747049ef9602bbd7e90868e9cb1c04fb2a02f128db44e241e` |
|
|
| Weighted operators' multiplier then shift arrays, graph order, no delimiters, SHA-256 | `222e05821695f3fdd47be682b2cc75e0e735aa106436bf941cdda3ef8cb03b59` |
|
|
|
|
The corresponding 64-byte header, consecutive hexadecimal bytes, is:
|
|
|
|
```text
|
|
4150554d00000100008000000100000031000a000c000c009071000000800000
|
|
01000000224b03b9aeea436800704fce800300000d0000000100000000000000
|
|
```
|
|
|
|
The runtime CRC check compares observed/header/register values as specified;
|
|
it is not a SHA validator or authorization for a differently trained release
|
|
model. The release flow additionally requires the complete golden APUM hash.
|
|
|
|
Each operator record is 64 bytes:
|
|
|
|
| Byte in record | Type | Meaning |
|
|
| ---: | --- | --- |
|
|
| `0x00` | u16 | Opcode: 1 Conv2D (also pointwise), 2 depthwise, 3 average pool, 4 fully connected, 5 Softmax. |
|
|
| `0x02` | u16 | Flags: bit 0 fused ReLU; all others zero. |
|
|
| `0x04`, `0x06` | u16 each | Input and output tensor IDs. |
|
|
| `0x08`, `0x0c` | u32 each | Image-relative weight and bias offsets. |
|
|
| `0x10`, `0x14` | u32 each | Image-relative Q31 multiplier and signed-shift array offsets. |
|
|
| `0x18`, `0x1c` | u32 each | Weight byte count; output channel count. |
|
|
| `0x20`, `0x22` | u16 each | Kernel height and width. |
|
|
| `0x24`, `0x26` | u16 each | Height and width stride. |
|
|
| `0x28..0x2b` | u8 each | Top, bottom, left, right zero-point padding. |
|
|
| `0x2c`, `0x30` | i32 each | Input and output zero points. |
|
|
| `0x34`, `0x38` | i32 each | Inclusive output clamp minimum and maximum. |
|
|
| `0x3c` | u32 | Reserved zero. |
|
|
|
|
Convolution weights are signed INT8 in `[out,h,w,in]` order; depthwise weights
|
|
are `[1,h,w,channel]`, depth multiplier one; FC weights are `[out,in]`. All
|
|
weight zero points are zero. Bias, multiplier and shift arrays contain one
|
|
signed-32 word per output channel. FC's single source scale is broadcast to
|
|
12 output channels. For each weighted operator in graph order, append weights,
|
|
biases, multipliers, then shifts, each 16-byte aligned. These arrays total
|
|
22016 + 2352 + 2352 + 2352 = 29072 bytes; no array is deduplicated. Pool and
|
|
Softmax have zero in all four parameter offsets and weight-byte count. FC and
|
|
Softmax use kernel/stride 1 by 1 and zero padding. Pool uses kernel/stride
|
|
25 by 5, VALID padding. Pool/FC/Softmax have no ReLU; clamp is -128..127.
|
|
|
|
Each tensor record is 32 bytes: u16 `N,H,W,C` at bytes 0,2,4,6; u32
|
|
scratch-relative offset at 8; u32 byte count at 12; u32 element type `1=INT8`
|
|
at 16; u32 IEEE-754 binary32 scale bits at 20; i32 zero point at 24; u32 zero
|
|
at 28. Scale bits are immutable metadata checked against the pinned tensor
|
|
table, not permission to execute floating-point arithmetic in hardware.
|
|
Byte count equals `N*H*W*C`, checked without overflow. All tensors are NHWC,
|
|
batch one. Pool/FC tensors use the four-dimensional shapes below; the upstream
|
|
reshape changes no bytes and creates no APUM operator or additional buffer.
|
|
|
|
#### P7 fixed graph and quantization profile 1
|
|
|
|
The immutable source is TFLite SHA-256
|
|
`aeea436800704fce17b17292e4412630ad856e9d777c044c64ef748a880bd0ae`.
|
|
The binary, not a freshly trained Keras graph or its prose README, is the
|
|
authority for every weight, bias and per-channel scale. It contains 13 TFLite
|
|
operators and 35 tensors; folding only reshape yields the 12 operators and
|
|
13 activation tensors below. Batch normalization and ReLU are already fused.
|
|
|
|
| APUM tensor | Producer / source TFLite output | Shape N,H,W,C | Scale bits / zero point | Scratch offset |
|
|
| ---: | --- | --- | --- | ---: |
|
|
| 0 | MFCC / 0 | 1,49,10,1 | `0x3f15af17` / 83 | `0x4000` |
|
|
| 1 | Conv 10x4, stride 2x2 / 22 | 1,25,5,64 | `0x3da13ac8` / -128 | `0x0000` |
|
|
| 2 | Depthwise 3x3 / 23 | 1,25,5,64 | `0x3da99aea` / -128 | `0x2000` |
|
|
| 3 | Pointwise 1x1 / 24 | 1,25,5,64 | `0x3d75dd81` / -128 | `0x0000` |
|
|
| 4 | Depthwise 3x3 / 25 | 1,25,5,64 | `0x3d808854` / -128 | `0x2000` |
|
|
| 5 | Pointwise 1x1 / 26 | 1,25,5,64 | `0x3d19329e` / -128 | `0x0000` |
|
|
| 6 | Depthwise 3x3 / 27 | 1,25,5,64 | `0x3d3c02c1` / -128 | `0x2000` |
|
|
| 7 | Pointwise 1x1 / 28 | 1,25,5,64 | `0x3d070c5a` / -128 | `0x0000` |
|
|
| 8 | Depthwise 3x3 / 29 | 1,25,5,64 | `0x3d3fdf8a` / -128 | `0x2000` |
|
|
| 9 | Pointwise 1x1 / 30 | 1,25,5,64 | `0x3da452db` / -128 | `0x0000` |
|
|
| 10 | Average pool 25x5 / 31 (32 aliases 31) | 1,1,1,64 | `0x3da452db` / -128 | `0x2000` |
|
|
| 11 | FC 64 to 12 / 33 | 1,1,1,12 | `0x3e142a46` / 14 | `0x0000` |
|
|
| 12 | Softmax beta 1 / 34 | 1,1,1,12 | `0x3b800000` / -128 | `0x2000` |
|
|
|
|
Operator `i` consumes tensor `i` and produces `i+1`. First-convolution padding
|
|
is top 4, bottom 5, left 1, right 1. Depthwise padding is one on every side;
|
|
pointwise has zero padding. All other convolution strides are one, dilation
|
|
is one, and all nine convolution operators fuse ReLU. The source weight/bias
|
|
tensor pairs in weighted-operator order are `(17,3)`, `(5,4)`, `(18,6)`,
|
|
`(8,7)`, `(19,9)`, `(11,10)`, `(20,12)`, `(14,13)`, `(21,15)`, `(16,1)`.
|
|
Per-channel scales use the source quantized dimension (Conv axis 0, depthwise
|
|
axis 3); FC is per-tensor. No recalibration, retraining, bias re-rounding,
|
|
channel permutation, pruning, or alternative model is part of P7.
|
|
|
|
For output channel c, accumulate `bias[c] + sum((input-zin)*weight[c])` in
|
|
signed INT32 with checked wider intermediates, in h,w,input-channel order.
|
|
Padding contributes `input=zin`. Overflow is an arithmetic fault, not wrap or
|
|
silent accumulator saturation. Convert the effective multiplier
|
|
`double(input_scale)*double(weight_scale[c])/double(output_scale)` with the
|
|
pinned TFLite `QuantizeMultiplier`: binary64 operations without contraction,
|
|
frexp, positive nearest/ties-away Q31 rounding, carry renormalization, and
|
|
the upstream shift-below-minus-31 flush. Record the resulting Q31 word and
|
|
shift, not a decimal approximation. Runtime requantization uses the pinned
|
|
`MultiplyByQuantizedMultiplier` double-rounding behavior: checked left shift,
|
|
`SaturatingRoundingDoublingHighMul`, then `RoundingDivideByPOT`. Add zout and
|
|
clamp to `[max(-128,zout),127]` for ReLU, otherwise `[-128,127]`. Do not
|
|
replace these rules with nearest-even rounding or single-rounding DSP modes.
|
|
|
|
Average pool sums the 125 signed input bytes in INT32 and divides by 125
|
|
with nearest rounding, ties away from zero, retaining the same scale/zero
|
|
point; it is not the 24x5 pool suggested by the training source's shape
|
|
calculation. Softmax is the pinned
|
|
`tflite::reference_ops::Softmax<int8_t,int8_t>` with
|
|
`input_multiplier=1242899200`, `input_left_shift=24`, `diff_min=-124`,
|
|
Q5.26 scaled differences and Q12 accumulation, using the pinned gemmlowp
|
|
fixed-point exp/reciprocal routines. The host oracle and RTL must agree on
|
|
all twelve output bytes, including underflow, saturation and tied maxima.
|
|
No float exp, alternative LUT approximation, omitted Softmax, or CMSIS-NN
|
|
rounding substitution is permitted in the inference reference path.
|
|
|
|
#### P7 memory and loader validation
|
|
|
|
The existing KWS partition remains banks 10..25, local `0x0a000..0x19fff`,
|
|
64 KiB total. Banks 10..17 hold the 32 KiB APUM; banks 18..25 are the 32 KiB
|
|
scratch reservation. Codec/control-store banks, Gateway A identity, IRQ and
|
|
resource allocations do not change. A new independently arbitrated KWS client
|
|
may access only these KWS banks; it cannot borrow codec buffers or MAC lanes.
|
|
|
|
P8 maps each of these sixteen logical banks to one `tc_sram_1024x32` wrapper.
|
|
Within the APUM and scratch halves, physical bank is byte offset
|
|
`[4:2] XOR [8:6]` and wrapper word address is byte offset `[14:5]`; this
|
|
reversible word-interleaving distributes both consecutive and fixed 64-byte
|
|
stride lanes without changing logical addresses. Every bank accepts at most
|
|
one read or write per PCLK. The client snapshots one fixed-engine operand
|
|
vector, coalesces duplicate word reads, issues at most one access per bank per
|
|
cycle, and stalls the KWS state transition until every synchronous read and
|
|
required write has retired. A model load is globally idle and has exclusive
|
|
access; for engine traffic a write wins a same-bank read and the read remains
|
|
pending. Successful bank activity resets the KWS no-progress watchdog, while a
|
|
wedged client remains bounded by that watchdog. `HAVE_SRAM_MACRO=NO` uses the
|
|
same bank selection, one-cycle read latency, arbitration, and stall contract
|
|
with inferred arrays. This internal scheduling changes no APUM address, tensor,
|
|
scratch, register, descriptor, result, or error ABI and must re-pass the P7
|
|
accuracy, cycle, concurrency, xrun, abort, reset, and handoff gates.
|
|
|
|
Scratch layout 1 has A at `0x0000..0x1fff`, B at `0x2000..0x3fff`, MFCC at
|
|
`0x4000..0x41ff`, a 50x40 u32 raw-mel ring at `0x4200..0x61ff`, complex FFT
|
|
workspace at `0x6200..0x71ff`, 768 S16 ingress samples at `0x7200..0x77ff`,
|
|
and metadata at `0x7800..0x7fff` (peak ring, FIR state, counters, pending
|
|
stereo word and reduction state). A/B lifetimes alternate exactly as in the
|
|
tensor table. Scratch range checking cannot treat the entire 112 KiB local
|
|
store as available. The one-second history is retained as raw mel bands plus
|
|
peak metadata, not an additional unbudgeted 32000-byte PCM buffer. Immutable
|
|
frontend coefficients are immutable numerical constants generated from the
|
|
numerical recipe. Pre-P9 uses generated engine ROM functions; P9 requires
|
|
the separately loaded and locked macro-backed coefficient store below.
|
|
Report that auxiliary storage independently from these sixteen KWS banks.
|
|
|
|
MODEL_LOAD is LP-only, globally idle and quiesced, KWS disabled, ACL-valid and
|
|
model unlocked. Fetch/validate header first, then exact-size payload and CRC,
|
|
then records, ranges and quantization. Validate every fixed field, zero byte,
|
|
opcode, tensor ID, shape, scale/zero point, array length/alignment, graph edge,
|
|
padding/stride, scratch lifetime and parameter region before publishing valid.
|
|
Unsupported major/minor/quantization/operator-set/layout versions fail closed.
|
|
The loader MUST compare the records and requantization arrays with the frozen
|
|
profile; arbitrary parameters with internally consistent but different shapes
|
|
or arithmetic do not become a second supported model. All address additions
|
|
are checked; no DMA may escape the inclusive read ACL or image range.
|
|
|
|
An accepted load clears previous unlocked loader diagnostics and actual CRC,
|
|
sets busy and keeps valid clear. Success atomically publishes valid/locked and
|
|
the observed CRC, applies the header defaults to KWS_CONFIG and raises IRQ 4.
|
|
Any failure leaves valid/locked clear and execution disabled, records the
|
|
specified error and raises terminal IRQ 4 plus first-error IRQ 8. A retry is
|
|
allowed only after draining and clearing/recovering the error. A successful
|
|
lock cannot be cleared or reloaded by software, HP, abort, soft reset or
|
|
resource reset; only hard/PCLK reset invalidates it. An aborted partial load
|
|
never publishes valid or raises a successful-load indication.
|
|
|
|
### P7 frontend numerical profile 1
|
|
|
|
This profile closes the former 10 ms/49-row contradiction: a one-second,
|
|
16000-sample mono window uses 480-sample (30 ms) frames, 320-sample (20 ms)
|
|
hop, and a 512-point FFT. Frame r uses samples `320*r .. 320*r+479`, r=0..48;
|
|
the last 160 samples contribute to the normalization peak but not to a frame.
|
|
Inference windows end after samples 16000,17600,19200,... in continuous mode.
|
|
There is no pre-emphasis, DC removal, noise augmentation, AGC, dither, lifter,
|
|
center padding or trailing STFT padding. The frozen floating reference is the
|
|
pinned `get_dataset.py` MFCC branch, not its LFBE/microfrontend branch.
|
|
|
|
Let RNE denote exact nearest integer with ties to even and TZ truncation
|
|
toward zero. All constant generation uses increased precision with interval
|
|
bounds until rounding is unambiguous; independently generate and compare the
|
|
ROM words, and put their SHA-256 and profile ID in every release report.
|
|
Host math-library defaults are not the numerical specification.
|
|
|
|
1. Input is signed S16 after the capture conversion below. Use the positive
|
|
peak `P=max(1,max(x[0..15999]))`, not max absolute value. The `max(1,...)`
|
|
rule explicitly defines silence/all-nonpositive inputs where the upstream
|
|
division would otherwise be invalid or unsuitable. On the official corpus
|
|
the positive-peak rule is unchanged. Retain maxima for 100 successive
|
|
160-sample blocks so each rolling window has its own exact P.
|
|
2. Hann coefficients are `H[n]=RNE(2^30*(1-cos(2*pi*n/480))/2)`, n=0..479.
|
|
Build a 512-element complex input with real part
|
|
`RNE(x[n]*H[n]/2^15)` and imaginary zero; n=480..511 is zero. This carries
|
|
15 fractional bits of the unnormalized S16 value. Do not normalize each
|
|
frame with a different peak.
|
|
3. Use radix-2 decimation-in-time FFT, bit-reversed input, stages of length
|
|
2,4,...,512 and ascending butterfly indices. Twiddles are independently
|
|
RNE-quantized Q2.30 cos and negative sin. For each complex multiply, form
|
|
both signed-64 sums of products before one RNE divide by `2^30`; butterfly
|
|
sum/difference is then RNE divided by two at every stage. Components are
|
|
signed-32; overflow faults rather than wrapping. Thus final components
|
|
represent the unscaled DFT times 64. Keep bins 0..256 and use nearest
|
|
integer square root of the unsigned-64 sum of component squares (ties
|
|
even); no magnitude-squared/power substitution or log10 is allowed.
|
|
4. Define `mel(f)=1127*ln(1+f/700)`. Forty triangular filters have 42 evenly
|
|
spaced mel edges from mel(20) to mel(4000). Convert those edges back to Hz
|
|
and evaluate the linear triangle ramps in Hz at `f[k]=16000*k/512`, as
|
|
in the committed generator/BAM; this clarifies the coordinate convention
|
|
without changing any committed coefficient. Clamp each to [0,1], force DC-bin weights to zero,
|
|
and quantize weights to Q2.30 using RNE. For each band store
|
|
`M=RNE(sum(magnitude[k]*weight[k])/2^32)` as unsigned UQ28.4. This is
|
|
raw, unnormalized magnitude, not power. Products/reduction use unsigned
|
|
64-bit checked arithmetic. A 50-row ring holds these 40-word frames.
|
|
5. At a window endpoint, capture P and the 49 corresponding mel rows. For
|
|
each band form the positive rational
|
|
`z=(1000000*M+16*P)/(16000000*P)`; this is `M/(16*P)+1e-6`.
|
|
Normalize z exactly as `2^e*m`, 1<=m<2. The fixed log table contains
|
|
`L[i]=RNE(2^24*ln(1+i/1024))`, i=0..1024, and
|
|
`LN2=RNE(2^24*ln(2))`. Set i=floor(1024*(m-1)) and
|
|
`f=RNE(65536*(1024*(m-1)-i))`, allowing f=65536. Output signed Q8.24
|
|
`e*LN2+L[i]+RNE((L[i+1]-L[i])*f/65536)`. Integer divisions and exponent
|
|
selection must use the exact rational; no intermediate float is implied.
|
|
6. DCT coefficients are
|
|
`D[j,b]=RNE(2^30*sqrt(2/40)*cos(pi*(b+1/2)*j/40))`, j=0..9,b=0..39.
|
|
Compute `C[j]=RNE(sum(log[b]*D[j,b])/2^30)` in signed Q8.24 using signed-64
|
|
checked reduction. Coefficient zero has the same scaling as the other
|
|
coefficients, matching TensorFlow MFCC rather than an orthonormal DCT-II.
|
|
7. Quantize with `q=TZ(C[j]/(2^24*S)+83)` using the exact binary32 scale
|
|
`S=0x3f15af17`. Store the low eight bits, interpreted signed INT8.
|
|
This intentional modulo-256 conversion matches upstream NumPy INT8
|
|
export; it is NOT saturation. The published corpus includes 15 features
|
|
in `tst_000563_Go_1.bin` for which saturation gives different bytes.
|
|
This compatibility exception applies only at the MFCC boundary; inference
|
|
requantization and PCM conversion retain their own saturation rules.
|
|
|
|
For the independently evaluated floating recipe on all 1000 reconstructed
|
|
waveforms, 1381 of 490000 feature bytes differed from the published bytes when
|
|
using saturation: 15 were the export-wrap case and the others were within one
|
|
LSB. This 2026-09-11 host cross-check supports the corpus mapping and exposes
|
|
the quantizer distinction; it is NOT fixed-point RTL accuracy evidence.
|
|
P7 MUST implement a bit-accurate model (BAM) of the integer profile above and
|
|
compare every frontend stage and every inference tensor against RTL. Report
|
|
wrapped INT8 feature distance, per-stage error versus the floating reference,
|
|
and end-to-end top-1 separately. No feature-distance tolerance waives the
|
|
900/1000 hardware top-1 gate, and no implementation may change the formulas
|
|
or constants merely to improve that score without another refreeze.
|
|
|
|
### P7 capture, scheduling, status and diagnostic operation
|
|
|
|
P7 appends one register; existing offsets and reserved masks are unchanged:
|
|
|
|
| Offset | Name | Access / reset | Meaning |
|
|
| ---: | --- | --- | --- |
|
|
| `0x23c` | `KWS_INPUT_CONFIG` | RW disabled/idle; `0x0104bb80` | Rate `[16:0]`, physical channels `[18:17]`, precision `[25:20]`; all other bits zero. Reset is stereo S16 at 48000 Hz. |
|
|
|
|
This register is needed because AXI4-Stream audio has no rate/precision tag.
|
|
It does not cause APU to read or write I2S APB registers. Legal continuous
|
|
values are two physical channels, 16 or 24 bits, and 16000/48000/96000 Hz.
|
|
The caller must configure matching I2S master/dividers/stream RX while I2S is
|
|
disabled, then select RX route 1. The current I2S HAL's exact divider checks
|
|
remain authoritative; programmable 16 kHz capture is a P7 integration test.
|
|
Memory-window operation ignores KWS_INPUT_CONFIG and is always mono S16/16 kHz.
|
|
Unsupported rates, mono physical I2S, or reserved fields return PSLVERR before
|
|
state changes. P1..P5 continue returning PSLVERR at the new offset. Software
|
|
must test KWS capability before access; IP_VERSION remains `0x00010001`.
|
|
KWS_INPUT_CONFIG uses byte-strobe merge and validates the merged full value,
|
|
like KWS_CONFIG. KWS_CONTROL pulses/transitions require a full-word strobe.
|
|
|
|
S16 RX consumes the older low half then newer high half of each full 32-bit
|
|
beat. S24 RX pairs consecutive beats using signed bits 23:0; upper bits are
|
|
ignored. The mono pair is defined by wire order, not a nonexistent LRCK/channel
|
|
tag: after flush, its first member is the first complete accepted sample,
|
|
then the next sample. Do not infer left/right identity from a paused 24-bit
|
|
stream. Downmix is arithmetic floor((older+newer)/2) in a widened signed
|
|
accumulator. S24 is then arithmetic-shifted right eight
|
|
and saturated to S16. `TKEEP=TSTRB=0xf`, no RX TLAST; malformed sidebands or
|
|
unrecoverable half-pairs cause code 19/stage 9, clear history and stop KWS.
|
|
|
|
P7 exports the I2S wrapper's existing synchronized PCLK `s_rx_flush_busy`
|
|
as a same-domain `rx_flush_busy_o`, connected to APU
|
|
`i2s_rx_flush_busy_i`. This is an internal integration status wire, not an
|
|
AXI sideband, APB register, pad or new CDC. It reuses the existing Common
|
|
warm-flush detection, including unilateral audio reset. While asserted, APU
|
|
must not accept RX data and must invalidate any pending half-pair/history;
|
|
a live unplanned epoch loss counts one overrun and requires explicit restart.
|
|
For planned quiesce/reset, use the existing non-error/forced-loss distinction.
|
|
No new complete inference may contain samples from both sides of a flush.
|
|
|
|
At 16 kHz conversion is exact bypass. At 48/96 kHz use a dedicated 63-tap
|
|
causal FIR and decimation D=3/6. With input indices starting at zero, emit
|
|
at n=D-1,2D-1,... using `sum(t=0..62,H_D[t]*x[n-t])`, zero history for n<t.
|
|
Let c=1/D, x=t-31, w=(1-cos(2*pi*t/62))/2 and
|
|
`a=c*sinc(c*x)*w`, sinc(z)=sin(pi*z)/(pi*z), sinc(0)=1. Quantize normalized
|
|
coefficients to Q2.30 by RNE and add the unity-sum residual to tap 31.
|
|
Use signed-64 reduction, RNE divide by `2^30`, then S16 saturation. These
|
|
126 fixed coefficient words are independent of P5 codec resampler profiles/state.
|
|
Record the 31-input-sample filter delay; do not trim it or silently resample
|
|
the official mono16k diagnostic corpus. Neither this FIR nor the FFT may use
|
|
codec microcode, codec scratch or codec MAC lanes.
|
|
|
|
KWS_CONTROL bits remain ENABLE 0, MEMORY_WINDOW 1 and CLEAR_HISTORY pulse 2.
|
|
An enable rising edge latches continuous input/config, requires valid locked model and
|
|
starts empty history. ENABLE=1/MEMORY_WINDOW=0 is continuous RX; value 3 arms
|
|
memory-window operation without listening. Mode may change only disabled.
|
|
Configuration/clear-history writes require KWS disabled and global idle,
|
|
except KWS_CONFIG may be changed while memory mode is armed and no finite job
|
|
is active. The full-word write that clears ENABLE while retaining mode and
|
|
writing no pulse is additionally legal while KWS is active: stop admitting
|
|
new work, finish the current feature/inference, drain accepted input/DMA,
|
|
then become disabled. It does not abort a concurrent codec job. Mode/config
|
|
changes during this drain are rejected. CLEAR_HISTORY resets feature/peak/FIR
|
|
history, debounce and result-valid, but not the model, counters or IRQ state.
|
|
|
|
Global STATUS.IDLE and the resource idle output still require every client
|
|
idle; continuous listening counts as busy until disabled or quiesced. P7
|
|
separates that global lifecycle condition from finite-job admission: job/ring
|
|
configuration and codec START/RING_KICK may proceed when the finite-job path
|
|
is idle even while continuous KWS runs. This narrow admission exception does
|
|
not permit ACL/model/microcode/route/reset changes during listening. Configure
|
|
and enable continuous KWS before starting concurrent decode. Quiesce drains
|
|
the current KWS work, suppresses new windows and preserves enable/mode/model;
|
|
release resumes with fresh history and a one-second warm-up. If a nonempty
|
|
history was discarded, count one abandoned window, without first-error IRQ.
|
|
Do not combine samples across the gap. Abort disables KWS; soft/resource reset
|
|
clears enable/mode, capture/config registers to reset values, history, results,
|
|
IRQs and counters while preserving valid locked model bytes and actual CRC.
|
|
Forced loss and unilateral resets follow the existing error/CDC precedence.
|
|
|
|
Continuous inference begins only with a complete history, then every 1600
|
|
accepted 16 kHz samples. The deadline is the next such endpoint. The 49-row
|
|
MFCC snapshot must be consumed before its oldest raw-mel row is overwritten;
|
|
no partially updated input tensor may reach inference. A missed deadline,
|
|
mel-ring overwrite or RX overrun abandons that window, increments overrun
|
|
once, clears history/debounce, records code19/stage9 and stops KWS. Recovery
|
|
is bounded disable/drain, RX flush, error/IRQ clear, history clear and enable;
|
|
the validated model is retained. No silent catch-up, sample duplication or
|
|
completion of a corrupted window is allowed. Frontend/inference watchdogs
|
|
use the existing nonzero SEQUENCER_TIMEOUT as a maximum consecutive
|
|
no-progress PCLK-cycle count independently per KWS work item. Progress means
|
|
an accepted PCM sample, completed butterfly/band/feature, completed MAC
|
|
reduction step or committed output tensor element, not merely an active
|
|
state machine. Expiry is code14 at stage9/10 and quiesces the APU. Slow
|
|
PCLK correctness tests may increase that timeout but may not claim 48 MHz
|
|
real-time performance. DMA stalls continue to use DMA_TIMEOUT.
|
|
|
|
| KWS_STATUS bit | Meaning |
|
|
| ---: | --- |
|
|
| 0 | Listening, live continuous capture (not quiesced/draining). |
|
|
| 1 | Inference busy, including preparation of its immutable MFCC snapshot. |
|
|
| 2 | History full, belonging to the current uninterrupted capture epoch. |
|
|
| 3 | Current published result is a stable hit (same as KWS_RESULT bit16). |
|
|
| 4 | Sticky overrun, cleared with the existing stream-xrun IRQ_STATE bit9 W1C or soft/resource/hard reset. A new overrun also raises IRQ9; hardware set wins clear. |
|
|
| 5, 6 | Model valid, model locked. |
|
|
| 7 | Result valid; at least one result has been published since history/reset clear. |
|
|
| 31:8 | Reserved zero. |
|
|
|
|
KWS_MODEL_STATUS bits 0,1,2 are busy, valid, locked. Bits 8,9,10,11,12 are
|
|
header, range, size, CRC and operator/quantization failure respectively;
|
|
all other bits read zero. They are sticky until the next accepted unlocked
|
|
load or reset, with exactly one semantic failure bit selected. Validation
|
|
order is size, header fields in byte order, payload DMA/CRC, then records in
|
|
byte order; range is checked before dereferencing each field. Failures use
|
|
code12/stage1, except CRC uses code13/stage1. ERROR_ADDRESS is the first bad
|
|
field's external byte address (size uses KWS_MODEL_SIZE's APB address; CRC
|
|
uses model base+0x24), and ERROR_DETAIL is `0x07000000 | reason`, reason
|
|
1=size, 2=header, 3=range, 4=CRC, 5=operator/quantization. AXI/timeout/abort
|
|
faults retain their existing codes and precedence. Internal KWS arithmetic
|
|
uses code14/stage9 or10, address equal to the failing local byte address,
|
|
detail `0x07000100 | operator_index` (frontend index 0xff).
|
|
If new KWS and existing codec semantic faults coincide, the pre-existing
|
|
global AXI/lifecycle/xrun precedence still wins; otherwise retain the codec
|
|
fault, then KWS frontend, then KWS inference in that order. Model loading is
|
|
globally exclusive. Collect every applicable sticky event/counter without
|
|
overwriting the first error. Actual model CRC remains zero until the entire
|
|
payload has been received, then reports the observed finalized CRC even if
|
|
subsequent CRC/record validation fails.
|
|
|
|
Choose the lowest class ID on tied final INT8 scores. Class order is Down,
|
|
Go, Left, No, Off, On, Right, Stop, Up, Yes, Silence, Unknown (0..11).
|
|
Unsigned confidence is `int32(softmax[class])+128` (0..255); threshold is an
|
|
inclusive comparison. Only classes 0..9 can be hits. A run increments only
|
|
for the same above-threshold keyword on consecutive completed windows; a
|
|
different class starts at one, and silence/unknown/below-threshold/gap resets
|
|
the run. Emit one stable-hit event when run count first reaches debounce
|
|
(1..255), saturating the run count at debounce, not emitting on later matching
|
|
windows. Hold hit for that uninterrupted
|
|
run; re-arm on the first nonmatching/below-threshold result or explicit clear.
|
|
KWS_RESULT holds every latest completed top-1 result, including non-hits;
|
|
IRQ2 and HIT_COUNT change only on the event edge. IRQ W1C does not re-arm or
|
|
clear the classifier history. Hardware set wins W1C.
|
|
|
|
The timestamp is the 64-bit PCLK timestamp of the accepted last sample of
|
|
the evaluated one-second window, not the time software services the IRQ.
|
|
Reading KWS_RESULT atomically latches its timestamp for subsequent LO/HI
|
|
reads; a later inference cannot tear that pair. A read does not acknowledge
|
|
IRQ or consume the result. Frame, inference, hit and overrun counters are
|
|
unsigned-32 saturating: completed raw-mel frames, completed inferences,
|
|
stable-hit edges and abandoned windows respectively. CLEAR_COUNTERS is
|
|
globally idle-only and clears these without clearing model/history/IRQ.
|
|
|
|
Diagnostic operation 1 uses the existing direct/ring slot, not a second
|
|
concurrent finite job. It requires valid locked microcode (compatibility
|
|
admission only; no codec entry executes), valid locked model and memory mode
|
|
armed; it is rejected while continuous KWS is enabled. CONTROL operation=1,
|
|
format=0, output-mode=0, downmix/resample=0; INPUT_ADDRESS is four-byte aligned,
|
|
INPUT_LENGTH=32000, INPUT_CONFIG explicitly mono/16000/16. OUTPUT_ADDRESS,
|
|
OUTPUT_CAPACITY, OUTPUT_CONFIG and JOB_FLAGS are zero. This is the sole
|
|
operation-1 exception to the decode rule requiring a nonzero memory output.
|
|
All other reserved fields remain zero; OWN/IOC/cookie/ring ordering are
|
|
unchanged. KWS_CONFIG is descriptor word9 for ring jobs and the KWS_CONFIG
|
|
register latched at START for direct jobs. Each independent memory window
|
|
clears debounce history and RESULT_VALID at acceptance, so debounce>1 returns hit=0 even when top-1 is a
|
|
keyword. Accuracy uses top-1, not hit; use debounce=1 for standalone hit tests.
|
|
|
|
Success returns INPUT_USED=32000, OUTPUT_BYTES=0, FRAMES=16000,
|
|
SOURCE_INFO=mono/16000/16, DETAIL=0 and the normal done/cycles/timestamps/cookie;
|
|
descriptor word22 and KWS_RESULT contain the result. No PCM output DMA is
|
|
issued. Direct reads use existing job result registers plus KWS_RESULT;
|
|
ring reads use word22 before slot reuse. A failed/aborted operation sets
|
|
word22=0, does not publish a fresh KWS result or inference/hit count, and
|
|
uses existing terminal writeback/OWN-clear rules. Input-used is the contiguous
|
|
number of successfully consumed bytes, a multiple of two, at failure.
|
|
RESULT_FRAMES on failure is INPUT_USED/2; OUTPUT_BYTES stays zero. A ring may
|
|
mix decode and operation1 entries while memory mode is armed, but cannot
|
|
silently switch a running continuous listener into memory mode.
|
|
Invalid raw direct requests return PSLVERR without payload DMA/result change;
|
|
invalid owned ring requests use code2/stage2 at the first invalid descriptor
|
|
word, DETAIL=`0x07000200 | word_index`, then normal error writeback.
|
|
|
|
### P9 macro-backed auxiliary storage
|
|
|
|
#### Objective, inspected baseline and claim boundary
|
|
|
|
This is a storage/latency refreeze, not a smaller KWS network or a new numerical
|
|
profile. Priority is physical macros first, exact multi-cycle processing second.
|
|
Do not replace the tables with a larger combinational case/mux network, reset-
|
|
initialized flops, a hidden duplicate register file, or approximate CORDIC/log/
|
|
polynomial coefficients to improve a memory statistic. Keep the 16 MAC lanes,
|
|
the model/corpus/APUM hashes, all rounding/overflow rules and proof coverage.
|
|
|
|
The inspected source baseline is commit
|
|
`0b73994772068e5fac00fb1a98f87f88ed121cdf`:
|
|
|
|
| Confirmed from source | P9 action |
|
|
| --- | --- |
|
|
| `apu_kws_sram_client.sv` already has sixteen synchronous 4 KiB physical banks for APUM/scratch, operand coalescing and stall-until-retired control. | Retain that implementation boundary; do not claim these 64 KiB as newly removed inferred memory. |
|
|
| `apu_kws_rom.svh` has 12948 32-bit words; `apu_kws_apum_profile.svh` has 1496 expected APUM words. Multiple combinational calls include repeated twiddle/log/Softmax lookups. | Move all 14444 words (57776 logical bytes) to one shared, banked, immutable-after-load physical store. |
|
|
| `apu_microcode_loader.sv` stores 8192 full 64-bit memo keys and 8192 valid bits as inferred memories: 532480 bits. | Replace both arrays with dedicated physical SRAMs; retain hashing, exact-key comparison and proof traversal. |
|
|
| The 4096x64 proof path stack is already eight SRAM wrappers, separate from eight control-store plus 28 local-data wrappers. | Retain and count it; the full pre-P9 structural inventory is 44 wrappers, not just the 36 advertised-capacity wrappers. |
|
|
| `apu_reg.sv` reports pre-P9 V1.1, CAPABILITY0 `0x1fd`, CAPABILITY1 `0x01827020`, digest `0xf5005d7c` with EnableP7. | Append V1.2 coefficient discovery/control; regenerate the digest from the new complete tables. |
|
|
|
|
The user-supplied synthesis note reports 1900786 whole-SoC inferred bits,
|
|
799680 KWS-table bits and 532480 memo bits for a 2026-09-23 IHP130 run, with
|
|
the long-running pass after memory lowering being `opt_dff -sat -nodffe -nosdff`.
|
|
Those remote raw logs were not available in this checkout and are not newly
|
|
measured evidence. Inferred memories may be padded/duplicated by elaboration;
|
|
the 462208 logical table bits above are not interchangeable with that tool
|
|
statistic. Removing the two reported groups would arithmetically leave 568626
|
|
bits (about 70.1 percent lower), but that is a projection, not a synthesis
|
|
speed, RSS or measured memory claim. Vexii and other IP memories are outside
|
|
P9 scope. Fresh like-for-like reports below are required.
|
|
|
|
Stable requirements:
|
|
|
|
- `APU-P9-001`: IHP130 macro builds MUST contain no inferred coefficient,
|
|
APUM-profile, memo-key or memo-valid memories and no logic-array substitutes.
|
|
- `APU-P9-002`: macro-backed APU inferred storage MUST fall by at least 90
|
|
percent versus the inspected baseline and total at most 65536 bits at the
|
|
same pre-memory checkpoint. Small FIFOs, vector registers and metadata must
|
|
be individually inventoried; target arrays may not be relabeled as metadata.
|
|
- `APU-P9-003`: numerical outputs, accepted/rejected microcode programs, first
|
|
errors, reset/ownership behavior and published results MUST remain equivalent
|
|
apart from the explicitly appended coefficient-init protocol and latency.
|
|
- `APU-P9-004`: extra cycles are permitted within the frozen 20 ms feature /
|
|
100 ms inference schedule, 48 MHz qualification and zero-xrun concurrency
|
|
gates. Cold initialization is measured separately from steady-state latency.
|
|
- `APU-P9-005`: completed same-configuration A/B synthesis, pass timing, peak
|
|
RSS, standard-cell/macro area and STA evidence are mandatory. Smaller
|
|
inferred-bit counts alone are not evidence of a faster or smaller chip.
|
|
|
|
#### Selected macro geometry and bank ownership
|
|
|
|
Reuse `rtl/tech/tc_sram.sv::tc_sram_1024x32`. Under the committed
|
|
`configs/ci/ihp130.mk` (`HAVE_SRAM_MACRO=YES`), each wrapper is one
|
|
`RM_IHPSG13_1P_1024x32_c2_bm_bist` with synchronous reads and byte write masks.
|
|
Use the locked PDK/tool inputs; no new memory compiler or vendor macro is
|
|
selected. Unsupported macro mappings fail elaboration rather than becoming
|
|
flops or undriven wrappers. Non-macro profiles use synchronous inferred RAM
|
|
with the same transactions and LP initialization; they establish functional
|
|
compatibility, not the P9 inferred-memory reduction or physical acceptance.
|
|
|
|
| Full P9 APU allocation | 4 KiB wrappers | Physical KiB |
|
|
| --- | ---: | ---: |
|
|
| Control store | 8 | 32 |
|
|
| Codec/common local data | 12 | 48 |
|
|
| KWS model/scratch | 16 | 64 |
|
|
| Verifier path stack | 8 | 32 |
|
|
| Verifier memo keys | 16 | 64 |
|
|
| Verifier valid bitmap | 1 | 4 (1 KiB used) |
|
|
| Coefficients plus APUM validation profile | 15 | 60 |
|
|
| Total | 76 | 304 |
|
|
|
|
Thus P9 adds exactly 32 wrappers / 128 KiB to the 44-wrapper source baseline.
|
|
Neither verifier nor coefficient banks alias existing code/data/KWS banks.
|
|
CAPABILITY1 continues to describe 32 KiB control + 112 KiB local data, not
|
|
304 KiB software-addressable storage. Physical wrapper and PDK-cell counts
|
|
are different on PDKs that assemble one wrapper from multiple macros.
|
|
|
|
The coefficient payload is fifteen banks of 1024 little-endian 32-bit words,
|
|
bank-major. Payload word `1024*bank+row` maps directly to that macro row.
|
|
The following lossless placement avoids runtime frontend/Softmax bank conflicts
|
|
without duplicating a lookup table:
|
|
|
|
| Bank / row | Stored words / index mapping |
|
|
| --- | --- |
|
|
| 0 / 0..479 | Hann[0..479] |
|
|
| 0 / 480..879 | DCT[j*40+b], j=0..9,b=0..39 |
|
|
| 0 / 880..942; 943..1005 | FIR3[0..62]; FIR6[0..62] |
|
|
| 1 / 0..255; 2 / 0..255 | Twiddle real[0..255]; imaginary[0..255] |
|
|
| 1 / 256..768 | Log[2*r], r=0..512 |
|
|
| 2 / 256..767 | Log[2*r+1], r=0..511 |
|
|
| 3..12 / 0..1023 | Mel[i], i=0..10239, bank=3+floor(i/1024), row=i mod 1024 |
|
|
| 13 / 0..39 | Mel[10240..10279] |
|
|
| 13 / 40..1023 | APUM fixed-profile words[0..983] |
|
|
| 14 / 0..511 | APUM fixed-profile words[984..1495] |
|
|
| 14 / 512..636 | Softmax exp[-difference], difference=0..124 |
|
|
|
|
All other 916 words are zero padding. The profile word order is the current
|
|
generator's sorted unique APUM offsets: every word in `[0,0x500)`, followed
|
|
by the multiplier/shift arrays at the ten weighted-operator offsets. It is
|
|
not a duplicate model or weight image. Preserve the existing candidate-offset
|
|
selection: ordinary weight/bias words that are not profile candidates must
|
|
not acquire an unintended comparison. LN2 remains scalar constant 11629080,
|
|
not an additional ROM array.
|
|
|
|
#### APUC 1.0 image, identity and startup
|
|
|
|
SRAM has no specified power-on contents. A synthesizable initial/readmemh
|
|
block, a macro INIT attribute, or a giant case-ROM that copies itself into
|
|
SRAM is NOT an implementation of this contract. LP loads the generated APUC
|
|
image through the existing private AXI DMA while globally idle/quiesced, then
|
|
hardware validates it and locks the store until hard/PCLK reset. No CPU
|
|
MFCC/inference or runtime coefficient approximation is introduced.
|
|
|
|
APUC has a 64-byte header and 61440-byte payload, total 61504 (`0xf040`) bytes,
|
|
with 64-byte-aligned source address. It is separate from the unchanged
|
|
32768-byte APUM. All header words are little-endian u32:
|
|
|
|
| Byte | Field / required value |
|
|
| ---: | --- |
|
|
| `0x00` | Magic `0x43555041` (bytes APUC). |
|
|
| `0x04` | Container ABI `0x00010000`. |
|
|
| `0x08`, `0x0c` | Total bytes 61504; payload offset 64. |
|
|
| `0x10`, `0x14` | Payload bytes 61440; numerical coefficient profile 1. |
|
|
| `0x18`, `0x1c` | Bank-layout ID 1; bank count 15. |
|
|
| `0x20`, `0x24` | Table count 10; payload CRC `0x25e7c27d`. |
|
|
| `0x28`, `0x2c` | Coefficient ID low `0x8a0b038d`, high `0x806c780d`. |
|
|
| `0x30`, `0x34` | Associated APUM payload CRC `0xb9034b22`; LN2 Q24 11629080. |
|
|
| `0x38`, `0x3c` | Reserved zero. |
|
|
|
|
CRC is the existing CRC-32/ISO-HDLC over exactly bytes `[64,61504)`, including
|
|
zero padding. Source range additions must be checked without wrapping and all
|
|
DMA bytes must remain in the snapshotted inclusive read ACL. Reject an illegal
|
|
size/address/state before payload DMA. Check every fixed header field before
|
|
payload, every padding word, and equality of observed/header/register/frozen
|
|
payload CRC. After writing, read back all 15360 physical words and recompute
|
|
CRC before atomically publishing valid+locked+ID. Readback has an exclusive
|
|
port schedule and must finish within 15364 PCLK cycles once started; pipeline
|
|
one word per cycle, with no clock-gated request left pending. The ready-target
|
|
cold-load acceptance budget is 100000 PCLK cycles from command to publication;
|
|
AXI starvation is separately bounded by DMA_TIMEOUT and reported as stalls.
|
|
|
|
Freeze-time parsing of the committed tables and independent in-memory bank
|
|
packing produced these golden identities (no RTL migration is claimed):
|
|
|
|
| Byte stream | SHA-256 |
|
|
| --- | --- |
|
|
| Logical words in order Hann, real twiddle, imaginary twiddle, Mel, DCT, Log, FIR3, FIR6, Softmax, APUM profile, each word LE32, no delimiters | `f416585119e488c82e5cea1dabb17424e33a16dd8041393135903a613edced46` |
|
|
| 61440-byte physical payload | `8d030b8a0d786c80a7fa072439700a4485711971d79a6a62e78fcafb1657d83a` |
|
|
| Complete APUC image | `d670688442ea6efe1e638108157f55fc55c75218c8edbee931aaca3497567818` |
|
|
|
|
The coefficient ID is the first eight payload-SHA digest bytes interpreted
|
|
little-endian. SHA checks are release/tooling checks; hardware CRC is not
|
|
authentication, anti-rollback or runtime ECC. The authoritative word source
|
|
for migration is the two table files at the inspected commit and the existing
|
|
generator/BAM parity tests, including the current Hz-linear Mel ramps. Do
|
|
not change the numerical profile while changing its storage representation.
|
|
|
|
Extend `scripts/generate_apu_kws_rtl_constants.py` to emit APUC and a bank/
|
|
table/hash manifest from the same exact generators and frozen APUM. Add
|
|
`make CONFIG=configs/ci/ihp130.mk apu-p9-coefficients` as a P9 implementation
|
|
deliverable; it does not exist merely because it is specified here. Generated
|
|
images/reports belong under the variant's `apu/coefficients/` directory.
|
|
Keep old SV lookup functions only as host/test reference collateral, excluded
|
|
from the production synthesizable hierarchy. Extend the release-asset generator
|
|
and LP startup sequence to load microcode, APUC, then APUM before HP handoff.
|
|
Account for the extra 61504 firmware/source bytes without changing a committed
|
|
on-chip SRAM profile or silently truncating an image.
|
|
|
|
#### Additive APB V1.2 and HAL contract
|
|
|
|
P9 appends CAPABILITY0 bit9 = coefficient-load interface and reports
|
|
`IP_VERSION=0x00010002`, qualified release CAPABILITY0 `0x000003fd`, unchanged
|
|
CAPABILITY1 `0x01827020`, and IRQ mask `0x00000fff`. Bit9 describes an interface,
|
|
not whether a particular PDK uses hard macros. Existing COMMAND bits, register
|
|
offsets, descriptor, APUM/APUMC versions, MP3 stub and system IRQ/resource/DMA/
|
|
clock/reset allocations are unchanged. Earlier profiles reject these new
|
|
offsets and bit11 IRQ writes. P9-only software tests discovery before access.
|
|
|
|
| Offset | Register | Access | Reset | Contract |
|
|
| ---: | --- | --- | --- | --- |
|
|
| `0x240` | KWS_COEFF_ADDRESS | RW idle/LP | `0` | 64-byte-aligned DMA source. |
|
|
| `0x244` | KWS_COEFF_SIZE | RW idle/LP | `0` | Exact 61504 bytes. |
|
|
| `0x248` | KWS_COEFF_EXPECTED_CRC | RW idle/LP | `0` | Expected APUC payload CRC. |
|
|
| `0x24c` | KWS_COEFF_COMMAND | WO | `0` | Full-word value 1 starts load; all other values reject. |
|
|
| `0x250` | KWS_COEFF_STATUS | RO | `0` | Busy0, valid1, locked2; header-declared size8, other header9, CRC10, padding11 error flags. |
|
|
| `0x254` | KWS_COEFF_ACTUAL_CRC | RO | `0` | Finalized SRAM-readback CRC, zero until a complete readback. |
|
|
| `0x258` | KWS_COEFF_ID_LO | RO | `0` | Published coefficient ID bits 31:0; zero until success. |
|
|
| `0x25c` | KWS_COEFF_ID_HI | RO | `0` | Published coefficient ID bits 63:32; zero until success. |
|
|
| `0x260` | KWS_COEFF_CAPACITY | RO | `0x0000f000` | Auxiliary payload bytes, not APUM scratch bytes. |
|
|
|
|
RW/WO writes require full-word strobes; reserved status bits read zero and
|
|
RO writes reject. Load admission requires LP owner, globally idle/quiesced,
|
|
disabled KWS, valid read ACL, unlocked coefficient store and no valid model,
|
|
SIZE=61504, aligned ADDRESS and the complete checked image range inside the
|
|
ACL. Failed command admission returns PSLVERR with the existing APB error
|
|
collection; it issues no DMA, leaves loader status unchanged and does not
|
|
raise IRQ11. After an accepted header transfer, mismatched words 0x08/0x10
|
|
are header-declared size errors; other fixed-field mismatches are header errors.
|
|
The DMA grant is exclusive with other APU loaders/jobs, reusing their drain
|
|
and epoch protocol rather than adding a fabric master or CDC. Reuse the P8
|
|
LP-quiesced-loader admission exception: the resource's block-new condition
|
|
must not deadlock the already admitted asset load. Global busy/idle includes
|
|
coefficient DMA, readback and all pending SRAM responses. An accepted
|
|
load snapshots address/size/CRC/ACL, clears unlocked diagnostics/ID/actual CRC,
|
|
and keeps both coefficient-valid and model execution clear until success.
|
|
|
|
Terminal success/failure raises new local IRQ11; failures also collect the
|
|
existing first-error IRQ8 and counters. Size/header/padding faults use code12,
|
|
stage1, CRC/readback faults code13/stage1. ERROR_DETAIL is
|
|
`0x09000000 | reason`, reason 1=header-declared size, 2=header, 3=payload CRC,
|
|
4=padding, 5=readback CRC. ERROR_ADDRESS is the first bad external size/header/
|
|
padding word or byte (size uses source+0x08 or source+0x10), or source+0x24 for either CRC
|
|
failure respectively. Bus/timeout faults keep codes15/17 and their existing
|
|
address/response precedence; semantic error flags stay zero for bus/abort
|
|
faults. For coexisting semantic errors choose size, header-byte order, padding-
|
|
byte order, payload CRC, then readback CRC; incomplete/failed DMA outranks
|
|
checks requiring its missing bytes. Failures never publish valid/lock/ID.
|
|
|
|
A successful coefficient lock is irrevocable until hard/PCLK reset. A failed
|
|
or aborted load is retryable after drain/recovery and cannot execute partial
|
|
contents. A clean abort emits abort-done, not IRQ11 or first error; forced
|
|
loss retains existing lifecycle precedence. Soft/resource reset cancels an
|
|
unpublished load but retains a validated locked coefficient image and its
|
|
readback CRC/ID, just as it retains a validated model. It resets configuration
|
|
registers and unlocked diagnostics, not retained SRAM contents. Hard reset
|
|
invalidates coefficient and model locks together and requires both loads again.
|
|
No macro array is asynchronously reset; flags and pending-response state are.
|
|
Quiesce/owner handoff cannot expose half-loaded assets, and HP cannot load,
|
|
write, unlock or alias these banks.
|
|
|
|
On V1.2, MODEL_LOAD and KWS enable/operation1 require coefficient valid+locked
|
|
with profile1/associated-model identity in addition to their existing checks.
|
|
APUM1 is still accepted byte-for-byte after APUC initialization. An old firmware
|
|
that never initializes APUC must fail closed, not find a hidden ROM fallback;
|
|
a HAL that only accepts V1.1 must be updated to negotiate V1.2. WAV/FLAC-only
|
|
work needs no coefficient load. Existing numerical/result/descriptor timestamps
|
|
and model-lock semantics do not change.
|
|
|
|
Append, without resizing existing public structs:
|
|
|
|
```c
|
|
typedef struct {
|
|
uint32_t status;
|
|
uint32_t actual_crc;
|
|
uint32_t coefficient_id[2];
|
|
uint32_t capacity_bytes;
|
|
} rs_apu_kws_coeff_status_t;
|
|
|
|
rs_status_t rs_apu_kws_coeff_load(const rs_apu_image_t *image, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_kws_coeff_status_read(rs_apu_kws_coeff_status_t *status);
|
|
```
|
|
|
|
Load is bounded/blocking, with existing image address/bytes/expected_crc and
|
|
poll budget `max(1,timeout)`. It validates state/range/cache visibility before
|
|
MMIO, starts the new command, then requires valid+locked, expected CRC and
|
|
coefficient ID for RS_OK. Use RS_ENOTSUP for missing interface/version,
|
|
RS_EINVAL for caller/state/range failures, RS_EFORMAT for hardware size/header/
|
|
padding rejection, RS_EIO for CRC/bus/internal failures, RS_ETIMEOUT for
|
|
exhausted polling. Timeout does not release buffers, cancel DMA, clear IRQs or
|
|
reset the APU. Use explicit abort/drain recovery. Status read is non-consuming.
|
|
Update the existing probe to accept supported minor versions 0,1,2; model/
|
|
enable helpers check the new readiness only when bit9 is advertised.
|
|
|
|
Independently append RTL/C constants, parity fixtures, Python image definitions
|
|
and the APUC schema/identity to `scripts/apu_abi_digest.py`'s canonical inventory.
|
|
Keep its existing serialization/CRC algorithm. The pre-P9 `0xf5005d7c` digest
|
|
is not valid for V1.2; compute and review the new nonzero value during P9
|
|
implementation, and require RTL/C/tool equality before release. Partial
|
|
implementations report zero rather than advertising the old complete digest.
|
|
|
|
#### Coefficient access, latency and exact multi-cycle arithmetic
|
|
|
|
Coefficient/profile reads are synchronous transactions, not calls to a large
|
|
combinational function. A frontend request carries kind and index; kinds are
|
|
Hann=0, twiddle pair=1, Mel=2, DCT=3, Log pair=4, FIR3=5, FIR6=6. Softmax
|
|
and APUM profile use kind codes 7 and 8 for diagnostics. The response returns one
|
|
32-bit word or `{imaginary,real}` / `{L[i+1],L[i]}` as appropriate. Single-word
|
|
responses have zero in the unused upper half. Preserve each old function's
|
|
signed/unsigned interpretation at its arithmetic consumer; SRAM returns raw
|
|
bits, not a newly sign-extended numerical format. Legal index
|
|
ranges are 0..479, 0..255, 0..10279, 0..399, 0..1023, 0..62, 0..62. Both Log
|
|
words always occupy different banks, including i=1023. A separate inference
|
|
request reads Softmax differences 0..124 from bank14. Model validation alone
|
|
uses the 1496-word profile read port and is globally exclusive with runtime.
|
|
|
|
Allow one outstanding request per frontend/inference/profile client, stable
|
|
payload until ready, and a retained response until consumed. Without consumer
|
|
backpressure, an accepted request returns in at most two PCLK cycles (macro
|
|
read plus response register). Frontend and inference requests may be accepted
|
|
together; their banks never conflict in this layout. Model/APUC loading owns
|
|
the banks exclusively. Illegal kind/index or invalid-store access returns a
|
|
bounded fault, not default zero or a masked address. Use code14/stage9 or10
|
|
for engine access faults and code12/stage1 for a model-profile access fault;
|
|
detail `0x09000100 | kind`, address=4*requested logical table index. It is not
|
|
a new CPU-addressable window.
|
|
|
|
Issue coefficient and existing scratch requests in parallel where both are
|
|
needed. Snapshot work identity, indices and operands and commit an arithmetic
|
|
step exactly once only when both responses belong to that work item. Reuse
|
|
the returned twiddle pair for all four products and the same L[i] for the
|
|
interpolation/base term; never replicate the large ROM to gain read ports.
|
|
Small response/operand holding registers are allowed, not a shadow table.
|
|
Abort/reset/epoch change discards stale responses before new work; a blocked
|
|
response does not count repeatedly as watchdog progress. Actual request issue,
|
|
retired response, arithmetic iteration or scratch commit is progress.
|
|
|
|
Additional pipeline/iterative cycles MUST preserve exact signed widths,
|
|
RNE/TZ, Softmax scalar behavior and overflow faults. In particular the existing
|
|
96-bit log normalization/divisions may be serialized using exact integer
|
|
operations (at most 320 arithmetic PCLK cycles per band, excluding explicitly
|
|
counted operand stalls), and nearest-isqrt may use at most 40 arithmetic cycles
|
|
per bin. These are ceilings, not required delays or approximation permissions.
|
|
No coefficient-generation CORDIC, smaller/recalibrated model, new LUT values,
|
|
changed hop/window/threshold or reduced MAC-lane count is authorized.
|
|
|
|
Every lookup wait and iteration contributes to measured KWS cycles. Preserve
|
|
SEQUENCER_TIMEOUT as a consecutive no-progress bound, not a total-job budget;
|
|
do not enlarge its reset value to mask a stalled handshake. The 100 ms window
|
|
deadline and protection against overwriting the oldest of the 49 mel rows
|
|
remain blocking even if individual transactions meet their local bounds.
|
|
Qualify actual combined SRAM/arithmetic scheduling, not an ideal zero-latency
|
|
lookup model. Other clock dividers make no new real-time claim.
|
|
|
|
#### Macro-backed microcode proof memo
|
|
|
|
Keep PathMemoDepth=8192 for expanded P5/P9, the existing full 64-bit key
|
|
`{loop_active,return_pc[3:0],pc}`, hash constant `0x9e3779b97f4a7c15`, hash
|
|
selection, linear probing and exact-key equality. Do not shorten keys, use
|
|
hash-only matches, evict entries, skip deeper proof paths or lower path limits
|
|
to save hardware. The call-depth>2 bypass, full-table normal-traversal fallback,
|
|
V1/V2 traversal limits 131072/262144 and path-stack bounds remain unchanged.
|
|
|
|
Map entry i to key bank-pair `floor(i/1024)` (0..7), row `i mod 1024`, low/high
|
|
words in two 1024x32 macros, sixteen in total. The seventeenth macro stores
|
|
valid bits: row `floor(i/32)` (0..255), bit `i mod 32`; other rows are unused.
|
|
Read key halves and bitmap word in parallel, latch them synchronously, then
|
|
perform the existing comparison/probe decision. One lookup/probe requires at
|
|
most four PCLK cycles including controller staging. Insert both key halves
|
|
and the previously read bitmap word OR its selected valid bit as one logical
|
|
commit; never publish a valid bit before both key writes. Only one proof
|
|
transaction is outstanding, so bitmap read/modify/write cannot lose an update.
|
|
|
|
Before every memoized entry proof and every restarted load, clear the 256 used
|
|
bitmap rows and drain the final write (at most 260 cycles). Keys need not be
|
|
reset. Abort during clear/lookup/insert must drain at most the accepted
|
|
transaction, suppress image publication and restart a complete clear on retry.
|
|
Soft/resource reset never makes stale memo contents usable for a new proof.
|
|
Use synchronous full-word writes, not a resettable 8192-bit valid flop vector.
|
|
The actual checked path-visit counter still counts proof states, not SRAM
|
|
service cycles; report visits, memo hits/probes/full events and wall cycles
|
|
separately. Bounded probing/clearing must not be hidden from abort/idle logic.
|
|
Smaller power-of-two depths used by directed tests retain their existing
|
|
semantics; they are not permission to shrink the production table.
|
|
|
|
### HAL and compatibility
|
|
|
|
`<retrosoc/hal/apu.h>` owns discovery, ACL, microcode/model load, direct/ring
|
|
submit, stream routing, KWS, interrupt, error, statistics, bounded wait, abort,
|
|
and reset. Fallible functions return `rs_status_t` and waits take a timeout.
|
|
`<retrosoc/hal/apu_regs.h>` independently mirrors every public constant.
|
|
|
|
The APB/job ABI is append-only within major version 1. Existing offsets,
|
|
job-descriptor size, opcode/format/error/IRQ IDs, ownership, and lock semantics
|
|
retain their meaning. APB V1.1 adds PC_HIGH and capacity discovery without
|
|
moving an existing field. APUMC has its own binary/ISA version: legacy V1 is
|
|
immutable, and the approved V2 widens its entry-PC and branch fields with
|
|
explicit version negotiation. `APUM` model ABI does not change. Software fails
|
|
closed on unknown major versions in the relevant namespace, not by equating
|
|
APB `IP_VERSION` to `MC_ABI`.
|
|
|
|
The updated P5 HAL accepts APB major 1, minor 0 or 1 for the supported legacy
|
|
and expanded profiles, comparing the extracted major against 1 rather than
|
|
against the full V1.1 word. It reads actual control-store KiB from CAPABILITY1.
|
|
Release software targeting APUMC V2 requires APB V1.1 with 32 KiB before
|
|
submitting that image. The existing microcode-load API and image structure
|
|
remain unchanged; the hardware validates header word 1, and successful HAL
|
|
load accepts/readbacks the corresponding MC_ABI 1.0 or 2.0. It must not require
|
|
MC_ABI to be 1.0 on a valid V2 load or infer it from image size. Unknown image
|
|
versions retain the existing header-failure/RS_EIO path. Existing legacy
|
|
software can submit V1 images to expanded hardware; software displaying full
|
|
PCs must use PC_HIGH or the full trap address. Functional PCM/job/error rules
|
|
and every public HAL function signature remain unchanged.
|
|
|
|
`STREAM_WATERMARK` at `0x060` is the sole P2 ABI append. P1 continues to return
|
|
`PSLVERR` for that formerly reserved offset, while P2 implements it; no P1
|
|
offset, accepted field, reset value, or reserved mask is repurposed. P2 updates
|
|
the independently handwritten SVH/C tables and parity tests together.
|
|
|
|
### P5 HAL contract
|
|
|
|
The following declarations are the required P5 additions to
|
|
`<retrosoc/hal/apu.h>`, implemented in `crt/src/hal/apu.c` with deterministic
|
|
packing/validation tests. They describe software interfaces to implement in
|
|
P5; this freeze does not add code. Existing `rs_apu_probe`, `rs_apu_info_t`,
|
|
`rs_apu_descriptor_t`, and every 128-byte descriptor member offset are retained.
|
|
Enums use the already frozen integer encodings. These host-side structures
|
|
are not DMA wire formats; only `rs_apu_descriptor_t` is the shared layout.
|
|
|
|
```c
|
|
typedef enum { RS_APU_WAV = 0, RS_APU_MP3 = 1, RS_APU_FLAC = 2 } rs_apu_format_t;
|
|
typedef enum { RS_APU_MEMORY = 0, RS_APU_I2S = 1 } rs_apu_output_t;
|
|
typedef enum { RS_APU_S16 = 0, RS_APU_S24_32 = 1 } rs_apu_pcm_t;
|
|
|
|
typedef struct {
|
|
rs_apu_format_t format;
|
|
rs_apu_output_t output;
|
|
rs_apu_pcm_t pcm;
|
|
uint32_t input_address, input_bytes;
|
|
uint32_t output_address, output_capacity;
|
|
uint32_t expected_rate, expected_channels, expected_bits;
|
|
uint32_t output_rate, output_channels;
|
|
uint32_t downmix, resample, strict; /* each exactly zero or one */
|
|
uint32_t cookie[2];
|
|
} rs_apu_job_t;
|
|
|
|
typedef struct { uint32_t address, bytes, expected_crc; } rs_apu_image_t;
|
|
typedef struct { uint32_t status, address, detail; } rs_apu_error_t;
|
|
typedef struct {
|
|
uint32_t status; /* descriptor RESULT_STATUS encoding, including direct */
|
|
uint32_t input_used, output_bytes, frames, source_info, cycles, detail;
|
|
uint32_t cookie[2], start_timestamp[2], finish_timestamp[2];
|
|
uint32_t microcode_build_id;
|
|
rs_apu_error_t first_error;
|
|
} rs_apu_result_t;
|
|
|
|
typedef struct {
|
|
rs_apu_descriptor_t *descriptors; /* aligned CPU mapping, caller-owned */
|
|
uint32_t dma_address, entries, tail;
|
|
} rs_apu_ring_t;
|
|
|
|
rs_status_t rs_apu_set_acl(uint32_t read_base, uint32_t read_limit,
|
|
uint32_t write_base, uint32_t write_limit);
|
|
rs_status_t rs_apu_microcode_load(const rs_apu_image_t *image, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_validate_job(const rs_apu_job_t *job);
|
|
rs_status_t rs_apu_submit_direct(const rs_apu_job_t *job);
|
|
rs_status_t rs_apu_wait_direct(rs_apu_result_t *result, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_decode(const rs_apu_job_t *job, rs_apu_result_t *result,
|
|
rs_timeout_t timeout);
|
|
rs_status_t rs_apu_ring_configure(rs_apu_ring_t *ring, uint32_t stop_on_error,
|
|
uint32_t coalesce_count, uint32_t coalesce_timeout);
|
|
rs_status_t rs_apu_ring_submit(rs_apu_ring_t *ring, const rs_apu_job_t *job,
|
|
uint32_t ioc, uint32_t *slot);
|
|
rs_status_t rs_apu_ring_result(const rs_apu_ring_t *ring, uint32_t slot,
|
|
rs_apu_result_t *result, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_ring_disable(rs_timeout_t timeout);
|
|
rs_status_t rs_apu_stream_route(uint32_t tx_route, uint32_t rx_route);
|
|
rs_status_t rs_apu_abort(rs_timeout_t timeout);
|
|
rs_status_t rs_apu_soft_reset(void);
|
|
rs_status_t rs_apu_error_read(rs_apu_error_t *error);
|
|
rs_status_t rs_apu_error_clear(void);
|
|
rs_status_t rs_apu_irq_read(uint32_t *state);
|
|
rs_status_t rs_apu_irq_enable(uint32_t mask);
|
|
rs_status_t rs_apu_irq_ack(uint32_t mask);
|
|
```
|
|
|
|
All pointers are mandatory; addresses are 32-bit DMA addresses, never silently
|
|
truncated CPU pointers. Validation rejects unknown enums, nonboolean flags,
|
|
reserved fields, misalignment, overflow, overlap, unsupported capabilities,
|
|
and invalid capacity/route combinations before any job-register mutation.
|
|
Header-dependent checks are performed by APU microcode after submission, not
|
|
by reading the file on LP/HP. Direct submission packs the same descriptor
|
|
words into `JOB_*`, fences, and issues START once; it is asynchronous.
|
|
`rs_apu_decode` is exactly submit-direct followed by wait-direct. Direct
|
|
results normalize `JOB_STATUS` into descriptor-result bit positions; direct
|
|
cookie is the saved submitted cookie, and direct start/finish timestamps are
|
|
zero because no corresponding APB registers exist. The direct build ID is
|
|
read from the locked MC build ID. `first_error` is a raw snapshot of the global
|
|
first-error tuple and may belong to an earlier fault; per-job status/detail
|
|
are authoritative for the returned job. No API implicitly clears first error.
|
|
|
|
`rs_timeout_t` uses the existing unsigned poll-budget convention here: timeout
|
|
`n` permits at most `max(1,n)` status observations; zero is a nonblocking
|
|
single observation, not infinite. `RS_TIMEOUT_DEFAULT` is the existing SDK
|
|
default. A poll has no assumed wall-clock duration. Exhaustion returns
|
|
`RS_ETIMEOUT`, leaves the output result structure untouched, and does not
|
|
abort, reset, release buffers, or retry a command. An admitted operation can
|
|
still be active; buffers remain owned until a later successful terminal wait
|
|
or drained abort. A successful poll populates the complete result even when
|
|
its terminal status maps to a nonzero `rs_status_t`.
|
|
|
|
Return mapping: `RS_EINVAL` for invalid arguments, range/packing violations,
|
|
or illegal idle/owner conditions; `RS_ENOTSUP` for a clear required capability
|
|
or error code 3; `RS_ENOSPC` for full software ring or reason `0x0051` capacity
|
|
exhaustion; `RS_ETIMEOUT` for poll exhaustion; `RS_EFORMAT` for codec codes
|
|
4..7; `RS_EIO` for hardware DMA, trap, overflow, abort, or other terminal
|
|
failures. Successful operation is `RS_OK`. Busy is not encoded as success;
|
|
terminal DMA timeout is `RS_EIO` with hardware code 17, distinct from a HAL
|
|
poll budget expiring while hardware is still running.
|
|
|
|
The caller owns resource acquisition/quiesce, I2S setup, cache maintenance,
|
|
and serialization between LP/HP/interrupt contexts. APU HAL calls never
|
|
transfer resource ownership, decode on the host, allocate memory, or load a
|
|
replacement image automatically. ACL programming and microcode load are
|
|
LP-only and quiesced/idle; a locked image returns `RS_EINVAL` without trying
|
|
to unlock it. Load waits for busy to clear, then checks MC valid/lock/CRC and
|
|
returns the frozen loader result. Timeout does not cancel the load.
|
|
|
|
Ring configure requires idle with ring disabled, 2..256 power-of-two entries,
|
|
128-byte-aligned CPU/DMA bases, a non-cacheable descriptor mapping, boolean
|
|
stop-on-error, count 1..255, and timeout 1..65535. It programs
|
|
base/size/coalescing, tail zero, then enables;
|
|
software must have cleared every OWN bit before configuring. At most
|
|
`entries-1` slots are queued to disambiguate head==tail. Submit fills a free
|
|
slot, zeros result/reserved/KWS words, preserves the requested cookie, writes
|
|
OWN last, fences, advances tail, and rings the doorbell. The P5 ring helper
|
|
requires non-cacheable descriptor storage so no cache-maintenance callback is
|
|
needed between its payload stores and OWN publication. Payload-buffer cache
|
|
clean/invalidate remains the caller's responsibility before submit and after
|
|
completion; manual cached-descriptor operation still follows the existing P2
|
|
CBO contract. Submit does not wait. Result polling observes OWN clear with
|
|
an acquire fence and then copies the immutable descriptor
|
|
result. A slot with OWN clear and no terminal result is not a completed job
|
|
and returns `RS_EINVAL`; callers must collect a slot before resubmitting it.
|
|
Result polling never recycles or advances a producer slot. Ring disable uses abort
|
|
when active, waits for idle, then clears enable. Abort on an idle APU is a HAL
|
|
no-op returning OK; otherwise it issues ABORT once and waits for idle/abort
|
|
completion. Soft reset requires idle and preserves the locked bundle.
|
|
|
|
`rs_apu_stream_route` changes the requested directions only after checking
|
|
their active state and P5 directional capabilities; it preserves the P2
|
|
same-value write rule. IRQ enable replaces the enable mask, IRQ ack W1C-clears
|
|
only requested implemented bits, and reads never clear. Invalid mask bits are
|
|
`RS_EINVAL`. Error clear writes only ERROR_STATUS valid/W1C and cannot clear a
|
|
same-cycle hardware fault. None of these calls changes existing IRQ routing.
|
|
|
|
### P7 HAL additions
|
|
|
|
These declarations are frozen additions to `<retrosoc/hal/apu.h>` for
|
|
implementation in `crt/src/hal/apu.c`. Existing P5 structures/functions and
|
|
the 128-byte descriptor retain their layout and signatures. The new structs
|
|
are host-side objects, not DMA wire layouts; all flags/enumerated integers
|
|
must be range checked. No dynamic allocation or hosted-library dependency is
|
|
permitted. Independently extend `apu_regs.h` and `apu_define.svh`, and maintain
|
|
handwritten Python APUM constants and deterministic parity tests.
|
|
|
|
```c
|
|
typedef struct {
|
|
uint32_t threshold; /* 0..255, inclusive */
|
|
uint32_t debounce; /* 1..255 */
|
|
uint32_t input_rate; /* 16000, 48000 or 96000 */
|
|
uint32_t input_bits; /* 16 or 24; physical I2S channels fixed at two */
|
|
} rs_apu_kws_config_t;
|
|
|
|
typedef struct {
|
|
uint32_t input_address; /* exactly 32000 mono S16_LE bytes */
|
|
uint32_t threshold;
|
|
uint32_t debounce;
|
|
uint32_t cookie[2];
|
|
} rs_apu_kws_job_t;
|
|
|
|
typedef struct {
|
|
uint32_t class_id;
|
|
uint32_t score;
|
|
uint32_t hit;
|
|
uint32_t timestamp[2]; /* low, high; evaluated-window endpoint */
|
|
} rs_apu_kws_result_t;
|
|
|
|
typedef struct {
|
|
uint32_t status;
|
|
uint32_t model_status;
|
|
uint32_t model_crc;
|
|
uint32_t frame_count;
|
|
uint32_t inference_count;
|
|
uint32_t hit_count;
|
|
uint32_t overrun_count;
|
|
} rs_apu_kws_status_t;
|
|
|
|
typedef struct {
|
|
rs_apu_result_t job;
|
|
uint32_t class_id;
|
|
uint32_t score;
|
|
uint32_t hit;
|
|
} rs_apu_kws_completion_t;
|
|
|
|
rs_status_t rs_apu_kws_model_load(const rs_apu_image_t *image, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_kws_configure(const rs_apu_kws_config_t *config);
|
|
rs_status_t rs_apu_kws_enable(uint32_t memory_window);
|
|
rs_status_t rs_apu_kws_disable(rs_timeout_t timeout);
|
|
rs_status_t rs_apu_kws_clear_history(void);
|
|
rs_status_t rs_apu_kws_status_read(rs_apu_kws_status_t *status);
|
|
rs_status_t rs_apu_kws_result_read(rs_apu_kws_result_t *result);
|
|
rs_status_t rs_apu_kws_validate_job(const rs_apu_kws_job_t *job);
|
|
rs_status_t rs_apu_kws_submit_direct(const rs_apu_kws_job_t *job);
|
|
rs_status_t rs_apu_kws_wait_direct(rs_apu_kws_completion_t *result, rs_timeout_t timeout);
|
|
rs_status_t rs_apu_kws_ring_submit(rs_apu_ring_t *ring, const rs_apu_kws_job_t *job,
|
|
uint32_t ioc, uint32_t *slot);
|
|
rs_status_t rs_apu_kws_ring_result(const rs_apu_ring_t *ring, uint32_t slot,
|
|
rs_apu_kws_completion_t *result, rs_timeout_t timeout);
|
|
```
|
|
|
|
- `model_load` is blocking and reuses rs_apu_image_t's DMA address, exact byte
|
|
size and expected payload CRC. Validate size=32768, alignment, checked
|
|
inclusive ACL range, LP ownership, quiesce/global idle, disabled KWS and
|
|
unlocked model; perform the same CBO/fence discipline as microcode load.
|
|
Program the three existing model registers, issue COMMAND bit5, and poll
|
|
KWS_MODEL_STATUS. Success requires valid AND locked and matching actual CRC.
|
|
No unlock, implicit hard reset, IRQ acknowledgement or retry is hidden.
|
|
- `configure` requires disabled/global idle, packs the two fields of
|
|
KWS_CONFIG and the appended KWS_INPUT_CONFIG, and preserves all other
|
|
settings. It does not configure I2S, change route or clear history/errors.
|
|
`enable(memory_window)` accepts only 0/1, validates capability/model/owner
|
|
and nonquiesced admission, and writes control 1 or 3. Continuous mode also
|
|
requires RX route1; the caller is responsible for matching I2S settings.
|
|
No codec microcode executes in either KWS mode.
|
|
- `disable` initiates the KWS-only bounded drain, preserving mode. Poll until
|
|
ENABLE reads zero and both listening/inference-busy clear; hardware keeps
|
|
ENABLE readback one until drain completes. Already-disabled is RS_OK. Do
|
|
not abort a concurrent codec job or silently reroute RX to central DMA.
|
|
`clear_history` issues only bit2 while disabled/global idle, preserving
|
|
mode and model lock. Neither call clears unrelated IRQ or first-error state.
|
|
- `status_read` returns the raw status/model words, actual CRC and individual
|
|
monotonic counters. These live counter reads are not a multi-register
|
|
atomic snapshot; use the existing PERF snapshot for cycle comparisons.
|
|
`result_read` checks RESULT_VALID, reads KWS_RESULT (latching its timestamp),
|
|
then timestamp LO/HI, and decodes class/score/hit. It returns the latest
|
|
valid result without consuming it; no-result returns RS_ETIMEOUT immediately.
|
|
- `validate_job` is pure, performs no MMIO and validates nonnull pointer,
|
|
four-byte alignment, checked 32000-byte range and threshold/debounce.
|
|
Submit functions additionally check capability, model/microcode locks,
|
|
owner/quiesce/ACL state and armed memory mode. They are nonblocking:
|
|
pack operation1 exactly as above and either issue START or publish the
|
|
owned ring entry with the existing cache/fence/doorbell discipline. Ring
|
|
submission preserves caller cookie and sets IOC from exactly 0/1. Do not
|
|
call the P5 WAV decoder to process these raw PCM bytes.
|
|
- `wait_direct` and `ring_result` are bounded completion readers with normal
|
|
P5 job/result/error semantics. Read descriptor word22 only after completed
|
|
OWN-clear and cache invalidation, before the caller reuses that slot; ring
|
|
results use that word, not the newest global result. Both completion APIs
|
|
return the unchanged job START/FINISH timestamps in `job`; they do not
|
|
claim a per-descriptor capture-endpoint timestamp. On a failed job, zero
|
|
the returned class_id/score/hit fields and return its error;
|
|
a previous successful global result is never presented as the failed job.
|
|
|
|
The global KWS result reports a capture endpoint, whereas the immutable
|
|
descriptor records job start/finish. All START/FINISH fields keep their
|
|
original meanings, including operation1. A per-descriptor capture-endpoint
|
|
timestamp is explicitly deferred because it requires a new descriptor ABI.
|
|
|
|
All fallible APIs use existing rs_status_t values: RS_EINVAL for null/range/
|
|
state/ownership/mode errors; RS_ENOTSUP for missing KWS or unsupported APB
|
|
major version (test discovery before touching the P7-only offset); RS_EFORMAT
|
|
for model size/header/range/operator rejection (code12); RS_EIO for CRC,
|
|
AXI, arithmetic and other hardware terminal failures; RS_ETIMEOUT for an
|
|
exhausted poll budget; RS_OK only on the specified successful state/result.
|
|
Waits use the existing rs_timeout_t poll budget `max(1,timeout)`, not
|
|
milliseconds and never an infinite wait. Timeout does not transfer ownership,
|
|
clear OWN, unlock the model, acknowledge IRQs or cancel outstanding DMA.
|
|
The caller retains input storage until bounded disable/abort/drain confirms
|
|
completion; global abort/reset is an explicit caller decision. Existing
|
|
rs_apu_irq_* and error APIs manage IRQ2/4/8/9 without new interrupt allocation.
|
|
The owner driver serializes register configuration, submission and result
|
|
reads; these freestanding APIs add no OS lock and are not implicitly reentrant.
|
|
|
|
Deterministic host tests cover exact packing/offsets and model CRC, every
|
|
rejection and return mapping, zero/one/max timeouts, no-MMIO pure validation,
|
|
no writes after failed validation, result freshness, ring slot reuse, cache
|
|
ordering, and P5 discovery fail-closed behavior. The implementation must review
|
|
applicable MISRA rules and add a reviewed deviation only if actually needed;
|
|
this documentation freeze grants no new MISRA deviation.
|
|
|
|
## Clock, Reset, CDC/RDC, and Lifecycle
|
|
|
|
APB4, DMA source, sequencer, local SRAM, fixed engines, KWS, and stream router
|
|
run in PCLK. Mini caps PCLK at 48 MHz. Correctness is required at all supported
|
|
dividers; real-time MVP performance is qualified only at 48 MHz.
|
|
|
|
I2S retains `clk_aud_i`, `rst_aud_n_i`, and existing `cdc_2phase`/
|
|
`cdc_fifo_warm_flush` crossings to PCLK. APU consumes only synchronized PCLK
|
|
streams. APU AXI crosses PCLK to HP through the existing Common warm-flush
|
|
bridge. Topology adds an `apu_data` crossing to the clock/reset inventory;
|
|
internal streams remain same-domain.
|
|
|
|
- Hard/PCLK reset invalidates microcode/model, clears their locks, denies DMA,
|
|
and clears jobs, KWS history, IRQ, errors, and counters.
|
|
- Soft reset is idle-only. It resets scheduler, sequencer, engines, streams,
|
|
KWS history, IRQ, and first error while preserving validated locked
|
|
microcode/model and ACLs.
|
|
- Busy recovery is abort, wait abort-done/idle, then soft reset. Busy soft reset
|
|
returns `PSLVERR`.
|
|
- Resource reset blocks new work, drains accepted AXI/stream traffic, then uses
|
|
soft-reset semantics.
|
|
- Quiesce blocks new jobs, stops sequencer at a frame/block boundary, stops KWS
|
|
after the current feature/inference, drains DMA/output, and reports idle only
|
|
after all engines/FIFOs and Gateway A are idle.
|
|
- Microcode/model load is legal only with LP owner, quiesced, idle, valid ACL,
|
|
and corresponding lock clear. HP cannot load or unlock them.
|
|
- Owner change follows Resource Controller block-new, CDC acknowledgement,
|
|
drain, owner update, and release. Retained KWS enable resumes under the new
|
|
owner; the finite gap is counted.
|
|
|
|
Unilateral HP reset does not reset PCLK APU state. The AXI bridge warm-flushes
|
|
and the active job waits for recovery or timeout. Unilateral PCLK reset
|
|
invalidates local state and requires bridge epoch recovery. The inventory and
|
|
formal checks do not replace commercial CDC/RDC signoff.
|
|
|
|
## Errors, Recovery, Security, and Observability
|
|
|
|
### Error allocation
|
|
|
|
| Code | Meaning |
|
|
| ---: | --- |
|
|
| 0 | no error |
|
|
| 1 | invalid configuration/APB command |
|
|
| 2 | invalid descriptor/ring |
|
|
| 3 | unsupported format/feature |
|
|
| 4 | malformed container/header |
|
|
| 5 | truncated stream |
|
|
| 6 | codec CRC/checksum |
|
|
| 7 | entropy/decode failure |
|
|
| 8 | reconstruction/resampler/PCM failure |
|
|
| 9 | invalid microcode header/range/control flow |
|
|
| 10 | microcode CRC/capability failure |
|
|
| 11 | sequencer trap/watchdog |
|
|
| 12 | invalid KWS model/coefficient header, range or operator |
|
|
| 13 | KWS model/coefficient CRC |
|
|
| 14 | KWS arithmetic/tensor failure |
|
|
| 15 | AXI read response/protocol |
|
|
| 16 | AXI write response/protocol |
|
|
| 17 | DMA timeout |
|
|
| 18 | stream underrun |
|
|
| 19 | stream overrun |
|
|
| 20 | abort terminal result |
|
|
| 21 | resource reset/forced lifecycle termination |
|
|
| 22 | FIFO/local-memory/arithmetic overflow |
|
|
| 23-63 | reserved |
|
|
|
|
Stages are APB/config 0, loader 1, descriptor/ring 2, DMA read 3, bitstream 4,
|
|
entropy 5, reconstruction/transform 6, resampler/PCM 7, DMA write/stream 8, KWS
|
|
frontend 9, KWS inference 10, and sequencer-control/lifecycle 11.
|
|
|
|
First error is immutable until W1C/reset. Later faults increment counters but
|
|
do not overwrite code, stage, address/PC, detail, AXI response, or descriptor
|
|
index. A requested, successfully drained abort or quiesced resource reset sets
|
|
terminal status/IRQ but not first error; code20/21 enters first error only when
|
|
forced, timed out, or accepted work was lost.
|
|
|
|
Simultaneous terminal conditions use this fixed first-error precedence:
|
|
|
|
1. Hard/PCLK reset clears all status and records no retained error.
|
|
2. Forced resource reset or lifecycle loss records code21.
|
|
3. AXI write response/protocol failure records code16.
|
|
4. AXI read response/protocol failure records code15.
|
|
5. DMA no-progress timeout records code17.
|
|
6. RX stream overrun records code19.
|
|
7. TX stream underrun records code18.
|
|
8. A forced abort records code20.
|
|
|
|
A normal resource reset or successfully drained software abort is not an error.
|
|
When several non-reset events coincide, every applicable sticky IRQ/status and
|
|
counter is updated, but only the highest item above enters the immutable first
|
|
error. An AXI fault observed while abort drains therefore outranks abort. RX
|
|
overrun outranks TX underrun because it represents lost input. Hardware event
|
|
capture outranks a same-cycle first-error or IRQ W1C.
|
|
|
|
Format errors terminate the owning job. AXI protocol loss, sequencer trap,
|
|
watchdog, impossible internal state, or repeated timeout quiesces the whole APU
|
|
until abort/reset. Bad microcode/model never publishes valid or unlocks
|
|
execution.
|
|
|
|
### Security boundary
|
|
|
|
There is no hardware coherency. Microcode/model bundles, descriptors, input,
|
|
output, and writeback use DMA-visible non-cacheable/shared memory or explicit
|
|
64-byte CBO maintenance plus `fence rw,rw`. Descriptor OWN is the ownership
|
|
handoff point.
|
|
|
|
Every byte of every DMA burst must fit the local inclusive ACL. Range arithmetic
|
|
is overflow checked. Microcode cannot address system memory, APB, or another
|
|
local partition directly. LP-only load, static verification, capability checks,
|
|
CRC, automatic lock, watchdog, and fail-closed traps are reliability controls,
|
|
not authentication. MVP claims no secure boot, confidentiality, DRM,
|
|
functional safety, ASIL, or IEC 61508 compliance.
|
|
|
|
### Observability
|
|
|
|
The APU exposes loader/model status, current PC/class/opcode, retired
|
|
instructions, sticky first error, descriptor results, ring state, stream
|
|
FIFO/xrun state, KWS result/timestamp, and atomic snapshot counters. Required
|
|
64-bit counters are active cycles, input/output bytes, decoded frames, DMA
|
|
read/write stalls, stream stalls, sequencer instructions, KWS cycles, and
|
|
faults. Counters saturate.
|
|
|
|
No waveform-only state is required to diagnose completion, rejection, trap,
|
|
bus fault, timeout, abort, xrun, model failure, or lifecycle failure.
|
|
|
|
## MVP and Commercial-grade Roadmap
|
|
|
|
### Exact MVP
|
|
|
|
- WAV RIFF PCM: mono/stereo, 8/16/24/32-bit, 8..96 kHz, checked unknown-chunk
|
|
skip and deterministic sign extension/truncation/saturation without dither.
|
|
- MP3 is not part of this release. Format ID 1 and the three-descriptor APUMC
|
|
layout are retained with the P5 unsupported-MP3 trap stub; MP3 requests
|
|
continue to fail closed.
|
|
- Native FLAC: mono/stereo, 16/24-bit, 8..96 kHz, constant/verbatim/fixed/LPC
|
|
order0..32, Rice/Rice2, independent/left-side/side-right/mid-side, CRC8/16,
|
|
and bounded metadata skip. Ogg mapping is unsupported.
|
|
- S16_LE or S24_32LE memory/I2S output; fixed-point resampling to 48/96 kHz,
|
|
including 44.1-to-48 kHz.
|
|
- Continuous KWS: 16 kHz mono S16, one-second history, 20 ms feature stride,
|
|
49 by 10 INT8 MFCC, 12 classes, inference each 100 ms, configurable threshold
|
|
and debounce.
|
|
- One decode job plus concurrent KWS, direct/ring DMA, APB4, LP/HP ownership,
|
|
interrupts, ACL, timeout, abort/reset, first error, and counters.
|
|
|
|
### MVP acceptance
|
|
|
|
1. WAV and FLAC produce bit-exact approved PCM with the P5
|
|
frame/sample/channel accounting and deterministic output-conversion rules.
|
|
MP3 unsupported-request and trap-stub compatibility tests pass; positive
|
|
MP3 decode, PSNR and three-active-codec packing are not acceptance gates.
|
|
2. The official MLPerf Tiny KWS 1000-utterance set reaches at least 90 percent
|
|
top-1 through the hardware MFCC/inference path.
|
|
3. At 48 MHz PCLK, the P5 supported WAV/FLAC playback workloads run concurrently
|
|
with continuous KWS with zero I2S underrun and zero KWS overrun under the
|
|
active P5 ready-memory qualification conditions. MP3 performance workloads
|
|
and the archived P6 service-envelope gate are not prerequisites.
|
|
4. 24-bit/96 kHz FLAC completes without xrun; byte/frame/cycle/stall counters
|
|
match the scoreboard.
|
|
5. `APUMC` static verification, instruction interpreter/RTL differential,
|
|
opcode mutation, loop/stack/range/watchdog, loader atomicity, and trap paths
|
|
all fail closed as specified.
|
|
6. Random AXI backpressure, 4 KiB boundaries, tails, every AXI error,
|
|
ring wrap, abort/reset at every state, stream backpressure, and LP/HP
|
|
handoff complete with the specified result or bounded error.
|
|
7. RTL/C register, descriptor, `APUMC`, `APUM`, instruction, format, IRQ, and
|
|
error definitions pass parity tests.
|
|
8. IHP130 firmware, behavioral, formal, synthesis, netlist, and OpenSTA
|
|
evidence is reviewed with no unowned warning; metrics remain under policy.
|
|
|
|
Post-MVP work may optimize MAC lanes, pipeline kernels, bank SRAM, or add a
|
|
dedicated fabric identity only after counters identify a bottleneck. It must
|
|
preserve V1 public ABI and microcode capability semantics. Deferred codecs,
|
|
power, coherency, or security require a new approved phase/spec revision.
|
|
|
|
## Verification and Software Validation
|
|
|
|
### Golden models and tools
|
|
|
|
- `apu-mcasm` and the Python microcode interpreter are self-owned and tested
|
|
from the same frozen ISA definitions without generated register RTL.
|
|
- WAV uses the existing bounded reader model extended for the frozen subset.
|
|
- The minimp3/mpg123 pins and MP3 numerical/performance rules below are
|
|
archived P6 research only. This release does not require installing those
|
|
inputs, adding target p6, or running positive MP3 qualification. Existing
|
|
generic P4 primitive tests and P5 unsupported-MP3 tests remain required.
|
|
- FLAC uses RFC 9639, locked Xiph libFLAC, and the official
|
|
[FLAC test files](https://github.com/ietf-wg-cellar/flac-test-files).
|
|
- MLPerf Tiny inputs/model/converter revision and generated `APUM` are locked
|
|
and reproducible.
|
|
|
|
All new external corpora or reference packages require exact revisions or
|
|
archive checksums in the dependency lock. Managed source retains notices and
|
|
does not become evidence of self-owned MISRA conformance.
|
|
|
|
### P7 locked reference inputs and corpus provenance
|
|
|
|
The following revisions and complete archive SHA-256 values were verified
|
|
from upstream bytes on 2026-09-11. Register them in the executable dependency
|
|
lock during P7 implementation, using the existing shared dependency helpers
|
|
and `scripts/setup_apu_reference.py`; this refreeze changes documentation only.
|
|
No floating branch, newly trained model, arbitrary first-1000 selection,
|
|
unverified cache hit or direct CI download is an equivalent input.
|
|
|
|
| Source lock key | Repository / full revision | License and retained notice |
|
|
| --- | --- | --- |
|
|
| `sources.apu_mlperf_tiny` | `https://github.com/mlcommons/tiny.git` at `4addd0fa08d216e20637637874e084895f289da4` | Apache-2.0; LICENSE.md and source/model notices. |
|
|
| `sources.apu_kws_mfcc` | `https://github.com/eembc/benchmark-runner-ml.git` at `cf7c2f2634608a7c0ea7458ab7cb3379f2863424` | Mixed tree: lock NOASSERTION, consume only datasets/kws01; retain source README and Speech Commands CC-BY-4.0 attribution. Do not package the runner or unrelated datasets. |
|
|
| `sources.apu_tfds` | `https://github.com/tensorflow/datasets.git` at `8997c4140cd4fc145f0693787b1da78691930459` (v4.3.0) | Apache-2.0; LICENSE and per-file notices; ordering reference only. |
|
|
| `sources.apu_tensorflow` | `https://github.com/tensorflow/tensorflow.git` at `fcc4b966f1265f466e82617020af93670141b009` (v2.3.1) | Apache-2.0; LICENSE and per-file notices; host numerical reference only. |
|
|
| `sources.apu_gemmlowp` | `https://github.com/google/gemmlowp.git` at `fda83bdc38b118cc6b56753bd540caa49e570745` | Apache-2.0; LICENSE and per-file notices; scalar fixed-point oracle only. |
|
|
|
|
Source destinations are `.cache/retrosoc/sources/<source-key-with-underscores-replaced-by-hyphens>`
|
|
(for example `.cache/retrosoc/sources/apu-mlperf-tiny`). Archive keys below
|
|
match source keys where applicable. Archive download destinations are
|
|
`.cache/retrosoc/downloads/apu/<key>-<revision>.<tar.gz-or-zip>`; the Google
|
|
corpus uses `speech_commands_test_set_v0.02.tar.gz`. These are managed inputs,
|
|
not installed Python runtime versions or code permitted in freestanding CRT.
|
|
|
|
| Archive key | Immutable URL | SHA-256 |
|
|
| --- | --- | --- |
|
|
| `archives.apu_mlperf_tiny` | `https://codeload.github.com/mlcommons/tiny/tar.gz/4addd0fa08d216e20637637874e084895f289da4` | `70012ee5a8fc3367b466854b1840fb0246e0525744262631a98c5fc0971a04b0` |
|
|
| `archives.apu_kws_mfcc` | `https://codeload.github.com/eembc/benchmark-runner-ml/tar.gz/cf7c2f2634608a7c0ea7458ab7cb3379f2863424` | `87e431a6b4d3f011d672180a3fb1f08856d8074310f37653d5388ec2affc5209` |
|
|
| `archives.apu_tfds` | `https://codeload.github.com/tensorflow/datasets/tar.gz/8997c4140cd4fc145f0693787b1da78691930459` | `e300258c247fe8607f3c0200a34343c6a28efb69f0d2b822606a8a66cccea651` |
|
|
| `archives.apu_tensorflow` | `https://codeload.github.com/tensorflow/tensorflow/tar.gz/fcc4b966f1265f466e82617020af93670141b009` | `ad41490904b0313c00f3729c7e2ba931b2b8d1e54ea1a859a4bcea3054d4fdc0` |
|
|
| `archives.apu_gemmlowp` | `https://storage.googleapis.com/mirror.tensorflow.org/github.com/google/gemmlowp/archive/fda83bdc38b118cc6b56753bd540caa49e570745.zip` | `43146e6f56cb5218a8caaab6b5d1601a083f1f31c06ff474a4378a7d35be9cfb` |
|
|
| `archives.apu_kws_pcm` | `https://storage.googleapis.com/download.tensorflow.org/data/speech_commands_test_set_v0.02.tar.gz` | `cc2a00c1147c2254e9be3fa0f779d8c17421dc349b86366567a8edfa9acd51df` |
|
|
|
|
The PCM archive is exactly 112563277 bytes and contains 4890 WAV files. Extract
|
|
it to `.cache/retrosoc/sources/apu-kws-pcm` with the shared safe extractor.
|
|
License is CC-BY-4.0; retain its LICENSE and README.md, attribute Pete Warden /
|
|
Google Speech Commands Data Set Test Files v0.02, and identify padding and
|
|
feature extraction as modifications in redistributed derivatives. Managed
|
|
reference code/data is excluded from self-owned MISRA claims. P7 release
|
|
notices must cover any derived model/ROM/data actually shipped; benchmark
|
|
inputs themselves are host-only unless explicitly included as test fixtures.
|
|
|
|
The model path under apu-mlperf-tiny is
|
|
`benchmark/training/keyword_spotting/trained_models/kws_ref_model.tflite`,
|
|
53936 bytes, SHA-256
|
|
`aeea436800704fce17b17292e4412630ad856e9d777c044c64ef748a880bd0ae`.
|
|
Do not substitute the README's obsolete `aww_ref_model` name, the float32
|
|
model, or a newly generated `kws_model.tflite`. Source preprocessing/converter
|
|
reference files are `benchmark/training/keyword_spotting/{get_dataset.py,kws_util.py,make_bin_files.py}`
|
|
at that same full revision. The scalar inference reference is
|
|
`tensorflow/lite/kernels/internal/{common.h,quantization_util.cc,reference/softmax.h,reference/integer_ops/conv.h,reference/integer_ops/depthwise_conv.h,reference/integer_ops/pooling.h,reference/integer_ops/fully_connected.h}`
|
|
at the pinned TensorFlow
|
|
revision, with scalar `fixedpoint/fixedpoint.h` from pinned gemmlowp. No
|
|
TensorFlow wheel, network-accessing training script or TFDS runtime is needed
|
|
to reconstruct the frozen PCM manifest.
|
|
|
|
#### Exact 1000-window selection
|
|
|
|
[apu-kws-corpus.tsv](apu-kws-corpus.tsv) is a normative input manifest, not a
|
|
build report. It has no header, UTF-8/ASCII text, six tab-separated columns
|
|
and LF terminators including the last line: six-digit index, official binary
|
|
name, relative source WAV path, decimal class ID, source WAV SHA-256, padded
|
|
PCM SHA-256. Its canonical-text SHA-256 is
|
|
`57fa600948ef7a19ed5eb0d0e73c7d09fef7d0dbb12bc8833a0a8caad1d6845e`.
|
|
When checkout line endings differ, normalize CRLF to LF only before checking
|
|
this text hash. Binary WAV/PCM/MFCC hashes never normalize bytes.
|
|
|
|
The verified selection reproduces TFDS speech_commands 0.0.2 ordering as
|
|
used by the upstream test exporter: take each WAV's key `<directory>_<filename>`,
|
|
sort by the unsigned 128-bit MD5 of UTF-8 `test` followed by that key, divide
|
|
the 4890 sorted records into four contiguous shards of 1222,1223,1223,1222
|
|
records (round-to-nearest-even boundaries 0,1222,2445,3668,4890), then read
|
|
16 records from each shard in order, repeatedly. Take the first 1000.
|
|
The MD5 here is an ordering algorithm, not an integrity/security checksum.
|
|
All 1000 labels match the official list. No filename remapping based only on
|
|
class labels, nearest-feature search or host-dependent TFDS iteration is used.
|
|
|
|
Read each selected RIFF WAV as mono 16000 Hz signed S16, preserve sample bits,
|
|
right-pad with signed-zero samples to exactly 16000 samples, and emit exactly
|
|
32000 little-endian bytes. Reject a longer file or different rate/precision.
|
|
The first source is `stop/563aa4e6_nohash_3.wav`; the last is
|
|
`up/c22d3f18_nohash_2.wav`. The PCM manifest is independently reproducible from
|
|
the public Google archive; an unavailable/deleted EEMBC td_samples package
|
|
or user-supplied licensed download is not a prerequisite.
|
|
|
|
| Object / byte-order of concatenation | Required SHA-256 |
|
|
| --- | --- |
|
|
| 1000 padded PCM files, index 0..999, no delimiters (32000000 bytes) | `abd1ff2c988ac168dd68c29f934d95114d1094d7818d79fe73adb166ac009bee` |
|
|
| Official `datasets/kws01/y_labels.csv`; identical to Tiny `benchmark/evaluation/datasets/kws01/y_labels.csv` | `6cb3709762d53fe64eb00eaf4a75796248bb3c1386f1d1f93ccdb07b071e9698` |
|
|
| Official 1000 `datasets/kws01/tst_*.bin`, index order, 490 bytes each, no delimiters | `c2e5f02def82726f5c49dfe85c311c52f295ad68561f6bae89931fdadaaedc73` |
|
|
|
|
The future self-owned converter is `scripts/apu_kws_convert.py`, contract
|
|
revision `apu-kws-convert/1.0.0`, target `p7`, APUM ABI 1.0 and frontend
|
|
profile 1. It performs the specified static import/packing, not training or
|
|
quantization calibration. Its source commit/hash cannot exist before
|
|
implementation: each P7 artifact MUST record the exact implemented converter
|
|
Git revision, dirty status, source-file SHA-256 and contract revision. A dirty
|
|
or missing converter identity cannot qualify a release. Two independent
|
|
imports of the pinned source must give identical APUM bytes, CRC, ROM words
|
|
and manifest. Check the generated APUM CRC/SHA and parameter/requantization
|
|
hashes against the independent freeze-time golden values above, and record
|
|
the actual results. The production converter is still an implementation
|
|
deliverable; its existence or correctness is not implied by that byte-layout
|
|
cross-check.
|
|
|
|
#### P7 qualification artifacts and gates
|
|
|
|
The implementation extends the existing APU reference setup flow with target
|
|
P7 and offline doctor checks. Its generated corpus, model, coefficients,
|
|
per-layer tensors and JSON reports belong below the selected committed
|
|
profile's `build/<profile>-<date>-<hash>/apu-kws/`. Setup/doctor must check all
|
|
archive, source model, label, manifest, per-file and aggregate hashes above.
|
|
It must fail for missing input rather than downloading outside the shared
|
|
dependency helpers or replacing the corpus with synthetic stimuli.
|
|
|
|
Required report names are `provenance.json`, `apum-layout.json`,
|
|
`frontend-differential.json`, `layer-differential.json`, `accuracy.json`,
|
|
`concurrent.json`, and `lifecycle.json`. They record input/converter/BAM/RTL
|
|
revisions, model/ROM hashes, profile, simulator/tool versions, seed, exact
|
|
command, success/failure, counts and artifact paths. Layout includes every
|
|
image interval, scratch lifetime, bank access and high-water, not just the
|
|
53 KiB source TFLite size. That source file must never be copied verbatim
|
|
into the 32 KiB APUM model reservation.
|
|
|
|
- Official feature-input inference is a separate host/verification-only
|
|
layer differential on all 1000 MFCC files; it exposes no new public
|
|
operation or bypass bit. Each INT8 layer and final result is bit-exact
|
|
against the pinned scalar inference reference.
|
|
- End-to-end accuracy feeds all 1000 padded PCM windows through operation 1
|
|
and the real hardware frontend/inference path, resets history per input,
|
|
threshold=128/debounce=1, and requires at least 900 correct top-1 labels
|
|
out of exactly 1000. Silence/unknown remain part of the denominator. No
|
|
skipped/duplicated utterance, CPU MFCC or precomputed-input substitution
|
|
is allowed. Report per-class counts and every incorrect index.
|
|
- Continuous tests cover the initial one-second warm-up, 20 ms feature hop,
|
|
100 ms inference cadence, every tie/threshold/debounce edge, snapshot
|
|
coherency, counter saturation, planned gaps and stale-result prevention.
|
|
Raw-mel reuse must equal recomputing the same window's integer frontend.
|
|
- Mutate every APUM header/record/range/CRC/reserved field, per-channel
|
|
scaling, sign/rounding extrema and scratch boundary. Test partial load,
|
|
retry, lock, HP denial, no payload DMA before admission and no valid on
|
|
failure. Independently handwritten RTL/C/Python constants and wire
|
|
fixtures must agree; a register generator is still prohibited.
|
|
- Concurrent WAV and every qualified P5 FLAC performance workload run with
|
|
continuous RX KWS for at least 60 simulated seconds at 48 MHz, at both
|
|
48 and 96 kHz I2S and both precisions, with the active P5 ready-memory
|
|
qualification. Require zero codec underrun and KWS overrun, every full
|
|
uninterrupted scheduled window completed before its successor, and
|
|
matching byte/frame/cycle/stall scoreboards. Do not promote archived P6
|
|
memory-service envelopes to new P7 prerequisites.
|
|
- Separately inject AXI stalls/errors, RX/TX xrun, abort/reset/quiesce/handoff
|
|
at each loader/frontend/layer/writeback state, descriptor wrap/ownership,
|
|
half stereo pairs and unilateral clock-domain resets. These stress cases
|
|
require the bounded specified recovery, not an impossible zero-xrun claim
|
|
under arbitrary starvation. KWS failure must not corrupt codec SRAM,
|
|
model lock or previously published descriptor completions.
|
|
|
|
IHP130 synthesis/netlist/OpenSTA and final commercial physical evidence remain
|
|
P8 work, as for P5. P7 records cycle/memory/ROM/CDC integration evidence but
|
|
does not claim area/timing/power closure or an official MLPerf submission.
|
|
The current release still advertises no MP3 support.
|
|
|
|
### P5 locked reference inputs and qualification
|
|
|
|
The following pins were read from upstream and both archive SHA-256 values
|
|
were computed from the complete fixed-revision archive bytes on 2026-09-05.
|
|
They are authoritative P5 setup inputs, not floating branch/tag selections.
|
|
This documentation freeze does not modify the executable dependency lock.
|
|
Adding the exact entries and setup/test integration below is the first P5
|
|
implementation step; missing installed inputs are setup work, not an open
|
|
architecture choice. No direct download is added to CI or firmware flows.
|
|
|
|
| Lock key / use | Upstream and full revision | Destination | License handling |
|
|
| --- | --- | --- | --- |
|
|
| `sources.apu_libflac` / host-only reference | `https://github.com/xiph/flac.git`, release 1.5.0 commit `1507800de4b70e21be71f38caa0d9079d0bc6e45` | `.cache/retrosoc/sources/apu-libflac` | Lock license `NOASSERTION` for the mixed source tree; libFLAC/libFLAC++ are BSD-3-Clause (`COPYING.Xiph`), CLI code is GPL-2.0-or-later. Retain COPYING.Xiph, COPYING.GPL, COPYING.LGPL, COPYING.FDL and per-file notices. |
|
|
| `sources.apu_flac_corpus` / host-only corpus | `https://github.com/ietf-wg-cellar/flac-test-files.git`, commit `aa7b0c6cf32994c106ae517a08134c28a96ff5b2` | `.cache/retrosoc/sources/apu-flac-corpus` | `CC0-1.0`; retain LICENSE.txt and root/per-group README.txt attribution. |
|
|
|
|
| Archive lock key | URL | SHA-256 | Download destination |
|
|
| --- | --- | --- | --- |
|
|
| `archives.apu_libflac` | `https://codeload.github.com/xiph/flac/tar.gz/1507800de4b70e21be71f38caa0d9079d0bc6e45` | `d80ef5facdb21972efe91774da03d6b9abf216aa17093d740fcc411cd8afbb41` | `.cache/retrosoc/downloads/apu/libflac-1507800de4b70e21be71f38caa0d9079d0bc6e45.tar.gz` |
|
|
| `archives.apu_flac_corpus` | `https://codeload.github.com/ietf-wg-cellar/flac-test-files/tar.gz/aa7b0c6cf32994c106ae517a08134c28a96ff5b2` | `36de2310155b4084011fbd56f24603dfef91a26c5433e3f92bd21995b45089c3` | `.cache/retrosoc/downloads/apu/flac-corpus-aa7b0c6cf32994c106ae517a08134c28a96ff5b2.tar.gz` |
|
|
|
|
Archive license fields match the corresponding source entries. Git checkout
|
|
and verified archive extraction are two encodings of the same pinned source;
|
|
setup selects one explicitly and must not silently fall back to a newer
|
|
revision after a checksum failure. Build the host reference with Ogg disabled,
|
|
and keep its binaries/build products in the variant build tree. No libFLAC,
|
|
GPL CLI, or corpus code is linked into `crt/`, LP/HP firmware, RTL, or shipped
|
|
APUMC; comparison is through host test processes. If reference tools are
|
|
redistributed, retain their applicable source/license obligations. `NOASSERTION`
|
|
is not a relicensing or compliance claim. P5's self-owned HAL and microassembly
|
|
are independent artifacts; any copied upstream material needs explicit notice
|
|
review before inclusion.
|
|
|
|
P5 delivers deterministic WAV/FLAC microassembly, the three-entry APUMC bundle,
|
|
1536-word resampler coefficient file, symbols, instruction/control-store and
|
|
scratch high-water reports, and a per-file corpus manifest. The manifest records
|
|
each pinned corpus relative path and SHA-256, its expected supported/rejected/
|
|
malformed result, profile reason, PCM geometry, and reference-output hash.
|
|
Every official corpus file is classified, including files above P5 block limits;
|
|
unsupported files must be tested for clean rejection, not silently omitted.
|
|
Generated valid/malformed vectors supplement the official corpus for every
|
|
WAV chunk boundary, FLAC escape width zero, wasted-bit count, predictor order,
|
|
CRC fault, strict/relaxed case, and 2048/4096 block boundary. Host libFLAC
|
|
supplies PCM truth; the independent integer post-processing model supplies
|
|
downmix/resample/packing truth. CRC-only success with MD5 unchecked must be
|
|
visible in expected results.
|
|
The host harness obtains PCM even for an MD5-only mismatch and records that
|
|
reference integrity failure separately; it must not mislabel the P5 documented
|
|
MD5-unchecked acceptance as a PCM decoding mismatch.
|
|
|
|
Directed tests must exercise production direct and ring submission, invalid
|
|
owned MP3/KWS entries, class-6 cursor/FIFO backpressure, all three required
|
|
bundle entries, every format error tuple, exact output capacity and one-frame
|
|
short capacity, I2S final TLAST/drain, abort/reset during every transport stage,
|
|
and cross-format ring sequences. Differential Icarus and Verilator runs use
|
|
the same fixtures and result scoreboard; no verification injector may appear
|
|
in product behavioral or synthesis filelists. Formal covers exclusive DMA/SRAM
|
|
ownership, range checks, stable stream payload under stalls, accepted-transfer
|
|
drain, OWN-clear ordering, and no public MP3/KWS/RX execution. P3/P4 target and
|
|
observability regressions remain required.
|
|
|
|
At 48 MHz PCLK, a ready memory target must sustain the P5 supported WAV/FLAC
|
|
rates and 44.1-to-48 kHz conversion in cycle-counted simulation. The I2S test
|
|
starts consumption after a 64-word APU prefill (or the whole output for a
|
|
shorter job), then supplies ready memory without injected stalls; between
|
|
first and last samples it must record zero xrun. Separate random-stall tests
|
|
verify bounded error/drain rather than claim uninterrupted playback under
|
|
unbounded stalls. Measured maximum tolerable AXI stalls, source properties,
|
|
instruction budget, and occupancy must accompany results. Static timing,
|
|
area, power, netlist, and physical 48 MHz closure remain Phase8 evidence.
|
|
|
|
<details>
|
|
<summary>Deferred APU-P6 references and qualification — inactive for this release</summary>
|
|
|
|
### P6 locked MP3 inputs and numerical evidence
|
|
|
|
Status: DEFERRED. This section and its PSNR, real-time and physical-evidence
|
|
subsections are historical notes, not current-release requirements. No MP3
|
|
dependency setup, decoder/corpus build, PSNR run, 320 kbit/s workload or
|
|
three-active-codec report is required by this release. Current P8 physical
|
|
requirements are stated in the active Synthesis, Timing, and Physical Evidence
|
|
section; archiving these P6 notes does not remove those P8 requirements.
|
|
|
|
These fixed revisions and archive SHA-256 values were read and computed from
|
|
the complete upstream archive bytes on 2026-09-11. P6 implementation extends
|
|
`scripts/setup_apu_reference.py` and the executable dependency lock with these
|
|
exact keys. This refreeze changes documentation only. Existing FLAC lock keys,
|
|
setup and qualification remain intact.
|
|
|
|
| Source lock key | URL / full revision | Source destination | License record |
|
|
| --- | --- | --- | --- |
|
|
| `apu_minimp3` | `https://github.com/lieff/minimp3.git` / `ea99364f61c14656440e8d77e9c233ccf3124633` | `.cache/retrosoc/sources/apu-minimp3` | `CC0-1.0`, retain LICENSE and upstream attribution. |
|
|
| `apu_mpg123` | `https://github.com/madebr/mpg123.git` / `f6c19f46031088efc8d0e5b83305a6f36ceceb65` | `.cache/retrosoc/sources/apu-mpg123` | `LGPL-2.1-only` as the default COPYING terms; retain COPYING, AUTHORS and any per-file exceptions. |
|
|
| `apu_mp3_corpus` | Same minimp3 URL / `ea99364f61c14656440e8d77e9c233ccf3124633`; select `vectors/` | `.cache/retrosoc/sources/apu-mp3-corpus` | Record upstream `CC0-1.0` declaration and retain LICENSE; preserve vector provenance and any per-file notices. Host-only test material, not a claim of ISO certification or a new license grant over third-party vectors. |
|
|
|
|
| Archive key | URL | SHA-256 | Download destination |
|
|
| --- | --- | --- | --- |
|
|
| `apu_minimp3` | `https://codeload.github.com/lieff/minimp3/tar.gz/ea99364f61c14656440e8d77e9c233ccf3124633` | `5628166eb82a9bb581317918a334c317a2c0a30278bb14a20381307976768f34` | `.cache/retrosoc/downloads/apu/minimp3-ea99364f61c14656440e8d77e9c233ccf3124633.tar.gz` |
|
|
| `apu_mpg123` | `https://codeload.github.com/madebr/mpg123/tar.gz/f6c19f46031088efc8d0e5b83305a6f36ceceb65` | `1b42d961c56ec0e47510e69768277dd6726316a3063116bfd8264f19b9e1c218` | `.cache/retrosoc/downloads/apu/mpg123-f6c19f46031088efc8d0e5b83305a6f36ceceb65.tar.gz` |
|
|
| `apu_mp3_corpus` | Same fixed minimp3 archive URL | `5628166eb82a9bb581317918a334c317a2c0a30278bb14a20381307976768f34` | Same minimp3 download destination, verified once and reused for extraction. |
|
|
|
|
The mpg123 mirror is linked by the project's
|
|
[download page](https://www.mpg123.de/download.shtml). The two decoders have
|
|
independent implementations; one decoder executed with two configurations is
|
|
not sufficient. All reference programs and corpus files are host-only, outside
|
|
firmware, RTL and APUMC release outputs. Use shared checksum/download/extraction
|
|
helpers; there is no floating HEAD/tag fallback. Retain notices with cached
|
|
sources and any redistributed reference artifacts. Product microassembly and
|
|
numerical tables must have independently recorded provenance; copying GPL/LGPL
|
|
decoder code into the product is not authorized by these test-input pins.
|
|
|
|
Setup keeps the existing `--build-dir` interface and adds `--phase p5|p6`
|
|
(default p5). P6 installs all P5 inputs plus the three keys above. It checks
|
|
CMake at least 3.27, Ninja, and a C compiler before building the pinned mpg123
|
|
tree at `ports/cmake`; use `BUILD_PROGRAMS=OFF`, `BUILD_LIBOUT123=OFF`,
|
|
`BUILD_SHARED_LIBS=OFF`, `GAPLESS=OFF`, `NO_LAYER1=ON`, `NO_LAYER2=ON`,
|
|
`NO_NTOM=ON`, `NO_EQUALIZER=ON`, `NETWORK=OFF`, `NO_REAL=OFF`, and `HAVE_FPU=ON`.
|
|
Select the library's `generic` decoder explicitly. Build minimp3 with
|
|
`MINIMP3_IMPLEMENTATION`, `MINIMP3_ONLY_MP3`, `MINIMP3_NO_SIMD`, and
|
|
`MINIMP3_FLOAT_OUTPUT`. Both host wrappers disable fast-math and FP contraction,
|
|
use native source rate/channels and float32 output, and record compiler,
|
|
configuration and binary hashes. Missing build tools are explicit setup
|
|
prerequisites, not skipped evidence or direct unpinned installer downloads.
|
|
|
|
mpg123 uses feeder decoding with GAPLESS removed, IGNORE_INFOFRAME set, unity
|
|
scale, ReplayGain disabled and no forced resampling or mono mode. minimp3
|
|
uses the frame decoder with persistent state, not the extended whole-file
|
|
helper's automatic gapless trimming. Both receive the same exact MPEG frame
|
|
bytes after this specification's metadata classification. Assert frame count,
|
|
sample count, rate and channels before comparing PCM. A reference that silently
|
|
resynchronizes or omits an Info frame is a harness failure. Neither reference's
|
|
CRC/underflow tolerance is the oracle for malformed files: a separate bounded
|
|
header/reservoir/CRC model implements the P6 rejection rules.
|
|
|
|
Every pinned `vectors/**/*.bit` and `vectors/**/*.mp3` is classified in a
|
|
committed deterministic manifest by path and SHA-256. Unsupported layer/free-
|
|
format/geometry/emphasis cases are rejection tests, not silently excluded
|
|
tests. Every valid in-profile file is a numerical test. Paired upstream `.pcm`
|
|
files are supplementary evidence with their byte order/count recorded; the
|
|
primary normalized oracle is the pinned mpg123 wrapper. Required stress
|
|
families include `l3-compl.bit`, `l3-he_32khz.bit`, `l3-he_44khz.bit`,
|
|
`l3-he_48khz.bit`, `l3-he_mode.bit`, `l3-si.bit`, `l3-si_block.bit`,
|
|
`l3-si_huff.bit`, `l3-sin1k0db.bit`, `M2L3_bitrate_16_all.bit`,
|
|
`M2L3_bitrate_22_all.bit`, `M2L3_bitrate_24_all.bit`, `M2L3_compl24.bit`, and
|
|
the performance vectors below. A named file may fail the P6 profile; its exact
|
|
first-offender result is then tested instead of treating tolerant reference
|
|
decoding as evidence of support.
|
|
|
|
Self-owned deterministic vectors supplement missing corners: all nine rates,
|
|
both channel counts, all supported bitrate indices, MPEG-2.5, protected frames,
|
|
all block/mixed modes and joint-stereo combinations, maximum reservoir, VBR,
|
|
zero main-data, every ID3 flag/size/footer boundary, and truncated headers,
|
|
side-info and entropy. Generate exact coded frames from documented literal
|
|
headers/side-info/Huffman symbols and pair every valid frame sequence with both
|
|
decoders; no new encoder dependency or opaque Internet audio sample is needed.
|
|
No coverage item is waived merely because the pinned corpus lacks it.
|
|
|
|
#### P6 PSNR calculation and comparison windows
|
|
|
|
Compare native-rate, source-channel MP3 PCM before P5 downmix/resampling.
|
|
Promote each reference float32 `x` to float64 before normalization. Clamp it
|
|
to `[-1,1-2^-31]`, round `x*2^31` to nearest-even, then arithmetic-shift right
|
|
eight bits to obtain signed 24-bit `r`. Obtain APU `a` from S24_32 output
|
|
using the same native geometry and no optional processing. Full-scale peak is fixed at
|
|
`P=8388607`, not the measured signal peak. For N samples,
|
|
`SSE=sum((a-r)^2)`, `MSE=SSE/N`, and `PSNR=10*log10(P^2/MSE)`; SSE zero means
|
|
positive infinity. NaN/infinite reference samples fail the harness before
|
|
quantization. Accumulate integer SSE in at least 128 bits or arbitrary-precision
|
|
integers without overflow. The acceptance
|
|
comparison is strictly `SSE < N*P^2/10^9.6` (>96 dB), evaluated with enough
|
|
precision to resolve the boundary; printed rounded dB is never the verdict.
|
|
|
|
Require >96 dB against each independent reference on the full file, on each
|
|
individual channel, and on consecutive 1152-source-sample-frame windows
|
|
(including the final nonempty short window). Also compare the two references
|
|
to each other with the same threshold; disagreement blocks qualification and
|
|
must be investigated, not resolved by choosing the easier oracle. Report
|
|
SSE, N, maximum absolute error and worst-window PSNR. Do not optimize delay,
|
|
gain, sample offset, or channel permutation to raise PSNR. Start all decoder
|
|
histories empty, include encoder/synthesis delay and padding samples, include
|
|
Info frames, and require exactly 1152/576 frames per MPEG frame; there is no
|
|
trimmed warmup window. Empty/tag-only inputs are error tests, not infinite-
|
|
PSNR successes.
|
|
|
|
Separate S16, downmix and resampling tests compare against applying the frozen
|
|
P5 integer post-processing model to the APU's native decoded sequence. This
|
|
isolates post-processing correctness from MP3 approximation error; the native
|
|
PSNR gates still apply. Run the unchanged WAV/FLAC bit-exact corpus against
|
|
both the legacy P5 image and the rewritten P6 image. Code relocation may change
|
|
build IDs and cycle/PC measurements, but not PCM, accounting or semantic errors.
|
|
|
|
#### P6 real-time envelope and physical-evidence boundary
|
|
|
|
The mandatory 320 kbit/s, 48 kHz joint-stereo workloads come from the pinned
|
|
corpus. Their file hashes are:
|
|
|
|
| Relative path under vectors | SHA-256 |
|
|
| --- | --- |
|
|
| `performance/MIPSTest.mp3` | `197265fa09d1b6777b71269d986055035f3e9e1f4d74e4cbaa0e55034447a9ca` |
|
|
| `performance/MEANDR_PHASE90.mp3` | `b8a8f2b38e2cacc42849af754a926552b87478003738a9f40c86ff0e22f555a1` |
|
|
| `performance/noise_meandr.mp3` | `423a97ef5b01c8253940d04bf93ee0d9508b77ef17608c69a1b3c09ae8667c0d` |
|
|
|
|
Run each as a finite job and in a descriptor ring for at least 60 simulated
|
|
seconds, restarting decoder history at each job boundary as specified. Test
|
|
S16 and S24_32, at 48 MHz PCLK, 48 kHz I2S; test 48-to-96 kHz output separately
|
|
using the P5 resampler. KWS is disabled in P6; simultaneous KWS qualification
|
|
is still a P7/P8 requirement. Do not label a clock divider slower than 48 MHz
|
|
or a different source corpus as the qualified run.
|
|
|
|
The qualified AXI service envelope is measured at the APU PCLK master and
|
|
includes Gateway A/CDC/target delay: AR or AW handshake within 64 PCLK cycles
|
|
of continuously asserted VALID; first RVALID within 32 cycles after AR; at
|
|
most four cycles between available R beats when the APU is ready; WREADY at
|
|
least once every four cycles after AW; BVALID within 16 cycles after the last
|
|
W handshake. Bursts are the existing 1..16 beats/4 KiB subset, responses OKAY.
|
|
The BFM must cover both zero-delay and maximum-delay schedules and randomized
|
|
legal schedules. APU-generated backpressure and local-SRAM stalls are not
|
|
subtracted from execution time. This is a qualified environment assumption,
|
|
not a new QoS guarantee imposed on the entire SoC or on slow serial memories.
|
|
|
|
Start I2S consumption after 64 APU-router words are prefetched, or the whole
|
|
output for a shorter job; initial prefill must finish within 2400000 PCLK
|
|
cycles from the first MPEG header after ID3. Per job, the steady interval from
|
|
the first consumed PCM sample through the last must show zero I2S underrun,
|
|
zero dropped/reordered/duplicated PCM frames, exactly one final TLAST for a
|
|
nonempty output, and exact P5 byte/frame counters. Queue gaps between jobs
|
|
are excluded only if explicitly recorded; they are not a gapless-playback
|
|
claim. Clear xrun state before the window and check both sticky state and
|
|
event scoreboard during it. Report effective clocks, per-frame/granule cycles,
|
|
minimum FIFO occupancy, refill stalls, last-sample time and the full service
|
|
trace. An average faster-than-real-time result cannot excuse an underrun.
|
|
|
|
Randomized tests beyond the service envelope verify the existing timeout,
|
|
first-error and drain behavior; uninterrupted playback is not required under
|
|
unbounded stalls. Physical signoff remains deferred to P8 as in the approved
|
|
APU execution policy. P6 completion requires functional/cycle/formal evidence,
|
|
not a claim that an RTL cycle model closes physical timing.
|
|
|
|
P8 must synthesize this exact P6/P7 hierarchy and compare with the reviewed P5
|
|
baseline under the same committed IHP130 profile and locked tools. Static
|
|
acceptance is max-delay WNS >= 0 ns and TNS = 0 at the 20.833 ns PCLK target,
|
|
no unconstrained active APU clock/data paths, no inferred latch or unresolved
|
|
non-PDK black box, and all macro/clock/reset views accounted for. Report hold
|
|
analysis separately; pre-layout STA is not post-layout signoff. Area acceptance
|
|
requires the unchanged eight control plus 28 data SRAM wrappers, complete
|
|
cell/macro accounting and reviewed per-block/total deltas versus P5. There is
|
|
no approved absolute standard-cell mm2 or power ceiling before measurement:
|
|
those metrics remain explicitly report-only under repository policy, and a
|
|
missing area report is not an area pass. No global warning or metric policy
|
|
is changed by these feature evidence requirements.
|
|
|
|
</details>
|
|
|
|
### Required evidence matrix
|
|
|
|
| Area | Required evidence |
|
|
| --- | --- |
|
|
| APB/register | Decode, waits, strobes, RO/WO, busy protection, W1C/set priority, reset, capability, and RTL/C parity. |
|
|
| DMA/ring | Native AXI BFM plus the P2 verification-only backend cover internal direct/ring ownership, writeback, wrap, coalescing epochs/IOC, 4 KiB split, tails, ACL overflow, faults, abort, and timeout without a public diagnostic operation. |
|
|
| Streams | P2 verification-only endpoints cover both production router/FIFO directions, random backpressure, watermark/xrun, active detection, and route protection; later phases add S16/S24/TLAST and concurrent codec/KWS product endpoints. |
|
|
| Assembler/loader | Syntax and semantic rejection, deterministic binary, all control-flow/loop/stack/range checks, CRC, capability, atomic valid/lock, mutation/fuzz. |
|
|
| Sequencer/formal | PC/control-store bounds, only bounded loop-back, counter decrement, call depth, watchdog, no system/APB access, descriptor-only DMA handles, legal traps. |
|
|
| Primitives | Bitstream/CRC, every Huffman/Rice mode, arithmetic extremes, saturation, transform/LPC/resampler differential, latency bounds. |
|
|
| Codecs | WAV/FLAC complete-file differential, sample/rate/channel counts, malformed/truncated/adversarial corpus, metadata limits, FLAC predictor/Rice extremes, and long playlists; MP3 is tested only for unsupported-request/stub compatibility. |
|
|
| KWS | MFCC differential, every INT8 layer tensor, converter rejection, official accuracy, threshold/debounce, continuous stream and overrun. |
|
|
| SoC | Address/topology, Gateway A fairness, Resource7, IRQ31/PLIC10 exclusion, cache maintenance, handoff, warm flush, HP reset, USB2/SDIO0 contention. |
|
|
| Software | HAL validation/timeouts/errors, microcode/model load, owner handoff, bare-metal LP/HP acceptance, and cache/handoff tests. Linux ASoC is deferred. |
|
|
|
|
An internal KWS result is not called MLPerf unless the exact applicable rules
|
|
and runner are followed. File interoperability alone is not codec certification.
|
|
|
|
### P9 memory-reduction verification and evidence
|
|
|
|
Use the same committed IHP130 profile, locked Yosys (currently dependency-lock
|
|
0.67), Slang build, PDK revision, macro views, PCLK/SDC, ABC recipe, flatten/
|
|
keep-hierarchy rules, host resources and timeouts for baseline A and candidate B.
|
|
Record executable/plugin hashes as well as version strings. Baseline A is the
|
|
inspected pre-P9 revision; B includes the migration and generated APUC. Separate
|
|
checkouts/output roots preserve both artifact sets. Non-APU inputs must match;
|
|
otherwise rebaseline explicitly rather than attribute unrelated changes to P9.
|
|
|
|
Do not confuse the existing EnableP7=0 versus EnableP7=1 block report with this
|
|
A/B test: memory-reduction A and B both have KWS enabled. Also retain the
|
|
existing P5-versus-KWS physical comparison. Use the production SRAM-macro
|
|
configuration, real model/coefficient loaders and full arithmetic datapaths,
|
|
not a stub, preinitialized inferred RAM or disabled KWS elaboration.
|
|
|
|
Required evidence below the variant root in `apu/p9/evidence/`:
|
|
|
|
| Report | Required evidence |
|
|
| --- | --- |
|
|
| `coefficient-layout.json` | All ten table word counts/hashes, logical-to-bank inverse mapping, zero padding, image/header CRC/SHA, generator revision and the exact 15-wrapper map. |
|
|
| `coefficient-lifecycle.json` | LP admission, unsupported discovery, cache/ACL checks, DMA/backpressure, payload/readback corruption, partial load/retry, lock, ownership, hard/soft/resource reset, quiesce-load and abort-at-every-state tests. |
|
|
| `memo-equivalence.json` | Baseline versus macro-memo proof verdicts/first errors/visited states on valid and mutated APUMC V1/V2; duplicate keys, collisions, wrap, full table, deeper-call bypass, key/bitmap boundaries and interrupted clearing/insertion. |
|
|
| `numerical-latency.json` | Every coefficient and all scalar/table boundary cases, variable response backpressure, no double commit/stale response, bit-exact MFCC/layer/final outputs, component and complete-window cycle counts. |
|
|
| `memory-synthesis-ab.json` | Per-hierarchy pre-memory bits/ports/instances, source and lowered memory forms, flop/mux counts, macro types/counts, memory/opt_dff/ABC/whole-flow times, peak RSS, return status/timeouts and raw report paths for A/B. |
|
|
| `physical.json` | Logic area and macro area separately, total area, WNS/TNS, unconstrained paths, hold reports, macro timing views and netlist-model coverage; no PDK black box silently omitted. |
|
|
|
|
The layout test must enumerate every valid logical table index, prove the
|
|
inverse mapping, count exactly 14444 populated positions and 916 zero-padding
|
|
positions (populated coefficient/profile words may themselves be zero),
|
|
and compare the generated APUC to the frozen hashes. Compare every lookup
|
|
against the pre-P9 reference, including last Hann/Mel/DCT/FIR indices, both
|
|
twiddle components, Log[1024], Softmax differences 0/124 and rejection of 125,
|
|
and all 1496 APUM profile words. Candidate tables/ROM helper functions cannot
|
|
serve as the only oracle for their own SRAM addresses. Use unknown/random
|
|
macro power-on data in tests; a successful LP load must establish all contents.
|
|
|
|
Model validation must still reject profile-word mutations and CRC-consistent
|
|
adversarial images as before; replacing the expected-word source with SRAM
|
|
must not replace structural validation with CRC alone. Test access at key
|
|
indices 0/31/32/1023/1024/8191, stale invalid-key data, same-bitmap-word inserts,
|
|
full hash wrap and equality differing only in upper key bits. A memo hit may
|
|
only skip a state that the unchanged exact-key policy permits. P9 may take
|
|
more cycles but must not reject a formerly accepted image by counting SRAM
|
|
cycles against the semantic traversal bound.
|
|
|
|
Run the full existing 1000-PCM hardware accuracy path (at least 900/1000),
|
|
per-stage/layer differentials and 60-second concurrent WAV/FLAC + KWS matrix,
|
|
including 48/96 kHz and S16/S24. Neither reduced smoke windows nor a CPU
|
|
reference replaces these reports. Reuse/extend `run_apu_p7_kws_rtl.py`,
|
|
`run_apu_p7_concurrent_rtl.py` and the P8 LP/HP/quiesce/contention tests to load
|
|
APUC through the public interface. Permit extra measured processing cycles
|
|
only while every complete continuous window finishes before its successor,
|
|
mel/input history is not overwritten and no xrun occurs under qualified
|
|
ready-memory conditions. Keep arbitrary-starvation fault recovery separate.
|
|
|
|
For structural acceptance, count memories with hierarchy multiplicity and
|
|
width*depth consistently at the existing pre-`memory` checkpoint. The four
|
|
targeted storage classes must contribute zero inferred bits. Require at least
|
|
90 percent reduction in APU-owned inferred bits and the 65536-bit residual
|
|
ceiling, plus exactly the live macro groups in the P9 allocation table. Do
|
|
not move `memory_map` before the checkpoint, remove hierarchy from the report,
|
|
replace memories with equivalent giant flop/mux banks, or alter the SAT/ABC
|
|
recipe merely to meet this statistic. Archive post-memory/pre-tech mapped
|
|
logic inventories as the cross-check. Wrapper simulation arrays are not
|
|
counted as physical macro storage in an IHP130 synthesis report.
|
|
|
|
The candidate must complete memory lowering and the unchanged
|
|
`opt_dff -sat -nodffe -nosdff` pass within the existing flow limits; compare
|
|
their combined runtime, full synthesis wall time and peak process-tree RSS.
|
|
Require demonstrated improvement in post-memory processing and peak RSS for
|
|
the memory-reduction handoff, not just fewer inferred bits. If A times out,
|
|
record a censored observation and a lower time bound, not a made-up finished
|
|
runtime or percentage. A completed B below that bound establishes a bounded
|
|
runtime improvement; RSS needs its own measured comparison. Unavailable
|
|
evidence is UNRUN, a timeout is not PASS, and absent improvement remains an
|
|
explicit P9 acceptance gap. No new absolute area/power ceiling is invented.
|
|
|
|
Update `report_apu_block.py`'s classifications and tests: source-era text that
|
|
describes the KWS window as flops is already stale, and counts omitting the
|
|
path stack, new memo/bitmap or coefficient banks are invalid. Distinguish
|
|
advertised capacity, physical provision, utilized payload and alignment waste.
|
|
Report added macro area/power/fanout and startup traffic alongside reduced
|
|
standard-cell storage. These are phase acceptance/review requirements, not
|
|
authorization to change the repository's observe-mode metrics policy, warning
|
|
baselines, synthesis timeouts or global CI quality policy.
|
|
|
|
## Synthesis, Timing, and Physical Evidence
|
|
|
|
The committed MVP profile is `configs/ci/ihp130.mk`. Block and full-SoC
|
|
synthesis use locked Yosys. OpenSTA analyzes the 20.833 ns/48 MHz PCLK target
|
|
and existing asynchronous relationships. Correctness at slower dividers is
|
|
required but no slower-clock real-time claim follows.
|
|
|
|
Current P8 physical acceptance covers the active P5 WAV/FLAC and P7 KWS
|
|
hierarchy, compared with the reviewed P5 baseline under the same IHP130
|
|
profile and locked tools. Max-delay WNS must be >= 0 ns and TNS = 0 at the
|
|
20.833 ns PCLK target, with no unconstrained active APU path, inferred latch,
|
|
or unresolved non-PDK black box; all macro/clock/reset views must be accounted
|
|
for and hold analysis reported separately. Retain the eight control-store
|
|
plus 28 data-store SRAM wrappers and report verifier/auxiliary macros separately.
|
|
The post-P9 hierarchy adds the frozen memo/bitmap/coefficient banks and must
|
|
meet the full 76-wrapper inventory, not a historical 36-wrapper total. Complete
|
|
per-block cell/macro/delta accounting is mandatory. Standard-cell area and power
|
|
remain report-only with no approved
|
|
absolute ceiling, and missing reports do not count as passes. Pre-layout STA
|
|
does not replace physical signoff. No MP3 hierarchy, decoder quality or MP3
|
|
performance result is required for this release's P8 acceptance.
|
|
|
|
Evidence includes:
|
|
|
|
- control-store and local-SRAM macro count/utilization; expanded P5 uses eight
|
|
4 KiB control-store wrappers plus the unchanged 28 local-data wrappers
|
|
(36 advertised-capacity wrappers versus 32 before expansion). Control storage
|
|
increases 16 KiB and combined image/data storage increases from 128 to
|
|
144 KiB. These are capacity counts, not measured area/power; report verifier
|
|
workspace, additional PC/branch flops, muxing, and fetch paths separately;
|
|
- sequencer, entropy, transform, reconstruction, resampler, and KWS cells/area;
|
|
- max/min WNS/TNS, worst APU paths, reset/fanout, clock gates, and black boxes;
|
|
- instruction/control-store high-water, maximum frame instruction count,
|
|
loop/call high-water, local SRAM high-water, and primitive cycles;
|
|
- decoder/KWS cycles, DMA/stream stalls, sustained bandwidth, and concurrent
|
|
workload utilization;
|
|
- netlist simulation, warning JSON, metrics JSON, and manifest evidence.
|
|
|
|
No target area or power number is approved before measurement. A successful
|
|
tool exit is not closure. Commercial release additionally needs qualified SRAM
|
|
views for every product PDK, CDC/RDC, scan/ATPG, MBIST/repair, PVT/MMMC, CTS,
|
|
extracted STA, activity power, IR/EM, SDF, package/board audio timing, and
|
|
silicon characterization.
|
|
|
|
## Development Order
|
|
|
|
The following phase IDs and titles are frozen. They MUST NOT be renamed,
|
|
renumbered, or reused; later work receives a new phase.
|
|
|
|
The active order is P0..P5, then P7 functionality, then the new P9 storage
|
|
migration, then final P8 physical/release closure. Existing P8 software and
|
|
banked-KWS integration work is reused; P9 does not depend on completed P8
|
|
physical signoff. Phase numbers are stable identities, not a reason to create
|
|
a circular prerequisite. P6 is a deferred placeholder, not an implementation
|
|
task or a prerequisite for P7/P8/P9. Record
|
|
it as DEFERRED, not completed or verified. Resuming MP3 requires a later
|
|
explicit scope refreeze; the retained reference material is not authorization
|
|
to start it automatically.
|
|
|
|
### Phase 0 - Freeze Coreless Microcode Architecture and ABI
|
|
|
|
ID: `APU-P0`.
|
|
|
|
Scope: this specification, requirements, coreless hierarchy, ISA, `APUMC`,
|
|
`APUM`, descriptor/register/error/IRQ ABI, format limits, KWS baseline, golden
|
|
models, dependency plan, and stable phases.
|
|
|
|
Changes: documentation/index/RTL guide only. It freezes future public
|
|
interfaces but changes no executable RTL, address map, software, dependency,
|
|
clock/reset inventory, or CI.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
git diff --check
|
|
```
|
|
|
|
Completion: all links/commands resolve, rejected processor/host-decode behavior
|
|
is absent from normative requirements, and all deferred work is explicit.
|
|
|
|
### Phase 1 - APB4 Shell, Resource Ownership, and IRQ Topology
|
|
|
|
ID: `APU-P1`.
|
|
|
|
Scope: APB register shell, reset/capability/command/error/IRQ, fail-closed
|
|
datapath stubs, Resource index7, APB slot, LP IRQ31, HP PLIC10, HAL discovery,
|
|
manual C/SVH definitions, and parity tests.
|
|
|
|
Dependencies: Phase0.
|
|
|
|
Public changes: activates `APB4_APU`, extends resource count and IRQ topology;
|
|
no DMA, microcode, stream, or CDC behavior is implemented.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
make check-memory-map check-soc-topology
|
|
make sw-format-check sw-policy-check sw-host-test
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke firmware
|
|
```
|
|
|
|
Completion: every APB/reset/access case and topology/parity check passes;
|
|
datapath commands return the frozen unsupported/error behavior.
|
|
|
|
### Phase 2 - Private AXI4 DMA and Audio Stream Routing
|
|
|
|
ID: `APU-P2`.
|
|
|
|
Scope: direct/ring DMA, descriptors, ACL, fair Gateway A arbitration,
|
|
PCLK-to-HP integration, stream router/FIFOs, I2S directions, abort/drain, bus
|
|
errors, P2 status/watermark semantics, and counters.
|
|
|
|
Dependencies: Phase1 and existing Common interfaces/FIFO/CDC/arbitration.
|
|
|
|
Public changes: implements DMA/ring/ACL transport, the appended
|
|
`STREAM_WATERMARK` register, frozen `STREAM_STATUS`/`JOB_STATUS`/
|
|
`RING_STATUS` fields, `CAPABILITY0=0x00000018`, and the `apu_data` CDC
|
|
inventory. `CAPABILITY1`, `ABI_DIGEST`, format/stream/KWS/sequencer/resampler
|
|
capabilities, public start/doorbell, and public APU stream routes remain at the
|
|
specified fail-closed P1 values. No sequencer, primitive, codec, KWS, public
|
|
diagnostic operation, or synthesized diagnostic endpoint is added.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
make check-soc-topology check-clock-reset-domains
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk formal
|
|
make CONFIG=configs/ci/ihp130.mk SIMU=VERILATOR rtl-lint
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke SIMU=VERILATOR firmware sim
|
|
```
|
|
|
|
Completion: the production DMA and ring scheduler pass direct/ring directed and
|
|
random tests through the verification-only backend; the production router and
|
|
both 64-word FIFO directions pass standalone backpressure/watermark/xrun tests;
|
|
public start/doorbell and route value1 remain rejected; every bus fault,
|
|
timeout, coalescing epoch, writeback, and abort path is bounded; status/IRQ/C
|
|
parity passes; Gateway A fairness is demonstrated. No P3..P7 engine is required
|
|
for P2 completion.
|
|
|
|
### Phase 3 - Microcode Assembler, Loader, and Sequencer
|
|
|
|
ID: `APU-P3`.
|
|
|
|
Scope: `apu-mcasm`, reference interpreter, ISA tables, `APUMC` loader,
|
|
2048x64 control store, scalar/loop/call state, load-time local/table protection,
|
|
watchdog/traps, loader lock/atomic publication, ABI parity, co-simulation, and
|
|
formal. Class-2 through class-6 execution, codec tables, and data SRAM remain
|
|
outside this phase.
|
|
|
|
Dependencies: Phase2, the Common `tc_sram_1024x32` wrapper for macro profiles,
|
|
and the frozen inferred-control-store fallback for `HAVE_SRAM_MACRO=NO`.
|
|
|
|
Public changes: implements the frozen microcode loader, class-0/class-1
|
|
sequencer, `MC_STATUS`, `MC_ABI`, build/CRC/lock/count, IRQ bit 3, and exact
|
|
P3 values `CAPABILITY0=0x00000098` and `CAPABILITY1=0x00000010`.
|
|
`ABI_DIGEST` remains zero. Public direct/ring commands and APU stream routes
|
|
remain fail-closed, and the verification-only dummy launch adds no public ABI.
|
|
It adds no processor, system hart, new clock domain, or arbitrary code
|
|
execution.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk formal
|
|
make CONFIG=configs/ci/ihp130.mk SIMU=VERILATOR rtl-lint
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke LINK_TYPE=ld2_all_sram SOC_SIM_TIME=360 VERILATOR_SIM_ARGS=--fast-flash SIMU=VERILATOR HAVE_SVA=YES firmware sim
|
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS synth
|
|
make CONFIG=configs/ci/ics55.mk SYNTH=YOSYS synth
|
|
```
|
|
|
|
The 360-second command with `--fast-flash` is the supported P3 SoC-level
|
|
Verilator acceptance command; fast flash changes only boot/XPI timing and does
|
|
not bypass APU logic. Directed loader/sequencer tests remain the functional
|
|
evidence for the P3 paths.
|
|
|
|
Completion: all three required zero-table/zero-primitive entries load
|
|
atomically and deterministic class-0/class-1 dummy programs execute through
|
|
the verification-only launch. Every malformed header/descriptor/ISA/control-
|
|
flow/range/table/CRC/capability/watchdog case fails closed with the frozen
|
|
status, IRQ, count, and reset result. Macro and inferred control-store mappings,
|
|
including ICS55 elaboration/synthesis, are reviewed. No P4..P7 engine is
|
|
required for P3 completion.
|
|
|
|
### Phase 4 - Shared Bitstream, Entropy, and DSP Primitive Engines
|
|
|
|
ID: `APU-P4`.
|
|
|
|
Scope: reservoir, CRC, Huffman/Rice, scalar reconstruction, transform,
|
|
resampler/PCM packer, 112 KiB local SRAM arbitration, primitive scoreboard,
|
|
latency counters, extreme arithmetic tests, and formal bounds. The implemented
|
|
primitive mask is `0x0000ffff`; class 6 and primitive bits 16..20 remain
|
|
outside this phase.
|
|
|
|
Dependencies: Phase3, Common `tc_sram_1024x32`, and Common `stream_fifo`.
|
|
|
|
Public changes: reports exact P4 values `CAPABILITY0=0x00000198` and
|
|
`CAPABILITY1=0x01827010`, admits the frozen class-2..5 ISA and APUMC table/
|
|
scratch fields, and retains `ABI_DIGEST=0`. Format, stream, and KWS capabilities
|
|
remain zero, while primitive channel/rate discovery becomes 2/96 kHz; public
|
|
direct/ring/stream behavior stays fail-closed. No new public register, opcode
|
|
class, format ID, IRQ, resource, address, clock/reset boundary, or CDC/RDC entry
|
|
is added.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk formal-apu
|
|
make CONFIG=configs/ci/ihp130.mk SIMU=VERILATOR HAVE_SVA=YES rtl-lint
|
|
```
|
|
|
|
`tests/test_apu_primitives.py` is a required P4 deliverable and runs the same
|
|
golden corpus through the Python BAM/interpreter plus focused Icarus and
|
|
Verilator primitive testbenches. `formal-apu` must include the P4 dispatcher,
|
|
local-range/validity, single-kernel, and latency-counter properties.
|
|
|
|
Completion: every primitive matches BAM over directed/random/extreme inputs,
|
|
meets the frozen ready-data latency bound, reports the frozen fault tuple,
|
|
proves local/table/FIFO bounds, and preserves all fail-closed public paths.
|
|
Yosys synthesis, OpenSTA, netlist simulation, macro PPA, and 48 MHz closure are
|
|
explicitly deferred to Phase8 and are not P4 completion gates.
|
|
|
|
### Phase 5 - WAV and FLAC Microprograms
|
|
|
|
ID: `APU-P5`.
|
|
|
|
Scope: WAV/FLAC microassembly, tables, metadata/frame parsing, PCM conversion,
|
|
Rice/fixed/LPC/decorrelation, resampling, memory/I2S output, interpreter/RTL
|
|
differential, conformance corpus, and the frozen P5 HAL. Includes production
|
|
class-6 transport, controller entry context, direct/ring backend connection,
|
|
TX stream routing, and exact codec/result policies in the P5 sections above.
|
|
The capacity refreeze adds the 4096x64 store, 12-bit PC/branch datapaths,
|
|
APUMC V2 plus legacy V1 decoding, and APB V1.1 PC_HIGH/capacity discovery to
|
|
this phase. Previously completed transport, HAL, formal, and corpus work is
|
|
the implementation base and is preserved except for the required version/
|
|
capacity/width integration.
|
|
|
|
Dependencies: reviewed Phase4 and the exact RFC/libFLAC/corpus inputs above.
|
|
Implement their dependency-lock/setup entries before reference tests. No host
|
|
decoder enters the product path.
|
|
|
|
Public changes: `CAPABILITY0=0x000001bd`, `CAPABILITY1=0x01827020`, implemented
|
|
primitive mask `0x001fffff`, classes 0..6, format IDs 0/2, TX route 1, and the
|
|
documented HAL. `IP_VERSION=0x00010001`; new release images are APUMC V2.0,
|
|
with widened entry PC/branch operands and PC_HIGH at SEQUENCER_STATUS bit 21.
|
|
MP3/KWS/RX route 1 remain unavailable and `ABI_DIGEST=0`. No existing APB
|
|
offset, job-descriptor layout, legacy APUMC V1 encoding, P1..P4 target behavior,
|
|
Resource7, APB group23, IRQ31/PLIC10, Gateway A identity, or clock/CDC allocation
|
|
changes.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
python3 scripts/dependency_lock.py --lock dependencies/dependencies.lock.json
|
|
make sw-format-check sw-policy-check sw-host-test
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk firmware
|
|
make CONFIG=configs/ci/ihp130.mk SIMU=VERILATOR HAVE_SVA=YES rtl-lint
|
|
make CONFIG=configs/ci/ihp130.mk formal-apu formal-apu-loader formal-apu-sequencer
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke LINK_TYPE=ld2_all_sram SOC_SIM_TIME=360 VERILATOR_SIM_ARGS=--fast-flash SIMU=VERILATOR HAVE_SVA=YES firmware sim
|
|
```
|
|
|
|
`tests/test_apu_codecs.py` and `tests/test_apu_codec_transport.py` are P5
|
|
deliverables included by the full Pytest command; missing required EDA/reference
|
|
tools are reported as unrun, never counted as passing skipped tests. The
|
|
ci_smoke command proves SoC integration and does not replace the directed
|
|
codec corpus or long-playback evidence.
|
|
|
|
Capacity-migration verification is mandatory in those same test/formal flows:
|
|
|
|
- V1 accepts 2048 words and rejects 2049; V2 accepts complete 2049/2437/4096-
|
|
word fixtures and rejects 4097. A count of zero is rejected in both. Test
|
|
V1 high descriptor bits and immediate bit 11, V2 reserved bits and immediate
|
|
bit 12, unknown ABI, bad CRC, and field/region overflow with exact loader
|
|
error tuples and no valid/lock publication.
|
|
- Round-trip entry/first/last PCs 0, 2047, 2048, and 4095 in handwritten SV/C
|
|
and Python tables. Exercise jump/call/return/loop crossings in both directions
|
|
across 2047/2048, zero/maximum deltas, underflow and a target of 4096; call
|
|
and loop depth/budgets retain their existing limits. No high bit may alias.
|
|
- Verify loader writes, proof-state save/restore and fetches across all four
|
|
depth banks with distinct low/high words. Verify eight-macro and inferred
|
|
mappings in behavioral tests, including the no-macro profile. Abort/reset/
|
|
CRC failure after upper-bank writes must leave stale code unexecutable;
|
|
legacy images cannot execute it. Run the complete existing V1 P3/P4/P5
|
|
fixtures, retaining their original binary bytes and terminal tuples.
|
|
- At PCs 2048 and 4095, verify SEQUENCER_STATUS PC_HIGH and all existing
|
|
class/opcode/wait/loop fields, full ERROR_ADDRESS, unchanged low-PC detail
|
|
packing, explicit-TRAP immediate, and END/trap/abort/reset retention. Include
|
|
an aux value with bit 4 set so no diagnostic bit is silently lost.
|
|
- Rebuild the shared production WAV/FLAC bundle with every previously frozen
|
|
parser/output/error path, cross-frame FLAC resampling, and complete supported
|
|
long-Rice handling. Count every control-store word including the MP3 stub,
|
|
common subroutines and padding. The complete bundle must use at most 4096
|
|
words and publish exact size, free words, CRC/build/SHA-256 and source hashes.
|
|
A larger capacity alone, the incomplete 2437-word trial, or passing only
|
|
already-delivered transport tests cannot establish P5 completion. If the
|
|
complete image still exceeds 4096, report a capacity conflict; do not remove
|
|
required paths or move parsing into RTL/LP/HP.
|
|
|
|
Completion: the exact supported/rejected matrices, malformed corpus, published
|
|
error/count rules, HAL host tests, and production direct/ring/TX paths pass.
|
|
Matching-precision/rate/channel FLAC is bit-exact; 44.1-to-48 and 24-bit/96 kHz
|
|
playback meet the cycle-counted xrun gate. Larger FLAC blocks, whole-file MD5,
|
|
unlisted conversion ratios, MP3 and KWS are outside P5. Synthesis/STA/netlist/
|
|
PPA remain deferred to Phase8; functional cycle evidence is not timing signoff.
|
|
|
|
### Phase 6 - MP3 Layer III Microprogram and Real-Time Closure
|
|
|
|
ID: `APU-P6`.
|
|
|
|
Status: DEFERRED for the current release. The ID and title are retained for
|
|
traceability; this phase must not be reported as implemented, passed or merged
|
|
merely because it has been excluded.
|
|
|
|
Scope: no MP3 implementation in this release. Do not add an active p6 target,
|
|
MP3 microprogram, three-real-codec bundle, MP3 reference/corpus setup, or MP3
|
|
PSNR/real-time qualification on behalf of this phase. Retain the existing
|
|
format ID, enum, reserved diagnostic IDs and unsupported-MP3 trap entry.
|
|
Previously implemented P4 primitives, 4096-word control store, APUMC V1/V2
|
|
compatibility, and all P5 functionality remain unchanged.
|
|
|
|
Dependencies: none for the current active release path. A future MP3 effort
|
|
requires an explicit refreeze and a fresh capacity/behavior/evidence review;
|
|
the archived P6 notes do not activate it.
|
|
|
|
Public changes: none from this deferred phase. MP3 CAPABILITY0 bit 1 stays
|
|
zero. Discovery remains `0x000001bd` before KWS and becomes `0x000001fd`
|
|
only when P7's KWS capabilities are actually implemented and qualified.
|
|
`CAPABILITY1=0x01827020` and `IP_VERSION=0x00010001` are retained;
|
|
`ABI_DIGEST=0` through P7. P5 direct/ring MP3 rejection and the exact
|
|
verification-only trap-stub result remain required.
|
|
|
|
Validation: no positive MP3, dual-decoder, MP3 dependency, 320 kbit/s, >96 dB
|
|
or three-active-codec packing gate applies. Continue the existing P5
|
|
unsupported-request, legacy image, ABI parity, and primitive regressions.
|
|
|
|
Exit status for release planning: DEFERRED, not COMPLETE. The next active
|
|
phase is P7 from reviewed P5; P8 reviews the active WAV/FLAC/KWS release and
|
|
does not wait for P6.
|
|
|
|
### Phase 7 - Independent Continuous KWS Engine
|
|
|
|
ID: `APU-P7`.
|
|
|
|
Scope: 16 kHz input, MFCC, `APUM` converter/loader/lock, fixed INT8 engine,
|
|
continuous scheduler, threshold/debounce, diagnostic operation1, IRQ, accuracy,
|
|
performance, and concurrent decode/KWS.
|
|
|
|
Dependencies: reviewed Phase5; the P7 source/model/corpus/converter contracts
|
|
above are frozen inputs. Registering their exact dependency entries and
|
|
installing them through the shared setup flow is P7 implementation work,
|
|
not an open choice of model/dataset or a missing-user-data prerequisite.
|
|
Deferred Phase6 is not a prerequisite and its MP3 reports are not required.
|
|
|
|
Public changes: implements frozen KWS/model/descriptor-operation/IRQ/counter
|
|
ABI, the additive KWS HAL and KWS_INPUT_CONFIG at `0x23c`, and RX route 1.
|
|
The I2S wrapper also exports its existing synchronized RX flush-busy state
|
|
to APU over the specified same-PCLK internal wire.
|
|
Existing offsets/reserved masks, 128-byte descriptor, APUMC V1/V2, 4096-word
|
|
control store, bank count, Gateway/IRQ/resource/pad/clock/CDC allocations are
|
|
unchanged. `CAPABILITY1=0x01827020`, `IP_VERSION=0x00010001` and `ABI_DIGEST=0`
|
|
remain required. Only after every P7 gate passes does the release capability
|
|
change from P5 `0x000001bd` to `0x000001fd`; MP3 bit1 remains zero. No generic
|
|
NPU interface, CPU MFCC, host inference or shared-codec-lane fallback.
|
|
|
|
Implementation order within this single phase:
|
|
|
|
1. Add exact dependency inputs, offline verification and the fixed corpus
|
|
manifest import; implement converter contract 1.0.0 and independent BAM.
|
|
2. Add handwritten RTL/C/Python APUM/register parity, wire fixtures and
|
|
deterministic HAL packing tests before enabling public commands.
|
|
3. Implement bounded model DMA/CRC/validation/atomic lock and failure tests.
|
|
4. Add the independent banks10..25 client, capture/FIR/MFCC/16-lane inference,
|
|
fixed graph, scheduler, snapshot/status/counters and lifecycle integration.
|
|
5. Activate RX route1 and direct/ring operation1 with HAL, firmware and
|
|
fault/ownership tests; retain all reviewed P5 and MP3-stub behavior.
|
|
6. Produce the complete P7 differential, 1000-window accuracy, concurrency
|
|
and lifecycle reports, then promote only the KWS capability bit.
|
|
|
|
Validation after implementation (these commands are not evidence of results
|
|
from this documentation-only refreeze):
|
|
|
|
```sh
|
|
python3 scripts/dependency_lock.py --lock dependencies/dependencies.lock.json
|
|
ruff check .
|
|
make sw-format-check sw-policy-check sw-host-test
|
|
python3 -m pytest -q
|
|
make CONFIG=configs/ci/ihp130.mk formal
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke SIMU=VERILATOR firmware sim
|
|
git diff --check
|
|
```
|
|
|
|
P7 must additionally register and run directed KWS model/frontend/inference,
|
|
HAL and full qualification tests under Pytest and the affected formal/firmware
|
|
flow; a green generic smoke is not a substitute for the seven named reports.
|
|
Extend `scripts/setup_apu_reference.py` with `--target p7` and `--doctor`,
|
|
preserving its current `--build-dir` and P5 default behavior. The future
|
|
converter accepts `--target p7 --model <verified-tflite> --output <apum>` and
|
|
`--manifest <json>`; all paths resolve inside the active build directory except
|
|
read-only managed model input. These options are implementation deliverables,
|
|
not commands assumed to exist before P7.
|
|
|
|
Completion: every byte/schema/loader/HAL/lifecycle gate above passes, every
|
|
layer is bit-exact, all 1000 windows execute through hardware with top-1
|
|
>=900/1000, and concurrent WAV/FLAC plus KWS meets the stated zero-xrun gate.
|
|
The source manifest and generation hashes must be reported, not inferred
|
|
from a successful simulator exit. Synthesis, netlist, OpenSTA, full LP/HP
|
|
contention and commercial physical closure remain P8; P6 remains deferred.
|
|
|
|
### Phase 8 - LP/HP Software, Contention, and Physical Evidence
|
|
|
|
ID: `APU-P8`.
|
|
|
|
Scope: complete freestanding HAL, LP-only startup load, HP ownership/jobs,
|
|
cache maintenance, handoff, USB2/SDIO0 contention, full regression, synthesis
|
|
recipes, netlist, OpenSTA, warnings/metrics, and commercial-gap report. Linux
|
|
ASoC is deferred because this phase does not freeze a Linux DT binding, kernel
|
|
driver ABI, or ALSA ownership protocol.
|
|
|
|
Dependencies: Phases1..5 and Phase7. Phase6 remains DEFERRED and is not a
|
|
release prerequisite. Post-P9 physical/release closure additionally requires
|
|
Phase9; previously completed P8 software work need not be repeated except for
|
|
the new asset-loading/discovery integration and affected regression.
|
|
|
|
Public changes: completes frozen HAL and bare-metal LP/HP surfaces; Linux ASoC
|
|
is not part of this phase. It introduces no further public changes beyond the
|
|
separately approved P9 V1.2 extension; descriptor, APUM/APUMC, address-map,
|
|
system IRQ/resource/clock allocations remain fixed.
|
|
|
|
Validation:
|
|
|
|
```sh
|
|
make sw-format-check sw-policy-check sw-host-test
|
|
python3 -m pytest -q
|
|
make regress-pr
|
|
make regress-nightly
|
|
```
|
|
|
|
Completion: every active WAV/FLAC/KWS MVP item passes; IHP130 block/full-SoC
|
|
evidence is reviewed; unrun commercial gates remain explicit; no unsupported
|
|
claim ships. MP3 remains unadvertised and its absence does not block this
|
|
release. Pre-P9 capability remains `0x000001fd`; the post-P9 release uses
|
|
`0x000003fd`. P8's digest covers the actual released contract, including the
|
|
P9 coefficient extension when present and the reserved MP3 IDs/stub, and
|
|
excludes inactive P6 proposals. Reusing pre-P9 physical results or digest as
|
|
proof of the new macro-backed release is not permitted.
|
|
|
|
### Phase 9 - Macro-backed Coefficients and Loader Memoization
|
|
|
|
ID: `APU-P9`.
|
|
|
|
Scope: replace the large synthesized KWS coefficient/profile tables and
|
|
microcode memo arrays with the exact dedicated physical-bank layout, add
|
|
bounded synchronous access and LP APUC initialization, and qualify inferred-
|
|
memory, synthesis resource, numerical and real-time behavior. This is not a
|
|
new model, reduced workspace, approximate frontend or MP3 phase.
|
|
|
|
Dependencies: the inspected P5/P7 implementation and its existing banked KWS
|
|
client/P8 ownership integration, the frozen generators/BAM/model/corpus, the
|
|
current Common/technology wrappers and IHP130 macro views. Existing functional
|
|
evidence must be rechecked at preflight; missing evidence is not assumed PASS.
|
|
Full P8 physical signoff is an output after this phase, not its prerequisite.
|
|
|
|
Public changes: APB V1.2, CAPABILITY0 bit9, registers `0x240..0x260`, local
|
|
IRQ11, APUC1 container and two additive HAL APIs as specified above. Existing
|
|
field meanings/offsets, APUM1 bytes, APUMC V1/V2, 128-byte descriptors,
|
|
advertised capacities and system topology/clock/reset allocations are retained.
|
|
An extra LP coefficient load is intentionally required for KWS after hard reset.
|
|
|
|
Implementation order within this phase:
|
|
|
|
1. Capture baseline A inventory/flow status and deterministic table/proof
|
|
fixtures; generate the exact APUC image and independent layout oracle.
|
|
2. Migrate memo keys/bitmap to 17 macros, reusing Common register/control
|
|
primitives and preserving exact proof, clear/insert and abort semantics.
|
|
3. Add 15 coefficient SRAMs, tagged synchronous ports and exclusive loader/
|
|
readback/lock, then the handwritten APB/C/Python constants and HAL.
|
|
4. Replace all production function lookups, including APUM fixed-word checks,
|
|
with SRAM transactions. Retain bit-exact arithmetic and add only bounded
|
|
state/latency needed by the macro interface or exact iterative operations.
|
|
5. Update LP/HP startup and evidence fixtures to load APUC, extend lifecycle/
|
|
formal/host tests, update ABI-digest and macro-accounting tooling, and run
|
|
the full existing numerical/concurrent corpus gates.
|
|
6. Capture candidate B using the unchanged comparison flow, verify the
|
|
inferred-bit reduction and actual runtime/RSS change, then refresh P8
|
|
macro/netlist/STA/area evidence. No acceptance status is inferred from
|
|
the design estimates or from a timeout.
|
|
|
|
Profile: `configs/ci/ihp130.mk`, locked tools, HAVE_SRAM_MACRO=YES, 48 MHz
|
|
PCLK performance target. Required existing entry points after implementation:
|
|
|
|
```sh
|
|
python3 scripts/dependency_lock.py --lock dependencies/dependencies.lock.json
|
|
ruff check .
|
|
make sw-format-check sw-policy-check sw-host-test
|
|
python3 -m pytest -q
|
|
python3 scripts/apu_abi_digest.py --check
|
|
make CONFIG=configs/ci/ihp130.mk formal
|
|
make CONFIG=configs/ci/ihp130.mk APP=ci_smoke SIMU=VERILATOR firmware sim
|
|
make CONFIG=configs/ci/ihp130.mk APU_BLOCK_ENABLE_P7=1 apu-block-synth apu-block-sta
|
|
make CONFIG=configs/ci/ihp130.mk apu-block-evidence
|
|
make CONFIG=configs/ci/ihp130.mk SYNTH=YOSYS synth
|
|
make CONFIG=configs/ci/ihp130.mk STA=OPENSTA sta
|
|
make regress-pr
|
|
make regress-nightly
|
|
git diff --check
|
|
```
|
|
|
|
The generic entry points do not replace the full 1000-window/60-second P7
|
|
qualification or the six P9 reports; register those tests and their exact
|
|
commands during implementation. Run A and B in separate revision-qualified
|
|
variants, not successive overwrites of the same outputs. New coefficient-
|
|
asset targets and extended report fields are deliverables, not tools assumed
|
|
already present in the source baseline.
|
|
|
|
Completion: every P9 requirement passes, all affected P5/P7 semantic results
|
|
remain equivalent, the added software-visible init flow is qualified, target
|
|
inferred memories are absent in macro synthesis, and the reported physical
|
|
inventory is 76 wrappers / 304 KiB with no hidden large register-file copy.
|
|
Timing/area/RSS/runtime evidence must describe the actual post-P9 hierarchy.
|
|
If functional or real-time gates fail, do not compensate by weakening
|
|
accuracy, using CPU inference, shrinking the memo or increasing the 100 ms
|
|
period. P6, Linux ASoC and commercial post-layout/silicon qualification remain
|
|
explicitly deferred/outside this phase.
|
|
|
|
## Commercial Delivery Gaps
|
|
|
|
The following remain release blockers after MVP unless separately closed:
|
|
|
|
These gaps apply to capabilities claimed by the delivered release. MP3/MPEG
|
|
decoder qualification is deferred with P6 and is not a blocker for the current
|
|
WAV/FLAC/KWS release.
|
|
|
|
- full requirements-to-test traceability and functional/code coverage closure;
|
|
- reusable APB4/AXI4/AXI4-Stream/I2S/microcode/descriptor/fault VIP;
|
|
- independent long-run WAV/FLAC interoperability, fuzzing, vulnerability
|
|
intake, and codec maintenance process; licensed MPEG conformance applies
|
|
only if MP3 is explicitly reactivated in a future release;
|
|
- KWS false-positive/false-negative qualification across speakers, accents,
|
|
noise, microphones, rooms, and target languages;
|
|
- authenticated/anti-rollback microcode/model update, confidential storage,
|
|
secure debug, and protected-content architecture;
|
|
- CDC/RDC and reset/clock-gating signoff with unilateral-reset fault injection;
|
|
- qualified SRAM for every PDK, ECC decision, MBIST/repair, scan/ATPG, and DFT;
|
|
- PVT/MMMC, CTS, extracted STA, SI, IR/EM, power, thermal, package, and board;
|
|
- gate/SDF, FPGA prototype, silicon characterization, audio quality, sustained
|
|
contention, and production soak;
|
|
- upstream-quality Linux ASoC, recovery/update policy, release notes, SBOM,
|
|
notices, integration examples, and versioned artifacts; and
|
|
- qualification of deferred codec, channel, low-power, coherency, safety or
|
|
security capabilities when they are later included in an advertised release.
|