feat: enhance documentation for Tiny SoC and PIO-lite extension

- Updated the tiny-soc-verification.md to clarify the separation of PIO-lite as a standard-product extension, detailing its planned features and evidence requirements.
- Revised tiny-soc.md to emphasize the historical context of the R2 design freeze and the independent nature of the PIO-lite extension, including its integration requirements and phase structure.
- Added details in soc-family-positioning.md regarding the PIO-lite extension's capabilities and its distinction from the R2 performance-only approval.
- Enhanced README.md files in rtl/ip and rtl/tiny to reflect the future integration of the PIO-lite extension, specifying its features and the implications for existing RTL and DMA configurations.
This commit is contained in:
maksyuki committed 2026-10-04 22:35:36 +08:00
1 parent f633159109
commit dad28f0c39
11 files changed
+1388 -27

No files matched your search

+6
View File
@@ -11,6 +11,12 @@ the root README and subsystem guides.
remain in the linked contract history. CPU/main-SRAM rates up to 240 MHz
require qualification. These targets remain separate from the existing
24 MHz/four-channel implementation and physical evidence.
- [PIO-lite](ip/piolite.md) freezes the separately approved future Tiny
standard programmable-I/O block: two state machines, shared 32x16 program
store, existing GPIO USER ownership, PCLK execution and central DMA V2.1
requests 14/15. Its `PIOLITE-P0..P5` phases preserve the historical
performance-only R2 boundary; the [verification ledger](ip/piolite-verification.md)
retains all implementation, application and physical evidence gaps.
- [Tiny Gen1 datasheet](../publications/datasheets/tiny/README.md) describes the
current 24 MHz implementation, registers, software and qualification boundary;
it does not yet describe the QFN64 Gen1 target.
+8
View File
@@ -5,6 +5,14 @@ does not need an address on every word. APB4 remains the register configuration
plane. The active stream endpoints are DMA to I2S TX, I2S RX to DMA, and DVP RX
to DMA. UART, I2C, and WS2812 retain their existing APB4 FIFO data registers.
The separately frozen [Tiny PIO-lite](ip/piolite.md) extension adds a planned
central-DMA TX/RX pair at requests 14/15 through [DMA V2.1](ip/dma.md).
Its PCLK 32-bit streams use full-word keep/strobe, one selected SM per direction,
exclusive channel-bound sessions and explicit abort/drain/isolation. It is not
implemented or enabled on Mini by this document. The historical I2S/DVP rules
below do not substitute for PIO-lite's packing, ownership or reset contract;
the existing [Crypto](ip/crypto.md) streams retain their own framing rules.
## Interface Contract
All three links use `DATA_WIDTH=32`, one-bit ID, destination, and user fields,
+149 -1
View File
@@ -26,6 +26,14 @@ rings. `TINY-R2-P3` prepares scheduling and `TINY-R2-P6` integrates the eight
channels. These are frozen Tiny requirements, not implemented Tiny or timing
evidence; the committed Tiny baseline still has four channels.
The [PIO-lite contract](piolite.md) freezes an additional **TINY-only product
integration target**, using the shared DMA V2.1 extension below. This is a
separate feature from Tiny's performance-only R2 roadmap. Current DMA RTL/HAL
still implement V2.0; the V2.1 register, ports, discovery and lifecycle rules
are requirements for subsequent implementation, not delivered capabilities.
Mini is an affected compatibility consumer of shared DMA changes, not a
PIO-lite rollout target. Existing phase IDs and evidence remain unchanged.
## Scope and limits
- Eight independent channel contexts share one AXI4 master (`ID=0`) in the
@@ -81,7 +89,7 @@ compares both definitions.
| Offset | Register | Access | Description |
| ---: | --- | --- | --- |
| `000` | `IP_ID` | RO | `DMA4` identification |
| `004` | `IP_VERSION` | RO | V2.0 |
| `004` | `IP_VERSION` | RO | Current V2.0 `0x00020000`; frozen V2.1 target `0x00020001` |
| `008` | `CAPABILITY` | RO | channel count, data width, maximum burst, stream count, descriptor=1 |
| `00c` | `GLOBAL_CTRL` | WO | bit 0 global reset |
| `010` | `GLOBAL_STATUS` | RO | any channel busy |
@@ -90,6 +98,7 @@ compares both definitions.
| `01c` | `IRQ_TEST` | RW | software interrupt test bits |
| `020` | `ERROR_SUMMARY` | RO/W1C | bit 0 valid/W1C, bits 3:1 channel, bits 15:7 status, bits 31:16 error-address upper half |
| `024` | `REQUEST_STATUS` | RO | peripheral pacing availability |
| `028` | `SUPPORTED_REQUESTS` | RO | V2.1 target only: static implemented request bitmap; absent in V2.0 |
Each channel occupies `0x80` bytes beginning at `0x100 + channel * 0x80`.
@@ -189,6 +198,145 @@ CRC-32/ISO-HDLC (`0xEDB88320`, init/xorout `0xffffffff`). Descriptors and data
must be in DMA-visible uncached/shared memory. Callers issue `fence rw,rw`
before start and after completion; no cache snoop or IOMMU is implied.
## Frozen V2.1 PIO-lite extension
### Scope and discovery
V2.1 MUST retain the existing direct-register offsets, four-bit request
selector, 64-byte TCD size/alignment and TCD request field `[15:12]`. Existing
request IDs 0-13 and their transfer kinds remain unchanged. In particular,
omitted Tiny I2C1 requests 9/10 MUST NOT be reused. No channel, AXI master,
cyclic descriptor, asynchronous stream clock or narrow-transfer mode is added.
| Request | ID | Transfer kind | Meaning |
| --- | ---: | --- | --- |
| `PIOLITE_TX` | 14 | MM-to-stream | Memory words into the selected SM TX FIFO |
| `PIOLITE_RX` | 15 | Stream-to-MM | Selected SM RX FIFO words into memory |
These are two block-level stream endpoints, not per-SM request pairs. One TX
SM and one RX SM may receive DMA service simultaneously; they may be the same
SM. Two concurrent RX DMA streams or two concurrent TX DMA streams are not
supported. Future four-SM configurations keep this endpoint limit unless a
separate extension changes the contract. Both endpoints use full 32-bit words,
`TKEEP/TSTRB=4'hf`, PCLK and the existing AXI master. Programmed byte count
terminates DMA; TX `TLAST` marks its final word and RX `TLAST` does not replace
the programmed count or terminate a PIO program. DMA completion confirms FIFO
transfer/memory-write completion, not completion of a waveform at the pins.
`SUPPORTED_REQUESTS` at `0x028` MUST return bits 0-15 for request IDs 0-15 and
zero in bits 31-16. Its cold-reset value is the build's effective implemented
mask: combine the request mask, supported transfer logic, stream-enable
parameters and actual product wiring. A reserved port, tied-off endpoint or
disabled stream MUST report zero. The value is static integration capability,
not FIFO readiness, current channel ownership or whether a PIO binding is
enabled. Writes return `PSLVERR` without changing state. `REQUEST_STATUS`
retains live pacing semantics and MUST NOT be interpreted as support discovery.
V2.1 `CAPABILITY[30:28]` MUST report the population count of implemented
stream-direction requests 1, 2, 11, 12, 13, 14 and 15 in that effective mask.
Seven is the maximum and fits the existing field. Other capability fields
retain their existing layout/encoding. The current V2.0 implementation's
hard-coded stream value 3 is historical behavior, not a reliable endpoint
inventory. V2.1 corrects the reported count without moving the field.
The two PIO ports and their grants MUST default disabled in shared-IP
instantiations. Mini keeps bits 14/15 clear and its current owners and endpoints;
updating the shared implementation does not enable PIO on Mini. Tiny asserts
each support bit only when the complete corresponding endpoint is integrated.
The product capability metadata, hardware mask and software checks MUST agree.
Software MUST check DMA identity/version before accessing `0x028`, which is
an invalid offset on V2.0. PIO DMA requires the V2.1 contract and both the
requested DMA support bit and the PIO block's capability/probe result. Product
metadata prevents probes of an absent PIO address. Absent, old-version or
unimplemented support returns `RS_ENOTSUP` before channel programming; live
readiness cannot substitute for these checks. CPU FIFO access remains a
separate PIO capability. The SVH/C register constants remain handwritten and
covered by register-parity checks.
### Endpoint binding and channel ownership
The PIO block owns one binding per direction: selected SM, exclusive DMA
channel and enable. The two enabled bindings MUST name distinct implemented
channels. Product application profiles reserve these channels explicitly;
Tiny's R2 default owners are not silently displaced. A bound mixed TCD chain
belongs entirely to that PIO session, including descriptors that use another
request. Aborting the session aborts that whole bound job.
The shared DMA receives default-disabled one-hot allowed-channel grants for
each PIO endpoint and a closing/admission guard for the reserved channels.
Direct START and every TCD activation MUST validate the transfer direction,
static request support and matching enabled channel grant before moving data.
Malformed, unsupported or unbound PIO requests report a channel configuration
error without issuing their payload transaction. TCD fetches needed to discover
an invalid descriptor still follow the normal accepted-read drain rules.
DMA exports complete job ownership and pending admission to the PIO integration.
Ownership spans the whole direct transfer or finite TCD chain, including
descriptor fetch/parse, non-PIO descriptors, suspension, accepted payload
transactions and abort/error drain. It MUST NOT be inferred from the currently
selected request or stream `TVALID`. Unrelated DMA channels continue running.
A binding enable, disable, channel/SM change or endpoint reset MUST be rejected
while either its old or proposed channel owns a job or has a pending START.
It also requires no unresolved endpoint beat/session. A same-cycle accepted
DMA START takes precedence over a conflicting binding change/reset, using the
current registered binding; rejected commands leave the old binding intact.
This rule applies even when the first/current descriptor does not use PIO.
Do not require global DMA idleness or restrict this extension to direct mode.
### Cancellation and stream cleanup
Abort is distinct from immediate endpoint reset. The PIO session first enters
closing state, disables pin output enables and stops new SM execution. Closing
MUST reject new STARTs on its reserved channels and prevent further descriptor
activation; it retains the old binding while accepted work drains. The TX
endpoint remains able to handshake/discard an already-present DMA beat even
when the SM FIFO was full. RX stops producing new words but preserves any
already-asserted `TVALID` and payload through the stream cleanup boundary.
The V2.1 DMA cancellation path MUST give abort/error cancellation priority over
new descriptor-fetch issue and descriptor activation, including simultaneous
commands. Accepted descriptor AXI reads, as well as payload reads/writes, must
complete through their terminal responses. Canceled fetched descriptors MUST
NOT activate or clear an abort request. Clear canceled queued fetch/parse work
without issuing it. Complete job ownership is released only after these
conditions hold; the current payload-only ownership test is not sufficient.
Software aborts only the bound DMA channels and waits with a bounded timeout
for complete job drain. Then the integration isolates the affected stream
endpoint and acknowledges a local stream-session reset on both sides before
flushing its residual FIFO/held RX word or changing its route. Channel idle
alone does not permit withdrawing a held RX `VALID`: a transfer can reach its
programmed byte count with residual source data. This local cleanup MUST NOT
reset the common DMA or disturb other channels. Normal, non-reset stream
operation preserves VALID and payload until handshake.
A timeout leaves outputs high impedance and the old binding closed/owned;
it does not acknowledge reset, reassign a channel or reuse memory still owned
by DMA. Recovery retries bounded drain/isolation under the product lifecycle
policy. Clock gating and endpoint reset require that complete handshake;
FIFO empty, SM stopped or a read of channel BUSY alone is insufficient.
### Required implementation evidence
The PIO-lite development order owns this extension's implementation gates.
Required evidence includes V2.0 rejection without reading `0x028`, V2.1
identity/parity/RO errors, accurate masks/counts at each staged integration,
default-disabled Mini ports, direct and finite mixed TCD transfers, endpoint
direction/channel rejection, and full-duplex use of distinct bound channels.
Exercise START versus rebind/reset, later PIO descriptors in an active chain,
suspension, descriptor-fetch backpressure, abort during fetch/parse/activation,
full TX FIFO, residual RX VALID after count completion, isolation/reset,
timeout retention and unrelated-channel progress. Formal/RTL checks must
cover route stability, no stale descriptor activation, accepted-transaction
drain and source stability outside the acknowledged local reset interval.
Run the affected DMA/GPIO host, register-parity, RTL and formal checks plus
Tiny end-to-end and affected Mini regressions for the implemented phase. The
existing verification described below is baseline coverage; it does not
establish these new V2.1 properties or a new PIO frequency/physical result.
## Validation boundary
`tests/rtl/dma_error_tb.sv` uses a native AXI4 BFM for exact counts, 4 KiB
+129
View File
@@ -7,6 +7,14 @@ filtered inputs, per-pin interrupts, irreversible configuration locks, and
capability discovery. The register ABI is directly encoded in RTL and C; a
register generator is intentionally not used in this version.
The [PIO-lite contract](piolite.md) freezes a prospective Tiny binding of the
existing user-IP owner to PIO-lite across all 32 GPIO. The integration and HAL
requirements below are not implemented capabilities: current Tiny ties the
user-IP outputs inactive. GPIO's APB ABI remains V2.0, with unchanged offsets,
reset values, ALT0/ALT1 assignments and lock semantics. This is not an ALT2,
new-pad, QFN64 change or a Mini PIO integration. Existing evidence and Tiny R2
phase IDs remain unchanged; PIO-lite has its own development order.
## Integration
| Property | Value |
@@ -117,6 +125,127 @@ high plus low is invalid. Level events reassert sticky state while the level
remains active. The output interrupt is the reduction OR of
`INTR_STATE & INTR_ENABLE`.
## Frozen Tiny PIO-lite ownership binding
### Integration and input timing
Tiny MUST bind the PIO block's output data/enables to `user_gpio_if` and consume
its synchronized input path. All 32 ordinary GPIO remain routable; dedicated
boot XPI, JTAG and system pins are outside this binding. `USER_SELECT` selects
the existing user-IP owner over software GPIO and ALT0/ALT1, preserving their
mapping and the existing one-clock high-impedance handoff. Existing peripheral
inputs may still observe their raw pad routes, so software must quiesce the
previous peripheral owner before claiming a pin. Routable pins are not a claim
that all 32 are simultaneously unused by a board profile.
Expose read-only integration outputs for `USER_SELECT`, `USER_STATUS` and
`FILTER_ENABLE`. `USER_SELECT` is the actual GPIO owner-selection register;
`USER_STATUS` MUST equal the active ownership mask already read through APB:
`USER_SELECT & ~handoff`. These are status wires to the PIO integration, not
new APB registers or a new GPIO version. Mini may leave the new outputs unused;
its user-IP ownership behavior remains unchanged.
Tiny's sole user-IP pad owner is PIO-lite. Its `OWNED_MASK` and the Tiny RCU
GPIO gate/reset veto MUST therefore use actual `USER_SELECT`, including the
acquisition handoff interval, independently of mutable SM `CLAIM_MASK` values.
Rewriting a claim or clearing block configuration cannot release or conceal
selected GPIO. Normal PIO block reset/gating and GPIO gate/reset require
`USER_SELECT=0` after checked handback; the existing peripheral-reset contract
also applies. Tiny RCU supplies GPIO clock/reset readiness. Retained GPIO
status bits alone do not prove that its clock runs.
Before SM START, every participating IN/WAIT/OUT/OE pin MUST be claimed and
present in `USER_STATUS`, with its `FILTER_ENABLE` bit clear and GPIO lifecycle
ready. PIO SM output masks MUST be disjoint; input masks may be shared only
within the PIO session. The PIO output enables are continuously qualified by
valid pin ownership and readiness. Lost ownership, enabled filtering on a
claimed pin or lost readiness forces affected PIO outputs high impedance,
stops the affected SMs and records a sticky fault. Restoration of the GPIO
state MUST NOT automatically restart an invalidated session.
Once GPIO ownership has been acquired for a session, guard invalidation also
covers its disabled-but-armed SMs, including an armed DMA job or DMA-prefilled
FIFO waiting for START. Unexpected GPIO reset or lost ownership/readiness
invalidates those sessions, closes their transport admissions and requires
explicit drain/reset recovery and reacquisition before restart. Monitoring
only RUNNING/PAUSED/HALTED would permit stale prefilled data to survive into a
replacement session. Passive CPU preload before any session acquisition is
not supported: CPU FIFO access and enabling a DMA binding require the same
valid ownership/filter/readiness guard. Neither a preload nor a binding
implicitly claims GPIO; software must acquire ownership first.
Filtering is disabled for claimed pins, but the existing input path still
contains two synchronizer stages and a registered filtered-input stage.
PIO timing specifications MUST account for that pipeline and asynchronous
sampling uncertainty. This binding adds no raw-input bypass, independent input
clock or claim of single-cycle external edge observation. PIO and GPIO share
PCLK; PIO's integer divider is an execution enable, not another GPIO clock.
### Checked acquisition and release
The PIO HAL MUST provide checked session acquisition/release instead of treating
the current sequential `rs_gpio_configure()` or `rs_gpio_user_ip_select()`
writes as an atomic reservation. The shared software owner serializes pin
changes against interrupt handlers and other drivers. Hardware pin ownership
checks complement this software contract; they are not a privilege or security
boundary against arbitrary same-hart register writes.
1. Reserve the complete union of participating pins and verify the selected
board profile, prior owners, SM masks and requested electrical settings.
Read `USER_SELECT`, `USER_STATUS`, `USER_LOCK`, `CONFIG_LOCK`, filter and
relevant mode/pad state before mutation. Reject conflicts and every locked
change required for both acquisition and eventual safe release.
2. Stop the previous peripheral owners, drain their traffic and release their
external drivers. Prepare a safe native GPIO/ALT state for later handback.
Keep the PIO SMs stopped and their output enables zero. Disable filtering
only for claimed pins; do not reprogram the global filter divider/count or
alter another session's pins. Apply supported pad settings and verify them.
3. Set `USER_SELECT` for the claimed mask and wait boundedly for matching
`USER_STATUS` after the handoff guard. Verify the unfiltered input and
lifecycle guards before enabling the SMs. Partial failure keeps affected
PIO output enables zero and uses checked rollback; it cannot report a
successful claim or silently resume a previous owner.
4. Release first stops pin activity and completes the bound DMA/stream cleanup
specified in [DMA V2.1](dma.md#cancellation-and-stream-cleanup). Keep output
enables zero. Before clearing `USER_SELECT`, ensure the native software OE
and alternate output path are safe. A retained ALT selection must not
reactivate a previous peripheral output implicitly.
5. Clear `USER_SELECT` only when permitted, wait boundedly for `USER_STATUS`
to clear, and then relinquish the software reservation. Restore a previous
peripheral configuration only through its owner's explicit restart path.
A timeout or failed readback retains the reservation and reports failure.
Dynamic PIO sessions MUST NOT set `USER_LOCK` or `CONFIG_LOCK` automatically.
`USER_LOCK` protects `USER_SELECT`; `CONFIG_LOCK` protects the separate
mode/pad/filter fields and does not lock ownership. Both remain write-one-set
until GPIO peripheral reset. An existing ownership lock with `USER_SELECT=0`
prevents acquisition. A pin locked with `USER_SELECT=1` cannot be released by
normal cleanup; stop its SM/output, report retained locked ownership and do
not claim that the pin is free. Incompatible configuration locks similarly
fail acquisition/release before an unsafe transition.
Do not reset all GPIO, reset the common DMA or disturb unrelated peripherals
to recover one PIO session. A forced GPIO reset invalidates PIO ownership,
disables the affected SMs/output enables and requires explicit configuration
and reacquisition before restart. Normal PIO/GPIO gate and peripheral-reset
operations must first complete pin release and the associated DMA endpoint
drain/isolation. On timeout, retain the safe state and report failure instead
of acknowledging a reset or transferring ownership prematurely.
### Required implementation evidence
PIO-lite implementation must verify all 32 routes and unchanged ALT0/ALT1,
QFN64 and dedicated boot/debug paths; input pipeline timing; disjoint output
and shared-input claims; two-way handoff; open drain; pre-existing locks;
filter-enabled rejection and filter change while active; same-cycle START and
ownership change; lost readiness/reset; residual DMA/stream traffic; timeout,
rollback, retained locked ownership and explicit rearm. Read-only status
outputs must match APB readback without changing GPIO V2.0 behavior. Verify
that handoff, disabled-but-armed sessions, claim rewrites and block reset
cannot hide selected pins from the RCU veto or restart a stale transport.
Check unrelated pins and affected Mini consumers throughout. The existing tests
below remain baseline evidence and do not establish these new PIO properties.
## Pad capabilities
Digital functionality is identical for every PDK, but pad electrical controls
+146
View File
@@ -0,0 +1,146 @@
# PIO-lite Verification and Evidence Ledger
The normative architecture is [piolite.md](piolite.md). This ledger targets
TINY/IHP130 and the separately approved `PIOLITE-P0..P5` roadmap. Freeze date:
2026-10-04. Only the documentation contract is delivered here; no test case,
model, assembler, RTL, firmware, performance or physical result below is
marked passed by this freeze. Existing Tiny/R2/DMA/GPIO evidence does not
automatically cover the new feature.
## Configuration and Evidence Identity
- Starting profile: `configs/ci/ihp130-tiny.mk`, TINY, IHP130, 24 MHz/no PLL,
current four-channel DMA and no PIO-lite.
- Planned integration: two SMs, shared 32x16 IMEM, per-SM TX/RX 8x32, PCLK
execution, APB `0x1001C000`, IRQ24, RCU15, DMA V2.1 requests 14/15.
- PCLK 48/60 testing requires the corresponding committed R2 platform inputs;
do not invent an executable profile or substitute Mini for Tiny.
- Every evidence record MUST identify source SHA, dependency/configuration
digests, profile/PDK, variant, tool versions, source programs and assembled
code, clock rates, pin assignment/electrical model, DMA bindings, commands,
logs, structured verdict and observed gaps. Artifacts belong below the
repository's `build/<profile>-<date-time>-<config-hash>/` layout.
- Shared Mini regressions validate compatibility only: PIO ports and support
bits remain disabled there. Full-chip P5 and R2-P11 evidence can be shared
only for the same PIO-inclusive source/netlist/configuration.
## Requirement Matrix
All rows currently have status **required, not run**. Implementation updates
must add evidence references and exact scope without deleting unmet cases.
| ID | Requirements | Required evidence / owner phase |
| --- | --- | --- |
| PL-V01 | PL-01/03/06 | All legal opcode/operand/delay combinations and illegal encodings against the reference model; independent ISA/APB version rejection; P1/P2 |
| PL-V02 | PL-01/06 | Deterministic assembly, duplicate/unknown labels, relocation at 0/31, exhaustion/fragmentation/sharing, invalid entry/wrap and failed-load publication; P1 |
| PL-V03 | PL-01/03 | Two SMs commit on the same tick without fetch arbitration; DIV 1/65535, delay 0/15, synchronized START, tick phase and PAUSE/resume; P1/P2 |
| PL-V04 | PL-01/02 | X/Y0/1/65535, saturating decrement, count 0=32 only for IN/OUT, MOVE narrowing/validity, wrap false/taken branches and out-of-region fault; P1/P2 |
| PL-V05 | PL-02 | Left/right packing, 1/8/16/31/32 bits, zero-valued valid words, partial PUSH, exact thresholds, partial OSR underrun and no partial effects; P1/P2 |
| PL-V06 | PL-02/07 | FIFO0/1/7/8 occupancy, simultaneous push/pop, blocked/nonblocking transfer, pre-sample autopush backpressure, stable beats and stall accounting; P2 |
| PL-V07 | PL-06/07 | Every CSR reset/access/field, reserved/unaligned/partial-strobe/unimplemented-SM errors, bounded APB response, repeated-access suppression, SVH/C parity; P2 |
| PL-V08 | PL-03/07 | Same-edge command/commit, flag set/clear/W1C, first-fault precedence, saturating counters and paused execution snapshot while DMA moves; P2 |
| PL-V09 | PL-04/09 | All 32 GPIO paths; unchanged ALT rows/pads; input pipeline; output-overlap rejection, shared input, windows atGPIO31, WAIT/test pin authorization; P3 |
| PL-V10 | PL-04/07 | Native-owner drain, two-way high-Z handoff, locks, open-drain/capability rejection, partial claim rollback, lost ownership/filter/readiness, unexpected GPIO reset, explicit rearm; P3 |
| PL-V11 | PL-05/06 | DMA V2.0 rejection before unsupported offset access; V2.1 identity/parity/static masks/accurate stream count; staged wiring and Mini disabled ports; P3 |
| PL-V12 | PL-05/07 | Direct/TCD TX/RX, direction/channel checks, distinct full-duplex channels, non-PIO-to-PIO chain, suspension, accepted START/rebind/reset race; P3 |
| PL-V13 | PL-05/07 | Descriptor-fetch backpressure, abort at fetch/parse/activation, payload/B-response drain, no stale activation, invalid TX beat discard, full-TX and empty-RX abort; P3 |
| PL-V14 | PL-05/07 | Residual RX VALID after byte-count completion, isolated endpoint reset, failed drain timeout retains ownership, unaffected SM/channel progress and no global reset; P3 |
| PL-V15 | PL-03/07/09 | RCU clock/gate/reset from WAIT/PAUSED/HALTED, GPIO ownership veto including multi-target commands, source-rate rediscovery, no stale epoch after reset; P3 |
| PL-V16 | PL-06/08 | HAL argument/range/overflow/capacity checks, static allocation, readback failures, finite timeouts, locks/interrupt serialization, actual demo object footprints; P1/P3/P4 |
| PL-V17 | PL-02/05/08 | Independent digital/serial/lighting BFMs, nominal and adverse schedules, exact FIFO/DMA counts and final responses, all acceptance targets below; P4 |
| PL-V18 | PL-08/10 | Sustained load, longest DMA service gap, CPU progress, errors/recovery, full Tiny regression and affected Mini regression with source-bound logs; P4 |
| PL-V19 | PL-03/09/10 | Storage mapping, block/full synthesis, netlist simulation, CDC/RDC/reset, PVT timing, pad/board/package and physical evidence; P5 |
Directed boundary cases also cover OUT with empty OSR and autopull disabled,
an autopull width exceeding TX_BITS without TX dequeue, HALT at the last
instruction outside wrap, rejection of CLOSING-to-DISABLE/START, CPU FIFO
rejection during closing, and pre-edge full/empty simultaneous FIFO activity.
Also verify that clearing/replacing SM claims cannot hide USER_SELECT from
OWNED_MASK/RCU, acquisition handoff keeps the veto asserted, block reset needs
released GPIO ownership, disabled-but-armed/prefilled sessions fault on GPIO
reset, and a drained failed buffer can be reclaimed without publishing its
partial contents as a valid result.
Model differential testing must not be the only oracle. Independent assertions
check handshake stability, FIFO bounds, one-owner outputs, no stalled partial
commit, isolation epochs and canceled descriptor non-activation. Protocol BFMs
check waveforms rather than sharing the assembler/model's expected trace code.
Formal bounds and assumptions must be recorded, especially eventual bus
response assumptions; bounded proofs do not establish arbitrary external
liveness or analog CDC safety.
## Application Acceptance
All programs and every required dual-SM combination MUST fit 32 instructions
after assembly/relocation. Do not increase IMEM to pass a demo. Each scenario
lists native peripheral conflicts and obtains GPIO/DMA ownership explicitly.
No simultaneous execution of all three groups is required or implied.
| Scenario | Required observations |
| --- | --- |
| Eight-channel logic capture | Exactly 32768 samples in a 32 KiB user buffer at 1 MSPS; four samples/FIFO word, 8192 DMA words; compare deterministic/ramp/pseudorandom independent pin input, endpoints and guard canaries; any capture stall invalidates lossless success |
| Pulse generation plus capture | Both SMs active; varied duty/length, WAIT entry phases, 0/1/65535 counter boundaries, programmed stop and abort-mid-pulse; measured widths agree with documented pipeline/tick quantization |
| UART8N1 | TX/RX at 115200 baud with <=2% actual error; independent asynchronous phase sweeps, back-to-back bytes, framing errors, break/noise recovery and deliberate FIFO starvation; both programs fit 32 words |
| SPI master | Modes 0..3, 8/16/32-bit frames at 1 MHz; known/random duplex data, first/last edges, CS setup/hold and short frames; documented safe pause phase or rejected waveform on starvation; exact full-word DMA counts |
| IR |38 kHz carrier with <=2% frequency error, known mark/space patterns and demodulated pulse input; bound timing quantization, timeout/buffer overflow and rearm; variable RX uses CPU/IRQ, not early DMA success |
| LED scan | External row/column driver model for 8x8 monochrome matrix; >=200 frames/s, correct row order/data, blanking before FIFO wait and no unintended row during reset/abort; do not assume direct LED current from Pads |
| Gamepad | Eight-bit latch/clock/data shift-register model; fixed and changing button patterns, sampling delay, disconnect/timeout and repeated scans with bounded CPU service |
For each applicable scenario run PCLK 24 first, then 48/60 only when enabled.
Record actual integer divisors, instruction path lengths, valid bits per word,
memory word counts, throughput and longest stall. Initial arithmetic budgets
are in the main contract; they are not proof that complete programs already
fit or meet protocol timing. FIFO IRQ watermark choices and service deadlines
must be justified for each program, including CPU/IRQ IR reception.
## Validation Commands and Status
For P0 documentation only:
```sh
git diff --check
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY --dry-run
python3 scripts/regress.py --root . --suite nightly --soc TINY --dry-run
```
Also verify relative links/anchors and command options against their sources.
Dry-runs validate command definitions, not execution or PIO integration.
P1 uses Ruff and Pytest for the new model/assembler. P2 adds discovered tests
and the existing lint/style/formal/synthesis mechanisms; test names and build
entries are created in that implementation phase, not invented as working
commands here. P3/P4 use the main contract's SDK/firmware/regression commands
and focused DMA/GPIO/PIO tests. P5 follows the existing IHP130 physical-flow
procedure with the frozen full-source variant and required collateral.
For Tiny firmware, success requires command exit 0, the configured
`SIM_TEST_PASS`, and no `FAILED`, `FATAL`, `assertion failed`, `%Error`,
`SIM_TEST_FAIL` or `SIM_TEST_TIMEOUT`. SYSCTRL TEST_STATUS is the terminal
verdict; UART output is diagnostic. Run both Verilator and Icarus pin-level
checks; preserve simulator-specific unsupported coverage rather than replacing
one with the other. Neither a dry-run nor a skipped fixture is a passing test.
## Freeze Record and Remaining Gaps
| Phase | Status at this freeze |
| --- | --- |
| PIOLITE-P0 | Documentation freeze complete; local links/anchor, command dry-runs, unchanged legacy/R2 IDs and QFN64/ALT tables, documentation-only scope and whitespace checks passed on 2026-10-04 |
| PIOLITE-P1 | Not started: model, assembler and actual 32-word program evidence absent |
| PIOLITE-P2 | Not started: core, CSR/ISA parity and standalone RTL/formal/synthesis evidence absent |
| PIOLITE-P3 | Not started: R2-dependent Tiny wiring, DMA V2.1 and GPIO/RCU/HAL lifecycle absent |
| PIOLITE-P4 | Not started: complete SDK/application and dual-simulator/contention qualification absent |
| PIOLITE-P5 | Not started: PIO-inclusive IHP130 timing, physical, Pad/package and silicon evidence absent |
Executed P0 validation used `git diff --check`, local Markdown link/anchor and
new-file whitespace checks, and structural comparison with HEAD of all 25
legacy/R2 phase headings, the QFN64 package section and 32 ALT rows. The Tiny
PR and nightly dry-runs above passed using the local `python` executable;
`python scripts/regress.py --root . --suite pr --pdk IHP130 --soc MINI --dry-run`
also passed for the shared-IP compatibility command path. These are definition
checks only. No P1 model, firmware build, simulator, formal, synthesis, STA or
physical flow was run because this change is documentation-only.
No MISRA deviation, warning-baseline change, metrics promotion, new PDK support,
maximum Pad rate or security/safety claim is approved here. Record missing
tools, vendor models, PDK/macro/Pad timing views and hardware access in later
phase evidence. Freeze completion does not close any of those gaps.
+748
View File
@@ -0,0 +1,748 @@
# Tiny PIO-lite Programmable I/O
## Purpose and Research Boundary
This is the approved `piolite` design freeze dated 2026-10-04, targeting
**TINY only**. It specifies a future standard Tiny feature, not an implemented
peripheral or a qualified device. `PIOLITE-P0` is the documentation gate;
P1-P5 require separately authorized implementation and evidence. The term
PIO-lite means this programmable engine; ordinary programmed register I/O
elsewhere in the repository does not imply this engine is present.
Authoritative inputs are the [Tiny product contract](tiny-soc.md),
[GPIO](gpio.md), [central DMA](dma.md),
[family positioning](../soc-family-positioning.md),
[engineering workflow](../engineering.md), and
[owned RTL policy](../rtl-coding-style.md). Executable configuration wins for
claims about current hardware. The baseline topology still has four DMA
channels and no PIO-lite. This freeze changes documentation only: no RTL,
firmware, configuration, dependency, warning baseline or quality-policy change.
## Target SoCs and Integration Scope
| Item | Frozen boundary |
| --- | --- |
| Target | TINY, future standard QFN64 product feature |
| Starting profile / PDK | `configs/ci/ihp130-tiny.mk` / IHP130; existing 24 MHz, no-PLL baseline |
| Product integration | `rtl/tiny/top/retrosoc_tiny.sv`, `rtl/tiny/integration/soc_topology.json`, `rtl/tiny/address_map/memory_map.json`, `rtl/tiny/pin_map/pin_map.json`, `rtl/tiny/integration/clock_reset_domains.json` |
| Filelists | `rtl/tiny/filelist/ip.fl`, `inc.fl`, `top.fl`, `tb.fl` and their existing build flow |
| Software composition | Shared freestanding `crt/` HAL; Tiny generated capability/memory/IRQ headers; independent `bringup` acceptance scenarios in `app/` |
| APB4 window | `0x1001C000..0x1001CFFF`, 32-bit configuration and FIFO access |
| Interrupt / RCU target | Tiny CPU IRQ24 / Tiny RCU target 15; not a family-wide assignment |
| DMA | Requests 14/TX and 15/RX through central DMA V2.1; no new memory master |
| Pads | Existing GPIO0..31 through GPIO `USER_SELECT`; no new ALT encoding, Pad or package terminal |
| Clocks | PCLK 24 baseline, PCLK 48/60 targets after applicable R2 enablement and qualification |
| Deferred products | MINI, STD, PRO and any four-SM product configuration |
Mini requires compatibility testing of shared DMA/GPIO changes but does not
gain PIO-lite. Its IRQ24 assignment is unaffected. Tiny retains 128 KiB main
SRAM, CPU/main-SRAM same-frequency SYS, private Crypto storage, the planned
eight central DMA channels and three external AXI owners. The new 64 B
instruction and 128 B FIFO payload stores are additional local register
arrays, not reservations from user SRAM. No dependency revision changes.
The performance-only R2 approval and all `TINY-R2-P0..P11` IDs/titles remain
historical truth. This separately approved feature extends the future product;
it does not rewrite old R2 evidence to include PIO-lite. Full integration
requires the applicable R2-P6 shared-IP/eight-channel and R2-P7 clock/reset
contracts. Standalone model/core development may precede those dependencies.
## Commercial References
Research checked on 2026-10-04. These are architecture references, not copied
implementations, binary compatibility promises or Tiny performance evidence.
| Primary reference | Confirmed external behavior and reuse boundary |
| --- | --- |
| [RP2040 datasheet, chapter 3](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf), PDF build 2025-02-20 | Four SMs per block share 32 instructions; each has shift/scratch registers, normal 4-word TX and RX FIFOs, DMA pacing and IRQ flags. Reuse autonomous execution, independent fetch, clock enables and explicit stalls. Tiny instead has two SMs, 8-word FIFOs in each direction, integer division and its own ISA. |
| [Pico SDK PIO API](https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#hardware_pio) | Maintained software distinguishes divider restart, SM restart and FIFO clearing. Reuse explicit lifecycle and resource allocation; no Pico SDK or RP instruction compatibility. |
| [NXP AN12174](https://www.nxp.com/docs/en/application-note/AN12174.pdf), Rev 0 June 2018 | S32K1xx FlexIO combines four shifters, four timers and eight pins with polling, IRQ and DMA. Resource discovery is useful; fixed shifter/timer configuration is less suitable than microcode for arbitrary short sampling/pulse/scan programs. |
| [NXP AN13358](https://www.nxp.com/docs/en/application-note/AN13358.pdf), Rev 0 August 2021 | SPI reload/frame-boundary interactions motivate explicit first/last-bit, short-frame and starvation tests, not merely successful bulk data movement. |
The RP2040 and [S32K1](https://www.nxp.com/products/S32K1) vendor product and
documentation families remain supported references at the research date.
The public NXP application notes are older than the current product manuals;
login-gated current timing manuals were not used as verified evidence.
No reference supplies Tiny area, power, metastability MTBF, maximum Pad rate,
IHP130 timing closure or production qualification. RP2350's larger resources
are not required for this MVP. Vendor synchronizer bypass and fractional
division are deliberately not imported.
## Requirements and Non-goals
| ID | Normative requirement |
| --- | --- |
| PL-01 | MUST implement two independent SMs, one shared 32x16 instruction store with independent reads, and per-SM 32-bit ISR/OSR plus 16-bit X/Y. |
| PL-02 | MUST provide per-SM TX and RX 8x32 FIFOs, exact bit packing and atomic stall semantics; MUST NOT silently overwrite or invent data. |
| PL-03 | MUST execute in PCLK using integer enables, deterministic commit/delay rules and masked phase-aligned START. |
| PL-04 | MUST route only claimed existing GPIO, forbid overlapping SM output authorization, verify ownership/filter/readiness and fail to high impedance. |
| PL-05 | MUST use the shared central DMA pair 14/15 with whole-job channel ownership, stable stream beats and bounded abort/recovery. |
| PL-06 | MUST expose versioned APB/ISA discovery, truthful capabilities, a handwritten RTL/C register mirror, deterministic assembler and freestanding HAL. |
| PL-07 | MUST distinguish execution stop from transport completion, preserve unrelated channels/SMs, and require explicit clean restart after fault/reset/clock change. |
| PL-08 | MUST qualify all three application groups, including combined-program capacity, independent pin-level protocol checks and contention budgets. |
| PL-09 | MUST preserve QFN64/Pad count, ALT definitions, R2 CPU/SRAM clocks, memory capacities, DMA count and AXI-owner count. |
| PL-10 | MUST bind validation to SoC, profile, PDK, source revision and variant; targets are not measured capabilities. |
MUST NOT add RP binary compatibility, eFPGA fabric, general memory access, an
independent AXI master, dedicated general SPI, recovery Boot ROM, caches,
fractional SM division, external SM clocks, raw asynchronous input bypass,
side-set, instruction injection, computed PC, FIFO joining or a general ALU.
Four-SM enablement, deeper instruction storage, variable-length DMA framing,
other PDKs/products and simultaneous execution of all demo groups are DEFERRED.
No unresolved architecture choice blocks P1; physical limits remain evidence
gates and MUST NOT be resolved by relaxing correctness or claiming completion.
## Selected Architecture
### Module hierarchy and storage
The intended owned hierarchy is `apb4_piolite` around `piolite_reg`,
`piolite_core`, two instances of `piolite_sm`, shared `piolite_imem`, and
`piolite_dma_adapter`/`piolite_gpio_guard`. `piolite_if` carries internal
control/status and `piolite_define.svh` the handwritten ABI constants.
Implementation follows the owned naming, Common register and FIFO policy;
these names describe planned files, not existing sources.
Two independent combinational instruction reads MUST deliver one instruction
to each eligible SM tick without arbitration jitter. The 32-word store has
per-word validity: invalid locations read as zero over APB but fault on fetch.
Validity, not reset of every payload bit, excludes stale code after reset.
FIFO empty state similarly hides old payload. Inferred/register storage is an
explicit small-memory exception; synthesis must verify its size and mapping.
Parameterizing storage or instance arrays does not authorize advertising a
four-SM product. APB reserves four slots; Tiny V1 implements slots 0 and 1 only.
### Tick, commit and control precedence
Each SM uses `DIV=N`, 1..65535. START clears the divider phase; the first
instruction executes after N PCLK rising edges following the START edge.
Initial output data/OE apply on START itself, after all ownership checks.
A successful instruction commits atomically on its tick, then consumes D
additional ticks of delay. The next instruction is eligible on the following
tick. Failed WAIT or blocking FIFO operations retain PC, shifts, counters,
pins and delay state; delay begins only after successful commit.
Reset, fault/ABORT, accepted PAUSE/DISABLE, and instruction execution have
descending precedence. Mask commands validate every selected SM first and
are all-or-nothing. PAUSE takes effect on the APB control acceptance edge,
independent of N or a stalled WAIT, and wins over that edge's instruction.
Accepted DMA START uses the registered route and wins over a competing route
write, which returns APB error. Hardware events/set operations win W1C/clear.
Flags and input conditions are observed from pre-edge state; two SMs cannot
communicate through a same-edge combinational flag path.
### Instruction set, ISA1.0
All instructions are `opcode[15:12], delay[11:8], operand[7:0]`. Unlisted
operands/reserved bits are illegal before any instruction side effect.
IN/OUT count field 0 encodes 32, otherwise 1..31. This encoding does not apply
to X/Y: counter zero always means zero, never 65536.
| Opcode | Instruction | Operand encoding |
| --- | --- | --- |
| `0` | CTRL | `[7:5]`: NOP=0, HALT=1, CLEAR_ISR=2, CLEAR_OSR=3; `[4:0]=0`; HALT requires delay 0 |
| `1` | SET_PIN | Unsigned 8-bit immediate applied to SET window |
| `2` | SET_DIR | Unsigned 8-bit OE immediate applied to SET window |
| `3` | SET_COUNT | `[7]`: X=0/Y=1; `[6:0]` unsigned immediate |
| `4` | IN | `[7:5]`: pins=0/X=1/Y=2/zero=3; `[4:0]` bit count |
| `5` | OUT | `[7:5]`: pins=0/directions=1/X=2/Y=3/discard=4; `[4:0]` bit count; counter destination count <=16 |
| `6` | MOVE | `[7:6]`: ISR=0/OSR=1/X=2/Y=3; `[5:3]`: ISR=0/OSR=1/X=2/Y=3/zero=4/ones=5; `[2:0]=0` |
| `7` | FIFO | `[7]`: PULL=0/PUSH=1; `[6]`: nonblocking=0/blocking=1; `[5:0]=0` |
| `8` | WAIT | `[7]`: pin 0/flag 1; `[6]` required level; `[5:1]` index; `[0]=0`; flag index 0..3 |
| `9` | BRANCH | `[7:5]`: always 0/X-zero 1/Y-zero 2/dec-X-nonzero3/dec-Y-nonzero4/test-pin-high 5/last-FIFO-failed6/test-flag-set 7; `[4:0]` absolute relocated target |
| `A` | FLAG | `[7]`: clear 0/set 1; `[6:5]` flag 0..3; `[4:0]=0` |
| `B..F` | Reserved | Illegal-instruction fault |
X/Y reads zero-extend and MOVE writes retain low 16 bits. Decrement branches
decrement only a nonzero counter, then branch only if the result is nonzero.
MOVE ISR/OSR creates 32 valid bits; CLEAR sets the respective value/count to 0.
WAIT on a flag does not clear it. A test-pin branch requires TEST_PIN_ENABLE
and a claimed pin; flag tests use TEST_SELECT. Runtime WAIT outside CLAIM_MASK
faults. SET ignores immediate bits above the SET width. IN/OUT to pins requires
count <= configured window width; other pins retain their value/direction.
Explicit PULL replaces OSR with the next TX word and TX_BITS valid bits.
Explicit PUSH requires a nonzero ISR valid count, emits the normalized word,
and clears ISR/value count on success. Nonblocking failure advances PC without
data changes, sets last-FIFO-failed and FIFO_FAIL; successful FIFO transfer
clears last-FIFO-failed. Blocking stall does not count as nonblocking failure.
The last-FIFO-failed state clears on START/reset and is also updated by a
successful automatic FIFO transfer. HALT is terminal until DISABLE/START;
it retains output levels and does not promise external protocol success.
Each SM has BASE, LEN1..32, ENTRY, WRAP_BOTTOM and WRAP_TOP. Their addresses
are absolute instruction indices 0..31; BASE+LEN must be <=32 and all entry/wrap
positions inside the program region, with bottom <= top. Taken branch wins
over wrap; otherwise executing WRAP_TOP selects WRAP_BOTTOM, else PC+1.
An out-of-region target/fallthrough faults, never truncates. Prologue/cleanup
may be outside the wrap interval. A finite loop must place HALT after its
conditional branch without accidentally wrapping on the false branch.
HALT is exempt from successor/wrap validation: it retains its own PC, enters
HALTED and does not calculate PC+1. Thus a final HALT outside the wrap interval
does not fault merely because its hypothetical successor is outside the region.
### Shifts and FIFO word validity
TX_BITS/RX_BITS are 1..32. PULL uses the low TX_BITS bits of a FIFO word and
zeros unused high bits. Right OUT consumes the least-significant requested
bits first; left OUT consumes the highest bits within the remaining valid
range, then keeps the lower remainder. The selected chunk is low-aligned at
its destination. Autopull occurs only when OSR is empty and an OUT needs data;
a nonempty OSR with too few valid bits faults rather than joining words.
OUT with an empty OSR and AUTOPULL=0 also faults for shift bounds. With
AUTOPULL=1, validate n<=TX_BITS before touching TX FIFO: an impossible width
faults without dequeuing, while a legal-width empty FIFO stalls. A successful
automatic PULL and OUT commit together with no partially consumed TX word.
IN selects the low n source bits (GPIO window bit 0 is its lowest GPIO).
Right shift inserts those n bits at the top of ISR; PUSH shifts the k valid
bits down by 32-k. Left shift appends n bits at the bottom and needs no such
normalization. Both zero unused high bits on PUSH. Four right-packed samples
produce `s0 | s1<<8 | s2<<16 | s3<<24`; a two-byte tail occupies low 16 bits.
An IN exceeding RX_BITS with autopush, or 32 without it, faults before sampling.
Autopush occurs exactly at RX_BITS and is atomic with IN: full RX FIFO stalls
the instruction before its sample, with no duplicate/partial sample. Manual
partial PUSH is allowed. SHIFT counts describe validity, not nonzero content.
FIFO overflow/underflow never overwrites data or fabricates zero words. A
stall is observable even if the external protocol cannot tolerate it. FIFO
budget uses emitted words: RX headroom is free_words/word_rate; TX reserve is
queued_words/word_rate, with a separately justified ISR/OSR reserve. Service
latency includes arbitration, descriptor reads, other DMA clients and memory
responses, not only average bandwidth.
All FIFO eligibility uses pre-edge occupancy, with no empty fall-through or
full look-ahead. At full, an attempted enqueue stalls/errors even if a dequeue
occurs on that edge; at empty, a dequeue stalls/errors even if a producer
arrives. At intermediate occupancy an eligible simultaneous enqueue/dequeue
preserves level and dequeues the old head. An SM transfer, CPU access and DMA
handshake therefore have the same model/RTL cycle boundary.
## Interfaces
### APB4 and memory data path
APB is 32-bit address/data, little endian, aligned words only. Accepted writes
require `PSTRB=0xF`; partial/unaligned/unmapped, reserved-bit, illegal-state and
wrong-direction accesses complete with PSLVERR and no requested side effect.
Reads use ordinary APB read strobes. WO reads and RO writes error; all reserved
read bits are zero. One transfer completes once; no repeated FIFO side effect
while APB remains asserted. Responses MUST be bounded independently of an SM
or FIFO condition, using the repository registered APB response convention.
Full TX write/empty RX read returns error immediately, never waits for space.
PIO-lite has no AXI memory port. The central DMA is the only PIO payload
memory owner, using Tiny AXI32's existing ordering, bursts (at most 16 beats),
4 KiB boundaries and errors. CPU accesses cross the existing SYS/PCLK bridge.
DMA buffers/descriptors stay owned until all accepted memory responses drain;
no cache, coherence or new executable-memory policy is implied.
### GPIO acquisition and guard
IN/OUT windows have base 0..31 and width 0..32; SET width 0..8. Width 0 disables a
window; base+width must not exceed 32. Every enabled window and WAIT/test pin
must belong to CLAIM_MASK. OUT/SET windows and initial OE must be subsets of
OUTPUT_MASK, itself a subset of CLAIM_MASK. Both SM OUTPUT_MASK values MUST be
disjoint, even when their current OE is zero. Input-only claims may overlap;
one SM may observe another's authorized output. Release requires software
reference-counting overlapping claims.
Use the existing GPIO `user_gpio_if` data/OE and synchronized input route.
GPIO must export read-only USER_SELECT, USER_STATUS and FILTER_ENABLE plus RCU lifecycle
readiness. START requires all claims owned, filters disabled, GPIO ready and
legal masks. CPU FIFO access and enabling a DMA binding also require these
guards; preload is performed after acquisition, not before claiming pins.
An SM session is live while RUNNING/PAUSED/HALTED or while an enabled binding,
bound DMA job, held beat or prefilled FIFO exists, including
DISABLED execution with DMA armed. Loss of any guard condition closes and
faults that session; stale prefill cannot survive into a new claim. Merely
writing a DISABLED, empty, unbound configuration before acquisition does not
create a fault. Physical OE is continuously qualified by ownership/readiness, so
the fault path cannot leave an unauthorized driven level for a software cycle.
The existing GPIO handoff high-impedance interval remains authoritative.
The input path contains the GPIO synchronizer and registered filter/bypass
stage. FILTER_ENABLE=0 removes debounce, not these registers; there is no
new PIO synchronizer or raw bypass. Account for the whole pipeline and SM tick
quantization in protocol timing. Independent asynchronous bus bits are not a
coherent source-synchronous bus without board/setup/hold constraints.
HAL acquisition MUST check CONFIG_LOCK/USER_LOCK, native and board ownership,
electrical capabilities and output contention; quiesce native outputs, input
consumers and interrupts; prepare native OE0/ALT-disabled fallback; disable
filters; select USER ownership and verify USER_STATUS after handoff before
START. Existing unchecked GPIO helpers alone are not sufficient. Dynamic
sessions do not set USER_LOCK. No speculative probing of absent product MMIO.
Release stops execution/drains transport, releases PIO OE, prepares/verifies
the native high-impedance fallback, clears USER_SELECT and verifies readback
before dropping the software claim. Do not restore a latent ALT driver.
USER_LOCK failure retains high-impedance ownership and returns error; no
automatic global GPIO reset. Unexpected GPIO reset invalidates the session,
requiring explicit reacquisition. RCU rejects GPIO gating/reset while any PIO
claim remains owned, including commands naming GPIO and PIO together; an
explicit coordinated system reset is a separate whole-system operation.
GPIO IRQ/filter/electrical changes on owned pins require session coordination.
This is trusted bare-metal ownership, not a security firewall. Dedicated boot
XPI/JTAG pads remain outside the routable mask. External drivers must be
quiesced or isolated; firmware routing cannot remove board-level contention.
Tiny's sole USER data/OE source is PIO-lite. OWNED_MASK and the RCU GPIO veto
therefore follow GPIO USER_SELECT, including an acquisition handoff, not the
mutable SM CLAIM_MASK union. START still requires active USER_STATUS. Clearing
or replacing a stopped SM claim cannot hide a still-selected USER pad; the
HAL retains its reservation until checked GPIO release completes. RCU rechecks
the ownership/readiness handshake at gate/reset commit, not only command issue.
## DMA and Interrupt Contract
### Shared pair and admission
PIO TX uses `PIOLITE_TX=14`, MM_TO_STREAM; RX uses `PIOLITE_RX=15`,
STREAM_TO_MM. Only
32-bit widths and positive lengths divisible by 4 are valid. One TX SM and
one RX SM can use DMA at once; they may be the same SM. Each enabled binding
names a distinct exclusive channel; the opposite FIFO direction may still
use CPU access. CPU cannot access the DMA-owned FIFO port, including during
pause or recovery. Default software assignment is TX channel 3 and RX channel 2
only after releasing bulk/DVP users. Other free channels need explicit
application ownership; Crypto/audio reservations are not silently stolen.
The authoritative shared extension is [DMA V2.1](dma.md):
`IP_VERSION=0x00020001`, `SUPPORTED_REQUESTS` at 0x028, requests 14/15 added
without widening the selector or modifying the 64 B TCD. REQUEST_STATUS is
live readiness, not presence. The capability stream count reflects actual
wired supported directions (at most 7 with I2S, DVP, Crypto and PIO), not a
constant for all products. Mini's PIO support/grants default off.
TX_BIND/RX_BIND select SM, channel and enable. Old/new affected SMs must be
DISABLED, old/new channel jobs fully drained and the endpoint free of held
beats before a change. Bindings supply one-hot channel admission grants to
both DMA direct START and TCD activation. An accepted START locks the current
registered binding. A job reservation spans the complete chain, including
non-PIO descriptors and suspended intervals; unrelated clients MUST NOT share
that chain. No global-DMA-idle condition is imposed.
Complete drain includes accepted descriptor reads and pending parse/activation,
not just payload R/W ownership or current TVALID. Cancel/error suppresses new
descriptor fetch/activation, drains accepted descriptor reads, discards their
results and clears canceled pending work before releasing the channel. Fixing
the baseline DMA abort gap is part of P3, not assumed existing behavior.
### Stream and completion semantics
Both endpoints use 32-bit AXI4-Stream in PCLK with TKEEP/TSTRB=0xF, one-bit
ID/DEST/USER=0. RX TLAST=0; TX TLAST is ignored because byte count controls DMA
completion. Invalid TX strobes/keep or nonzero identity/user fields fault the
SM and enter discard recovery; an already asserted invalid beat is accepted
and discarded so it cannot deadlock abort. RX data/VALID remain stable until
handshake or the explicit isolated endpoint-reset boundary.
PIO DMA length is four times the number of emitted FIFO words. UART byte-per-
word programs and four-byte-packed logic programs therefore differ. Program
metadata determines tail validity; DMA never infers it from zero high bits or
TLAST. No partial-keep tail or fabricated padding beats are supported.
Finite success requires program HALT, exact TX/RX word counts, DMA success
including final memory responses, expected FIFO/shift tail state, and no
disqualifying program/transport error. HALT, DMA idle, aborted DMA or cleared
interrupt alone is not success. Extra residual RX data is a length mismatch,
not permission to rebind. Variable-length infrared receive uses CPU/IRQ FIFO
service in V1 instead of aborting a maximum-length DMA and calling it success.
### Interrupts
Tiny IRQ24 is the level OR of enabled global sources. IRQ_STATUS bits 0..3
are each SM's enabled sticky events (unimplemented bits zero), bits 8..11 are
shared flags, bits 16..19 are TX occupancy <= TX_LOW, and bits 24..27 are RX
occupancy >= RX_HIGH. FIFO watermarks are level conditions independent of
execution state; service/disable their enables to deassert them. IRQ_ENABLE
uses the same mask. Flags are cleared explicitly, never by WAIT.
Per-SM EVENTS bits 0..5 are HALT, ABORT, FAULT, TX_STALL, RX_STALL and FIFO_FAIL.
EVENT_ENABLE selects their contribution. Hardware set wins concurrent W1C;
global flag SET wins all clears, including another SM or CPU. APB access
errors are reported to the bus without silently faulting an unrelated SM.
## Register and Software ABI
### APB1.0 map
Offsets are relative to the Tiny window. All registers are 32 bits. Reset
values are zero unless stated otherwise. Configuration writes require the
affected SM DISABLED and associated transport quiescent; live IRQ enable/W1C,
FIFO ports and lifecycle commands have the explicit exceptions below.
| Offset | Register | Access / fields |
| --- | --- | --- |
| `000` | IP_ID | RO `0x50494F4C` (PIOL) |
| `004` | IP_VERSION | RO `0x00010000`, APB1.0 |
| `008` | ISA_VERSION | RO `0x00010000`, independent ISA1.0 |
| `00C` | CAPABILITY | RO `[7:0]` SM count 2, `[15:8]` instruction words 32, `[23:16]` TX depth 8, `[31:24]` RX depth 8 |
| `010` | ROUTABLE_MASK | RO `0xFFFFFFFF` on fully integrated Tiny |
| `014` | CLOCK_HZ | RO actual current PCLK Hz, not SYS Hz |
| `018` | FLAGS | RO shared flags `[3:0]` |
| `01C`, `020` | FLAG_SET, FLAG_CLEAR | WO masks `[3:0]` |
| `024`, `028` | IRQ_STATUS, IRQ_ENABLE | RO aggregate / RW global enables |
| `02C`, `030` | TX_BIND, RX_BIND | RW `[1:0]` SM, `[10:8]` DMA channel, `[31]` enable; disabled reset 0 |
| `034` | TRANSPORT_STATUS | RO bits 0/1 TX/RX channel job owned, 2/3 TX/RX held beat, 4/5 TX/RX closing |
| `038` | IMEM_VALID | RO bitmap of 32 valid instruction slots |
| `03C` | OWNED_MASK | RO GPIO USER_SELECT on Tiny, independent of SM claims; includes handoff, reset follows GPIO |
| `040` | START | WO SM mask `[3:0]`, from DISABLED only; validate all selected SMs atomically |
| `044`, `048` | PAUSE, RESUME | WO SM masks, RUNNING to PAUSED / PAUSED to RUNNING |
| `04C`, `050` | DISABLE, ABORT | WO SM masks; lifecycle rules below |
| `054` | SM_RESET | WO SM mask; coordinated local endpoint reset after bound jobs drain |
| `058` | BLOCK_RESET | WO bit 0; all SMs DISABLED, bindings disabled, endpoints quiescent and OWNED_MASK=0 |
| `100..17C` | IMEM[0..31] | RW low 16 instruction, high 16 zero; validity set on write |
| `200..27C`, `280..2FC` | SM0, SM1 | Implemented per-SM slots below |
| `300..3FC` | SM2, SM3 | Reserved future slots; accesses error in Tiny V1 |
Offsets not listed error. Mask bits naming unimplemented SMs error even in
lifecycle/IRQ writes; commands with mask 0 are no-ops. IMEM writes require
all SMs DISABLED, both bindings disabled and no held/accepted transport.
BLOCK_RESET clears the block-local state on its accepted edge; its APB
response still completes. It is not an uncontrolled asynchronous reset.
CPU FIFO accesses are permitted in DISABLED/RUNNING/PAUSED/HALTED only when
that port is not DMA-owned and has the required space/data. CLOSING rejects
both CPU FIFO ports; diagnostics and recovery commands remain accessible.
### Per-SM map
The stride is 0x80. All reserved field bits are zero on read and must be zero
on write. Scalar range checks occur on writes; cross-register program/pin
consistency is checked again before START. Reset may be an unconfigured state.
| Offset | Register | Access / fields and nonzero reset |
| --- | --- | --- |
| `00` | STATUS | RO state `[2:0]`: DISABLED=0/RUNNING=1/PAUSED=2/HALTED=3/CLOSING=4; stall `[6:4]`: none=0/pin=1/flag=2/TX=3/RX=4; `[8]` last-FIFO-failed |
| `04` | CONFIG | RW bits 0 AUTOPULL, 1 AUTOPUSH, 2 TX_RIGHT, 3 RX_RIGHT, 4 TEST_PIN_ENABLE |
| `08` | DIV | RW `[15:0]` 1..65535; reset 1 |
| `0C` | PROGRAM | RW BASE `[4:0]`, LEN `[13:8]` 1..32, ENTRY `[20:16]` |
| `10` | WRAP | RW BOTTOM `[4:0]`, TOP `[12:8]` |
| `14`, `18`, `1C` | IN_PINS, OUT_PINS, SET_PINS | RW base `[4:0]`, width `[13:8]`; width 0 disables |
| `20`, `24` | CLAIM_MASK, OUTPUT_MASK | RW 32-bit pin masks |
| `28`, `2C` | INITIAL_VALUE, INITIAL_OE | RW 32-bit GPIO-aligned START values; non-output bits must be zero |
| `30` | INITIAL_XY | RW initial X `[15:0]`, Y `[31:16]` |
| `34` | SHIFT_LIMITS | RW TX_BITS `[5:0]`, RX_BITS `[13:8]`, both 1..32; reset `0x00002020` |
| `38` | TEST_SELECT | RW test GPIO `[4:0]`, test flag `[9:8]`; GPIO checked only when enabled/used |
| `3C` | WATERMARKS | RW TX_LOW `[3:0]` 0..8, RX_HIGH `[11:8]` 1..8; reset `0x00000100` |
| `40`, `44` | TXDATA, RXDATA | WO CPU push / RO CPU pop; errors for unavailable or DMA-owned port |
| `48` | FIFO_LEVELS | RO TX `[3:0]`, RX `[11:8]`, range 0..8 |
| `4C`, `50` | EVENTS, EVENT_ENABLE | W1C sticky / RW bits 0..5 |
| `54` | FAULT | RO first code `[7:0]`, PC `[12:8]`; cleared by SM/block reset |
| `58` | PC | RO current instruction index `[4:0]` |
| `5C`, `60`, `64` | ISR, OSR, XY | RO live shifts; X low 16/Y high 16 |
| `68` | SHIFT_COUNTS | RO ISR `[5:0]`, OSR `[13:8]` valid bits |
| `6C` | TICK_COUNT | RO saturating 32-bit count of unpaused execution ticks, including stalls/delays |
| `70`, `74` | TX_STALL_COUNT, RX_STALL_COUNT | RO saturating 32-bit count of execution ticks stalled for that FIFO |
| `78` | RETIRED_COUNT | RO saturating 32-bit successful instruction commits |
| `7C` | EXEC_PHASE | RO divider edges remaining `[15:0]`, delay ticks remaining `[19:16]` |
START resets runtime PC/divider/shifts/counts/counters/last-FIFO-failed, loads
INITIAL_XY/data/OE, and preserves prefilled TX FIFO and sticky event history.
RX FIFO must be empty. A held/accepted TX beat may continue filling the FIFO
under its already valid binding; an RX job may be armed waiting for samples.
START therefore checks valid route ownership, not global DMA idle. It does
not bypass IMEM/configuration/route-write quiescence. Stale fault requires
SM_RESET before reuse. HAL clears prior event history deliberately.
### Software contract and program format
Handwrite the future `piolite_define.svh` and
`crt/include/retrosoc/hal/piolite_regs.h` mirror, with a parity test covering
offsets, masks, resets, opcodes and enumerations. No register generator.
APB and ISA versions evolve separately; incompatible versions return
RS_ENOTSUP before loading code. Product-generated presence, RCU target
capability and PIO discovery agree. Do not invent an ARCHINFO bit; absent
product metadata must prevent probing an unmapped PIO window. PIO DMA requires
DMA major2/minor>=1 with the requested direction's support bit; full Tiny MVP
integration must expose both bits. A future unknown major is not implicitly
compatible. Do not read offset 0x028 on older V2.0 hardware.
The assembler input extension is `.piolite`. It supports labels, the exact
instructions above, optional delay 0..15, and directives `.program`, `.entry`,
`.wrap_bottom`, `.wrap_top`, `.in`, `.out`, `.set`, `.tx_bits`, `.rx_bits`,
`.test`, `.packing` and `.clock_ticks` for required metadata. Numeric values
are unsigned decimal or
hexadecimal; no implicit truncation, macros, include downloading or executable
expressions. Program/label identifiers use ASCII letters/digits/underscore,
starting with a letter/underscore. Comments begin `;`. Reject duplicate/unknown
labels, illegal operands, unresolved timing/resource metadata and >32 words.
Timing metadata states normal-path ticks and whether WAIT/FIFO can stretch it;
it never certifies an arbitrary program's external protocol.
Directive syntax is `.program NAME`; `.entry LABEL`, `.wrap_bottom LABEL`,
`.wrap_top LABEL`; `.in BASE, WIDTH`, `.out BASE, WIDTH`, `.set BASE, WIDTH`;
`.tx_bits N, left|right, manual|auto` and the equivalent `.rx_bits` form;
`.test PIN|none, FLAG`; `.packing TX_ITEMS, RX_ITEMS, ITEM_BITS` (zero items
means application-defined framed words); `.clock_ticks N, fixed|stretchable`
for the declared steady-state item period. Emit the flags/pins actually
referenced by instructions as resource metadata. Disabled windows use width 0;
RX_BITS/TX_BITS still use 1..32. Metadata requiring run-time count/tail framing
is explicitly application-owned, never inferred from zeros or TLAST.
One statement per line uses an optional `label:` and an opcode mnemonic from
the ISA table, with comma-separated symbolic/numeric operands in table order,
then optional `[delay]`. Names are case-sensitive; instruction/operand symbols
are uppercase. BRANCH uses a label, never an unchecked literal absolute PC.
CTRL uses NOP/HALT/CLEAR_ISR/CLEAR_OSR; FIFO uses PULL/PUSH and BLOCKING/
NONBLOCKING; branch symbols are ALWAYS, X_ZERO, Y_ZERO, DEC_X_NONZERO,
DEC_Y_NONZERO, TEST_PIN_HIGH, FIFO_FAILED, TEST_FLAG_SET. WAIT operands are
PIN|FLAG, level, index; FLAG operands are SET|CLEAR, index. P1 implements this
syntax without silently inventing extra instructions or changing their meaning.
Emit deterministic C program objects with ISA version, 16-bit words, length,
entry/wrap offsets, absolute-branch relocation sites, pin/flag/packing metadata
and timing requirements. The same input/options produce byte-identical output,
without timestamps or host paths. Generated arrays belong in
`build/<variant>/generated/piolite/`; handwritten programs remain application
source. No new downloadable assembler dependency is authorized.
Loader allocation uses a shared 32-bit slot bitmap. Patch only branch target
bits, validate base+offset<=31, and validate every relocated instruction before
publishing it. Both SMs can reference the same identical relocated image;
distinct loaded images together consume at most 32 slots. Hold a global HAL
loader/session lock across load/readback/publication; concurrent START, route,
FIFO, reset and program mutations are rejected/serialized, not interleaved.
An interrupted/failed load is not executable until fully validated and
published; software invalidates its allocation and does not start it. START
additionally requires all instruction-valid bits in the configured region.
Branch target bounds are checked even when the branch condition is false,
before counter or other instruction effects.
The public `piolite.h` API groups are discover/configure, program_load/unload,
claim/release, dma_bind/unbind, write/read, start/pause/resume/disable,
wait_done, abort_reset and get_status. All fallible `rs_piolite_*` operations
return `rs_status_t`; lengths/counts use uint32_t, masks uint32_t, instructions
uint16_t and timeouts rs_timeout_t. Static caller-owned program/session/buffer
storage is required. No heap, hosted library or OS dependency. Initialization
must validate 16-bit counters before narrowing, word_count*4 overflow, address
alignment/range/capacity and actual available channel/pin resources.
Use existing RS_EINVAL for invalid arguments, RS_ENOSPC for resources,
RS_ENOTSUP for absent/unsupported capabilities, RS_EFORMAT for bad code,
RS_ETIMEOUT for bounded wait expiry and RS_EIO for hardware/ownership/lock
failures. Status diagnostics distinguish busy/locked/closing even though no
new global status enumeration is added. Publishing a valid DMA result requires
ownership drain and successful program/length checks. After a failed session
has completely drained and isolated, software may reclaim/reuse its memory,
but the partial contents are not a valid capture or successful result.
## Clock, Reset, CDC/RDC, and Lifecycle
The core, APB registers, instruction store, FIFOs and stream adapters all run
in PCLK. SM division is an enable, not a generated-clock constraint. GPIO
already owns input synchronization; CPU APB and DMA memory domain crossings
remain the existing Tiny bridges. No additional CDC is hidden in a PIO route.
PIO consumes the actual RCU PCLK rate; CPU/main SRAM SYS and XPI MEM are not
substitutes. PCLK 24 is the starting environment;48/60 require R2 qualification.
| Operation/state | Required behavior |
| --- | --- |
| PAUSE | Bounded PCLK control action; retain PC, delay, divider phase, pins and FIFOs; DMA may continue |
| RESUME | PAUSED only; continue retained phase without fresh START initialization |
| HALTED | Terminal program state, pins retained and FIFO/DMA tail service permitted |
| DISABLE | From DISABLED/RUNNING/PAUSED/HALTED only; reject CLOSING or an active associated DMA job; stop execution/release OE and retain FIFO/held stream state, never imply successful transfer |
| ABORT/FAULT | Stop instruction side effects and release OE immediately; latch CLOSING and block new admissions/config/rebinding |
| SM_RESET | From DISABLED/CLOSING only, once its jobs drain; isolate its bound endpoints, cancel an unaccepted held RX beat, flush local FIFOs/runtime/events/fault/counters, disable its bindings and return DISABLED |
| BLOCK_RESET | Clear all configuration, bindings, masks, flags, IMEM validity, runtime and FIFOs; safe OE0 |
SM_RESET preserves its configuration/CLAIM_MASK, shared IMEM/flags and the
other SM's state; it never silently releases GPIO USER ownership. Its retained
configuration is revalidated before reuse. BLOCK_RESET does not reset GPIO;
safe native fallback and explicit GPIO reacquisition are still required.
CLOSING cannot be escaped through DISABLE/START, event clearing or a restored
GPIO guard; only successful SM_RESET recovery can make the affected SM reusable.
Initial reset has all SMs DISABLED, OE0, FIFOs empty, IMEM invalid, IRQ masks 0
and bindings disabled. Physical reset release follows Tiny's existing staged
synchronous release policy. No stale instruction/FIFO payload is observable.
ABORT/FAULT closes both affected bindings, enables TX discard to accept held
DMA beats, and preserves an already asserted RX beat. Abort the owning DMA
jobs, drain payload and descriptor transactions, then isolate/reset those
endpoints. RX abort must complete even when its FIFO is empty or VALID remains
asserted; never generate filler to meet the requested length. Ordinary FIFO
flush/route change cannot withdraw VALID. A timeout leaves the session closed,
owned and non-reusable until explicit successful recovery. Unrelated DMA jobs
and the other SM continue; no global DMA reset is an error-recovery shortcut.
PCLK rate change requires all SMs DISABLED, all PIO jobs drained, no held
beats and clean endpoint isolation. PAUSED/HALTED/WAIT is insufficient. Rate
changes retain stored programs/configuration but invalidate cached timing;
read CLOCK_HZ, recalculate DIV and explicitly START. RCU target 15 publishes
capability only after its idle/reset path is wired. PIO target gate/reset and
BLOCK_RESET additionally require releasing GPIO ownership first, so a stopped
clock or cleared claim register cannot conceal a still-selected USER driver.
This block-level requirement does not apply to recovery SM_RESET, which retains
the session's claim/configuration and reports its safe high-impedance state.
GPIO target 1 cannot be
gated/reset while OWNED_MASK is nonzero, even if PIO is stopped; release first.
Unexpected unilateral reset invalidates sessions, clamps OE and prohibits
automatic resume. A whole-system reset discards the complete traffic epoch;
peripheral-local reset must not strand accepted memory transactions.
CPU-only WFI gating, debug halt or hart reset does not implicitly reset/stop
PIO or its DMA job. Those independent domains retain the R2 service contract.
Restarted firmware must discover active/closing sessions and recover or adopt
them explicitly before reconfiguration; debug software uses PAUSE/ABORT when
pin activity must stop. Only system or qualified PIO-local lifecycle commands
own PIO reset.
## Errors, Recovery, Security, and Observability
FAULT first-code values are 0 none, 1 illegal instruction, 2 invalid fetch,
3 program bounds, 4 shift bounds, 5 pin authorization, 6 ownership/filter lost,
7 GPIO not ready/reset, 8 invalid stream beat. A first error latches code/PC
until SM_RESET; later events cannot overwrite it. If simultaneous, GPIO
readiness/ownership faults precede stream faults, then execution faults;
within the same class the lowest code wins. APB errors have no requested
side effect and remain bus errors rather than silently changing first fault.
Sticky FIFO stall/failure events and saturating counters expose underrun/
overflow pressure without inventing data loss counts. Pin capture may miss
events while stalled; a lossless application rejects any RX_STALL. TX stall
is acceptable only when its protocol explicitly allows extending that phase.
PC/ISR/OSR/X/Y and execution phase are live diagnostics; PAUSE provides an
execution snapshot, not an atomic snapshot of moving FIFO/DMA state.
PIO is trusted firmware functionality, not sandboxed code. GPIO claim checks
do not isolate malicious APB writers, provide secure boot, qualify entropy,
establish functional safety or guarantee electrical fault protection. Drivers
must check external voltage/drive/open-drain/turnaround requirements. No Pin
rate is derived merely from PCLK; pad/board timing and synchronizer behavior
require independent evidence.
## MVP and Commercial-grade Roadmap
MVP means the exact two-SM architecture, software tooling, GPIO/DMA lifecycle
and all three independent application groups below. It is not permission to
expand storage to make an oversized demonstration fit.
| Group | Required finite/observable acceptance |
| --- | --- |
| Digital instruments | Eight-channel 32 KiB finite capture at 1 MSPS, plus pulse generation/width capture using both SMs; no missing/repeated samples and documented synchronizer/tick error bounds |
| Serial protocols | UART8N1 TX/RX at 115200 baud with <=2% actual baud error; SPI master CPOL/CPHA0..3 at 1 MHz and 8/16/32-bit frames;38 kHz carrier/mark-space IR TX and demodulated pulse-width RX |
| Interactive lighting | Externally driven 8x8 monochrome LED matrix at>=200 complete frames/s, with blank-before-wait behavior;8-bit latch/clock/data shift-register gamepad with deterministic and changing input patterns |
These are separate profiles/scenarios, not all simultaneously enabled. UART
duplex and pulse/capture pairs must fit the combined 32 instructions. Each
scenario records SMs, instruction allocation, pin masks, native peripherals
disabled, FIFO packing, DMA ownership and expected word counts. No new APP
selection is required; use existing bringup composition. IR RX variable-length
records use bounded CPU/IRQ service, explicit buffer limits and software
framing, not an unbounded FIFO or early-DMA-success extension.
At 24/48/60 MHz, a two-tick eight-bit capture loop with DIV 12/24/30 gives 1 MSPS;
32 KiB contains 32768 samples and 8192 packed FIFO words. An eight-tick UART bit
with DIV 26/52/65 yields about 115384.6 baud (0.16% high). A 12-tick SPI bit with
DIV 2/4/5 yields1 MHz. These are arithmetic design budgets, not assembled or
tested programs; actual instruction paths, frame boundaries and pin latency
must satisfy them before publication. IR carrier tolerance is<=2%; pulse
envelope error includes documented integer quantization. Faster experiments
are measurements, not substitutes for the three baseline acceptance groups.
Commercial evolution may add four SMs, larger stores or richer timing only
through a separate ABI/resource/physical review. Maintain a reusable program
library, independent protocol models and per-board routing examples first.
Do not advertise a camera+audio+PIO combination without its own pin/DMA/service
budget and tests; existing camera/audio exclusion still applies.
## Verification and Software Validation
P1 supplies a cycle-accurate reference model and deterministic assembler tests;
P2 compares RTL against the model with independent protocol assertions. P3/P4
add actual Tiny pad/stream/firmware integration. The detailed requirement and
evidence ledger is [PIO-lite verification](piolite-verification.md).
Mandatory cases include all opcodes/operand rejection, count 0 encoding 32,
counter 0/65535, DIV 1/65535, every delay, wrap/branch bounds, instruction-store
sharing and exhaustion, simultaneous SM execution, WAIT/PAUSE/ABORT under
infinite stalls, partial pack tails, FIFO full/empty and concurrent push/pop,
set/W1C races, lost ownership/filter changes, GPIO handoff/lock failures,
DMA descriptor abort/activation races, suspended mixed chains, simultaneous
START/rebind, residual RX VALID, memory response errors and timeout retention.
Test unaffected SMs/channels and Mini's PIO-disabled shared-IP integration.
Firmware verdict is Tiny SYSCTRL TEST_STATUS and `SIM_TEST_PASS`, successful
command exit, and no `FAILED`, `FATAL`, `assertion failed`, `%Error`,
`SIM_TEST_FAIL` or `SIM_TEST_TIMEOUT`. UART boot text is not acceptance.
Verilator and Icarus pin BFMs must validate first/last-bit timing, all SPI modes,
UART asynchronous phase/error recovery, pulse bounds and display blanking.
Current commands below describe existing tooling, not proof that PIO tests
already exist. P1/P2 add focused tests to normal test discovery, not fictional
Make targets. After the relevant implementation is authorized:
```sh
ruff check .
python3 -m pytest -q
make sw-format-check sw-policy-check sw-host-test
make CONFIG=configs/ci/ihp130-tiny.mk firmware
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY --dry-run
python3 scripts/regress.py --root . --suite nightly --soc TINY --dry-run
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY
python3 scripts/regress.py --root . --suite nightly --soc TINY
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc MINI
```
P1 Python-only validation does not require running absent PIO RTL or pretending
R2 platforms are ready. New self-owned C follows MISRA C:2012 Amendment 2;
no deviation is approved by this document. Required-rule deviations, if any,
need their own reviewed record. Existing excluded/managed code remains excluded.
## Synthesis, Timing, and Physical Evidence
For TINY/IHP130, record source SHA, lock/config digest, variant, PCLK/SYS/MEM,
program binaries, pin loads and enabled endpoints for every result. Required
evidence includes block and full-SoC synthesis, register/IMEM/FIFO mapping,
area/cell count, activity-based power, WNS/TNS, reset fanout and release,
CDC/RDC review, netlist simulation, PVT/MMMC and extracted timing. Existing
observe-mode metrics and warning-baseline policy remain unchanged.
PIO PCLK 24/48/60 timing must coexist with the corresponding R2 SYS/SRAM and
MEM operating points; a PIO-only pass cannot qualify CPU240 or SRAM macros.
Physical evidence includes Pad rise/fall, load, setup/hold, OE turnaround,
simultaneous switching, board constraints and QFN64 routing. Structural DFT
and local-storage test coverage must be reviewed; no SRAM MBIST/ECC or silicon
qualification is claimed for these register arrays.
P5 may share a campaign with TINY-R2-P11 after applicable R2 system tests, but
both must identify the same PIO-inclusive source/netlist/configuration. Earlier
R2 qualification does not cover added storage, routing, reset load or pads.
Missing macro/Pad views, vendor models, licensed tools and board/silicon access
remain explicit gaps, not waived requirements.
## Development Order
All phases target TINY; shared-IP regression on Mini is compatibility work.
IDs and titles below are stable. P0 freezes documents only; no later phase is
authorized or marked complete by approval of this document.
| ID / stable title | Dependencies; changes; completion |
| --- | --- |
| PIOLITE-P0 - Contract Freeze | Approved research; create this contract/verification ledger and synchronize Tiny/GPIO/DMA/index docs. Freeze APB/ISA, address/IRQ/RCU, DMA and lifecycle contracts. Check links, commands, consistency and `git diff --check`; no implementation evidence. |
| PIOLITE-P1 - ISA Reference Model and Assembler | P0; add model, assembler, source programs/metadata and deterministic tests. Validate every ISA boundary and actual 32-word application/pair footprints with Ruff/Pytest. No Tiny integration or software-visible contract changes beyond implementing this frozen format. |
| PIOLITE-P2 - Core and Register Implementation | P1; implement owned hierarchy/APB/ISA, FIFOs, guard/adapters at standalone interfaces, handwritten SVH/C parity and testbench/assertions. Model-differential, directed/random/formal, lint/style and block-synthesis evidence; no false integrated capability. |
| PIOLITE-P3 - Tiny GPIO and DMA Integration | P2 plus applicable TINY-R2-P6/P7 and inherited fabric prerequisites; change topology/address/IRQ/RCU/filelists, GPIO sidebands and HAL, DMA V2.1 capability/grants/cancellation. Validate clock/reset ownership, full drain/recovery and unaffected Mini using targeted tests, SDK checks and affected firmware/simulations. |
| PIOLITE-P4 - SDK and Application Qualification | P3; finish freestanding loader/session/example library and all three bringup groups, exact counts/tails, independent BFMs, contention/long-duration/error recovery and complete Tiny regressions. No rate claim without current-program evidence. |
| PIOLITE-P5 - IHP130 Timing and Physical Qualification | P4 plus applicable R2-P10 system evidence; full-source synthesis/netlist/STA/CDC/RDC/physical/pad campaign, optionally joint R2-P11. Close or explicitly block each release gate; report measured rates/area/power, not vendor-derived values. |
### Next-phase preflight handoff
```text
Use $retrosoc-feature-implementation. Stage: preflight. Feature slug: piolite. Target SoCs: TINY.
Phase: PIOLITE-P1 - ISA Reference Model and Assembler.
Read docs/ip/piolite.md and docs/ip/piolite-verification.md. The executable starting profile is configs/ci/ihp130-tiny.mk, PDK IHP130, 24 MHz/no PLL; it has no PIO integration yet.
Plan only the frozen ISA reference model, deterministic assembler, program metadata/relocation and focused tests, including actual 32-word application and dual-SM footprints. Preserve the two-SM architecture, PCLK tick/packing semantics, GPIO/DMA lifecycle contracts and all R2 phase identifiers.
Do not implement RTL, HAL integration, DMA V2.1, GPIO/RCU wiring, new profiles or later phases. Do not alter the ISA/ABI, expand memory or package scope, download new dependencies, change quality policy, commit or push. Report SPEC_CONFLICT if a frozen requirement cannot be met; do not weaken it. Return the scoped preflight and validation plan for explicit approval before implementation.
```
## Commercial Delivery Gaps
At freeze, PIO RTL, model/assembler, register parity, HAL, DMA V2.1 changes,
integration metadata, pin BFMs and application programs are not delivered.
Coverage closure, reusable VIP, reset/CDC/RDC proof, DFT, extracted PVT timing,
power characterization, board routing examples, release artifacts and silicon
validation remain required. A documentation freeze does not update RTL
readiness, approve a new PDK, advance implementation phases or authorize a push.
+48 -2
View File
@@ -13,13 +13,59 @@ Historical `TINY-P0` through `TINY-P12` identifiers and evidence are preserved
under their original scope; the mapping in the main contract transfers
outstanding obligations without renaming old results or declaring them passed.
Other PDK qualification, new SPI/PIO/BootROM IP and changes to QFN64 or the
frozen IO/power-pad budget are outside this refreeze.
frozen IO/power-pad budget are outside the original performance-only R2
refreeze. PIO-lite is now a separately approved standard-product extension
under [piolite.md](piolite.md), with its own pending evidence matrix below;
it does not renumber or retroactively expand the R2 phase results.
The executed historical sections describe the 2026-09-25 initial baseline,
with two UARTs, two I2C controllers and the legacy pad mapping. The working
tree was uncommitted when that evidence was collected and its readiness
remains `prototype`. Those results do not validate the later package,
shared-IP/clock/reset, DVP/framebuffer or R2 performance refreezes.
shared-IP/clock/reset, DVP/framebuffer, R2 performance or PIO-lite freezes.
## PIO-lite planned extension evidence
Target SoCs: `TINY`; feature slug: `piolite`; approval date: 2026-10-04.
The standard-product target adds two state machines sharing 32 x 16-bit
program storage, 32-bit ISR/OSR, 16-bit X/Y counters and separate 8 x 32-bit
TX/RX FIFOs per state machine. The engine, APB and host DMA endpoints use
PCLK at the existing 24/48/60 MHz targets. This section records required
future evidence only; no assembler/model, RTL, firmware, DMA, simulation,
formal, synthesis, timing, physical or silicon acceptance has been executed
for PIO-lite by the freeze. Four-state-machine expansion is not MVP support.
The committed `configs/ci/ihp130-tiny.mk` IHP130 24 MHz/no-PLL profile has no
PIO-lite integration. New address/IRQ/request/RCU allocations remain planned
until their complete executable paths and truthful capabilities exist. The
authoritative phase titles and requirements remain in [piolite.md](piolite.md).
The detailed case matrix and documentation-check record are maintained in the
[PIO-lite verification ledger](piolite-verification.md).
| PIO-lite phase / area | Required evidence and completion boundary | Status |
| --- | --- | --- |
| PIOLITE-P0 / contract | Approved ISA/ABI, resources, pin ownership and lifecycle; consistent linked product/GPIO/DMA allocations; preserved legacy/R2 phase IDs/titles and unchanged QFN64 terminals; documentation links and commands. | Documentation freeze only; no implementation result |
| PIOLITE-P1 / model and assembler | Deterministic encoding and model traces; valid/invalid opcodes, operands, labels, branches, wrap and program-size boundaries; shared 32-word allocation; software error handling and generated program metadata against the frozen ISA. | Pending |
| PIOLITE-P2 / core and registers | Both independent SMs, divider/delay/branch/shift/counter boundaries, TX/RX full/empty and stalled-instruction behavior; illegal accesses, W1C races, stop/abort/reset, stale-data isolation, program-write restrictions and configuration conflicts; directed/randomized model comparison and focused formal properties. | Pending |
| PIOLITE-P3 / Tiny integration and HAL | APB `0x1001C000..0x1001CFFF`, IRQ24, RCU target15, requests `PIOLITE_TX=14` / `PIOLITE_RX=15`, actual capability discovery, handwritten register parity, freestanding bounded HAL and actual R2-P6/P7 prerequisites; no fourth AXI master or ninth DMA channel. | Pending |
| PIOLITE-P3 / pad and lifecycle ownership | `USER_SELECT` reach to all GPIO0-31; unchanged ALT0/ALT1 and dedicated boot/debug/control pads; conflicts, high-impedance reset, existing GPIO synchronizer plus registered bypass/filter stage with `FILTER_ENABLE=0`, input latency and release; no new PIO synchronizer/raw-pad bypass; reject GPIO gate/reset while PIO owns any pad, including multi-target commands; clock-change and PIO gate/reset drain/restart barriers. | Pending |
| PIOLITE-P4 / DMA and protocol programs | Approved pin-level acceptance programs in Icarus and Verilator; independently checked data, edge/bit timing, first/last transfer, short frames, FIFO starvation/overflow, bounded recovery and strict Tiny terminal verdict; source-bound throughput and worst observed service gaps. | Pending |
| PIOLITE-P4 / system contention | TX channel3 only after bulk-owner release, RX channel2 only after complete camera release; no theft of Crypto4/5 or I2S6/7, correct abort/final-response drain and backpressure; CPU/control progress and real FIFO service budgets with actual permitted background traffic. | Pending |
| PIOLITE-P5 / physical product | PIO-inclusive netlist and source/profile/PDK/corner identity; area/reset load, PCLK STA, GPIO ownership paths, input synchronizers, pad setup/hold/turnaround, simultaneous switching, package/power and CDC/RDC evidence; declared engine rate distinguished from external interface rate. | Pending |
`PIOLITE-P3` depends on the applicable accepted R2-P6/R2-P7 platform behavior.
`PIOLITE-P5` may share a run with `TINY-R2-P11` only when the same PIO-inclusive
source revision, configuration and physical inputs satisfy both contracts.
An earlier R2 netlist, standalone PIO test or another SoC's result cannot
qualify the extended standard Tiny product. Preserve 128 KiB main SRAM on
the same SYS source and rate as the CPU, three external AXI owners, eight
central DMA channels and all QFN64/power assignments in every integration run.
Record exact commands and executed simulator/proof coverage when tests are
introduced; a skipped/no-op RTL test or reserved request ID is not evidence.
Firmware uses SYSCTRL `TEST_STATUS` and the strict `SIM_TEST_PASS`/result-file
policy. Hardware, pad-speed and PPA claims remain pending until the specific
source/profile/PDK evidence passes.
## R2 pending phase acceptance
+119 -24
View File
@@ -2,15 +2,24 @@
## Purpose and research boundary
This contract freezes the performance-only R2 design approved on 2026-10-04
for Target SoCs: `TINY`, feature slug `tiny-soc`. It preserves the QFN64
The R2 portion of this contract freezes the performance-only design approved
on 2026-10-04 for Target SoCs: `TINY`, feature slug `tiny-soc`. It preserves the QFN64
package and pad allocation approved on 2026-09-26, the shared peripherals
approved on 2026-09-30, and the DVP/XPI-framebuffer contract of 2026-10-01.
R2 adds independent CPU I/D local paths, four independently arbitrated main
SRAM groups, per-target concurrency and bounded data-movement policies.
CPU and the actual main-SRAM macros share SYS at the same active frequency.
No pad, peripheral, user-SRAM capacity, DMA channel or external AXI owner is
added. `R2` identifies the development-roadmap revision, not an IP ABI version.
added by that performance refreeze. `R2` identifies the development-roadmap
revision, not an IP ABI version.
The separately approved 2026-10-04 [PIO-lite extension](piolite.md), feature
slug `piolite`, adds a programmable I/O block to the future standard Tiny
product. It preserves QFN64, all existing ALT0/ALT1 assignments, the 128 KiB
main SRAM, eight-channel DMA target and three external AXI owners. Its
`PIOLITE-P0` through `PIOLITE-P5` phases remain separate from the unchanged R2
phase sequence. PIO-lite is required by the extended product target but is
not implemented or qualified by this documentation freeze.
The clock contract retains the 96 MHz no-PLL and 192/240 MHz PLL targets,
now requiring the main SRAM to qualify at those same rates. Both variants
@@ -31,12 +40,16 @@ contract and must not be read as the new Gen1 integration or clock qualification
Product RTL, address/pin/topology inputs and filelists remain under `rtl/tiny`;
the SDK and application composition retain their existing `crt/` and `app/`
ownership. The active execution order is `TINY-R2-P0` through `TINY-R2-P11`,
ownership. The active R2 execution order is `TINY-R2-P0` through `TINY-R2-P11`,
with prerequisites pointing only to earlier R2 phases. Legacy `TINY-P0`
through `TINY-P12` keep their original headings and evidence in the archive;
their former non-monotonic schedule is not the current execution plan.
The current profile still selects four DMA channels and forbids PLL/non-24-MHz
Tiny configurations. New configurations require explicit platform enablement.
PIO-lite integration in `PIOLITE-P3` requires the applicable accepted R2-P6
DMA/shared-integration and R2-P7 RCU functionality. `PIOLITE-P5` may share a
physical run with R2-P11 only on the same PIO-inclusive source revision and
configuration, with both contracts' evidence requirements satisfied.
### Commercial references and reuse boundary
@@ -52,12 +65,14 @@ PPA or signoff evidence; no proprietary implementation is copied.
| [STM32H573 datasheet](https://www.st.com/resource/en/datasheet/stm32h573vi.pdf) | DS14121 Rev 5 (May 2025) describes a production 250 MHz MCU with domain controls, CRC/RNG/crypto and a parallel camera interface supporting snapshot/continuous capture and cropping. | Reuse the snapshot/crop programming pattern and separate product clock control. Do not import its wider camera bus, JPEG support, TrustZone, protected-key, independent-watchdog-clock or TRNG certification claims. |
| [Espressif camera driver](https://github.com/espressif/esp32-camera) | The official ESP32/ESP32-S2/ESP32-S3 driver documents PSRAM frame buffers and PSRAM DMA on S2/S3; it warns that raw RGB/YUV writes can lose data when bandwidth is insufficient. Single-buffer capture and multiple-buffer continuous capture have different memory/bandwidth costs. | Use external RAM capacity with explicit throughput and worst-stall checks. Tiny selects one-frame capture/readback first, not a descriptor ring, compression path or guaranteed continuous frame rate. The maintained driver is a software reference, not Tiny silicon, power or timing evidence. |
| [GD32F450 datasheet](https://gd32mcu.com/data/documents/datasheet/GD32F450xx_Datasheet_Rev2.3.pdf) | Rev 2.3 describes 200 MHz AHB domains, 50/100 MHz APB domains and RCU-managed clocks/resets. | Use explicit domain ceilings and dividers rather than assigning the processor frequency to every peripheral. No analog macro, process-specific voltage or measured PPA is reused. |
| [RP2350 architecture documentation](https://www.raspberrypi.com/documentation/microcontrollers/microcontroller-chips.html) | Current official documentation describes a multi-master crossbar and independently accessible SRAM banks for CPU/DMA concurrency. | Adopt independent target/bank service and explicit contention analysis. Tiny remains single-hart with 128 KiB, no new cache, PIO, USB or imported frequency/power claim. |
| [RP2350 architecture documentation](https://www.raspberrypi.com/documentation/microcontrollers/microcontroller-chips.html) | Current official documentation describes a multi-master crossbar and independently accessible SRAM banks for CPU/DMA concurrency. | Adopt independent target/bank service and explicit contention analysis. The performance-only R2 scope retains one hart and 128 KiB without adding cache, PIO or USB. The separately approved PIO-lite contract supplies its own scope; no vendor frequency/power claim is imported. |
| [STM32H573 RM0481](https://www.st.com/resource/en/reference_manual/rm0481-stm32h563h573-and-stm32h562-armbased-32bit-mcus-stmicroelectronics.pdf) | The reference manual describes CPU, general-DMA and SDMMC-DMA paths, multiple SRAM targets and round-robin bus-matrix arbitration. | Use target-local arbitration and separate control/data traffic. Do not infer Cortex-M33 timing, cache/coherency, TrustZone or zero-wait behavior for Tiny. |
The [RP2350](https://www.raspberrypi.com/products/rp2350/) is a Hazard3-based MCU
reference for software, SRAM, and deterministic I/O. Its dual-core, security,
USB, and PIO features are not Tiny requirements. The
and USB features are not Tiny requirements. The separate [PIO-lite](piolite.md)
contract uses programmable-I/O references without RP ISA or SDK compatibility.
The
[CAST SRAM controller](https://www.cast-inc.com/peripherals/memory-controllers/sram-ctrl)
illustrates native AXI synchronous SRAM and documented verification delivery;
no commercial implementation or qualification is reused.
@@ -77,8 +92,8 @@ no commercial implementation or qualification is reused.
- TINY-004: 32 bidirectional user GPIO, one UART, one I2C controller, one
full-duplex I2S controller, one SDIO host, two general timers, CLINT, eight
central DMA channels, four PWM outputs, RTC, watchdog, RNG V2, CRC V2,
WS2812, Crypto V2, DVP V2, Tiny RCU/SYSCTRL and architecture info. UART1 and
I2C1 are absent from the Gen1 target.
WS2812, Crypto V2, DVP V2, PIO-lite, Tiny RCU/SYSCTRL and architecture info.
UART1 and I2C1 are absent from the Gen1 target.
- TINY-005: retain `HAVE_PLL` as the single PLL build selector. With no PLL,
use an external XIN clock up to 96 MHz; with PLL, use a 24 MHz reference and
the single-output PLL interface for a maximum 240 MHz SYS/processor target.
@@ -99,8 +114,11 @@ no commercial implementation or qualification is reused.
return must meet the selected oscillator/PLL macro requirements. Position
labels on supply pins do not create independently powered IO banks.
- TINY-010: GPIO retains the `ALT_ENABLE`/`ALT_SELECT` model with GPIO, ALT0
and ALT1 modes. The Gen1 table below defines the logical mapping. UART/I2C
alternate input locations must have one selected route, never an OR of
and ALT1 modes. The separately approved PIO-lite extension uses `USER_SELECT`
for exclusive ownership of any of GPIO0-31 without replacing ALT0/ALT1
assignments or reaching dedicated boot/debug/control pads. The Gen1 table
below defines the logical mapping. UART/I2C alternate input locations must
have one selected route, never an OR of
competing inputs. I2C must preserve open-drain drive and input readback.
- TINY-011: reset must leave user GPIO as high-impedance inputs with alternate
functions disabled, preserve dedicated boot/debug access, and meet the
@@ -201,19 +219,43 @@ no commercial implementation or qualification is reused.
netlist and physical evidence. The active R2 roadmap MUST retain the legacy
phase IDs/titles and evidence as history, with explicit obligation mapping;
no historical phase or timing gap is closed merely by this refreeze.
- TINY-037: the standard Tiny target MUST include [PIO-lite](piolite.md) with
two state machines, one shared 32 x 16-bit program store, 32-bit ISR/OSR,
16-bit X/Y counters and independent 8 x 32-bit TX and RX FIFOs per machine.
Four-state-machine expansion is reserved by the IP contract, not an MVP
capability. PIO-lite uses PCLK and integer clock enables, with the existing
24/48/60 MHz PCLK targets subject to source-bound qualification.
- TINY-038: PIO-lite MUST use APB4 `0x1001C000..0x1001CFFF`, CPU IRQ24,
Tiny RCU target bit 15 and central-DMA requests `PIOLITE_TX=14` / `PIOLITE_RX=15`.
Default TX borrows channel 3 after bulk-client release; default RX borrows
channel 2 only after complete camera release. No additional DMA channel,
AXI master, user-SRAM capacity or package pad is introduced.
- TINY-039: GPIO gating or peripheral reset MUST be rejected while PIO-lite
owns any user pad, even when a command also selects PIO-lite. Software MUST
stop/drain PIO-lite and release pad ownership before that GPIO operation.
Clock changes and PIO gate/reset follow the linked PIO-lite lifecycle;
system reset still releases all user pads to high impedance.
- TINY-040: `PIOLITE-P0` through `PIOLITE-P5` MUST remain a separately approved
feature extension without renaming legacy or R2 phases. PIO capabilities,
requests, IRQ and RCU support MUST remain absent until their complete paths
exist. Functional, DMA/contention and physical evidence MUST identify the
actual PIO-inclusive source, profile and PDK; old R2 results do not qualify it.
Deferred: RV32 A atomics, RTOS ports, authenticated boot, retention/power gating,
independent sleep clock, 256-512 KiB SRAM, USB, standalone general SPI, CAN, ADC,
multimedia accelerators beyond the selected DVP capture path and other PDK
qualification. I2S, SDIO and DVP are Gen1 requirements awaiting integration,
not deferred product features. XPI retains
four chip selects: CS0_N is dedicated to boot NOR, while CS1_N through CS3_N
qualification. I2S, SDIO, DVP and the approved PIO-lite extension are standard
Tiny requirements awaiting integration, not deferred product features. XPI
retains four chip selects: CS0_N is dedicated to boot NOR, while CS1_N through CS3_N
use GPIO29 through GPIO31. Additional XPI device configurations still require
their own qualification.
This R2 scope MUST NOT add SPI, PIO-lite, a recovery Boot ROM, caches, atomics,
new accelerators or another PDK rollout. Those research ideas are explicitly
deferred rather than hidden prerequisites of the performance work.
The original performance-only R2 scope MUST NOT add SPI, PIO-lite, a recovery
Boot ROM, caches, atomics, new accelerators or another PDK rollout. That
historical scope boundary remains in force for its phase work. PIO-lite is
now a separately approved standard-product extension governed by
[piolite.md](piolite.md); its phases do not become hidden prerequisites of
R2-P0 through R2-P10. The other listed research ideas remain deferred.
## QFN64 package and power planning
@@ -322,6 +364,9 @@ Every row supports ordinary bidirectional GPIO mode. `Reserved` means no
assigned alternate function; it does not remove the GPIO capability. This
table supersedes the legacy Mini-derived Tiny routing for the Gen1 target,
but is not yet implemented by the current Tiny canonical maps.
The PIO-lite `USER_SELECT` route is an independent ownership selection for all
32 user GPIO; it does not occupy or change an ALT0/ALT1 table entry. Existing
peripheral functions are unavailable on each pad while PIO-lite owns it.
| GPIO | QFN pin | ALT0 | ALT1 | Direction or use |
| --- | ---: | --- | --- | --- |
@@ -395,6 +440,13 @@ leaves 16. Including SD card detection/power and four PWM outputs uses 22 and
leaves 10. WS2812 and the alternate I2C SCL route on GPIO26 are mutually
exclusive; the default I2C route on GPIO10/11 remains available.
These counts assume PIO-lite has not claimed the listed peripheral pads.
PIO-lite may claim any otherwise released GPIO through `USER_SELECT`; it
does not increase the number of simultaneously available pads. Its ownership
and conflict checks follow [PIO-lite](piolite.md) and [GPIO](gpio.md). Input
sampling uses the existing GPIO synchronizer plus its registered bypass/filter
stage with `FILTER_ENABLE=0`; no PIO-lite synchronizer or raw-pad bypass is added.
### Camera profile and board ownership
GPIO12-23 ALT1 forms one camera profile: DVP_D0-7, DVP_PIXCLK, DVP_HREF,
@@ -555,6 +607,7 @@ linked common contract; do not generate a second set of IP registers.
| DVP V2 | `0x1000E000` | 15 | [DVP](dvp.md), existing APB4/32-bit stream ABI, `DVP_RX=11`, Tiny DMA channel 2 |
| SDIO0 | `0x1000F000` | 10 | [SDIO](sdio.md), one host and its private AXI32 DMA master |
| Central DMA | `0x1000A000` | 20 | [DMA V2](dma.md), eight channels and supported request discovery |
| PIO-lite | `0x1001C000` | 24 | [PIO-lite](piolite.md), 4 KiB APB4 window, two state machines in PCLK; separately approved standard-product extension |
Mini's RCU has no separate MMIO region: its software controls are in SYSCTRL
at `0x1000B000`. Tiny retains this base and uses the private bank below for
@@ -568,6 +621,8 @@ base addresses. Retain CPU IRQ bits 0/1 for CLINT, 2 UART0, 3/4 timers,
I2C1 windows have no successful decode, and their IRQ bits 26/19 are zero.
All other unallocated IRQ bits are zero. CRC has no fabricated interrupt or
private DMA request; software finishes the CRC session after DMA completion.
PIO-lite's window is `0x1001C000..0x1001CFFF`; IRQ24 remains zero and its
capability absent until the block and complete interrupt path are integrated.
### DMA and bus behavior
@@ -575,14 +630,16 @@ private DMA request; software finishes the CRC session after DMA completion.
| ---: | --- |
| 0 | UART0 |
| 1 | I2C0 |
| 2 | DVP receive; general memory transfers only when camera ownership is released |
| 3 | Serialized bulk clients: XPI, WS2812 and CRC |
| 2 | DVP receive; PIO-lite RX or general memory transfers only after camera ownership is released |
| 3 | Serialized bulk clients: XPI, WS2812, CRC and PIO-lite TX |
| 4 | Crypto input |
| 5 | Crypto output |
| 6 | I2S transmit |
| 7 | I2S receive |
Retain Crypto request IDs 12/13, I2S request IDs 1/2 and DVP request ID 11.
The PIO-lite extension adds requests `PIOLITE_TX=14` and `PIOLITE_RX=15` without
renumbering existing requests or increasing the eight-channel target.
Channel ownership is product integration data, not a different DMA register
ABI. In particular,
Tiny channel 6 is not Mini's HP-boot reservation. Shared drivers use product
@@ -593,6 +650,14 @@ drain; memory clients must not steal it. DVP is a stream source, not a fourth
AXI master. Writing its stream to XPI mapped RAM still uses `DVP_RX`, not an
XPI indirect TX request or a CPU whole-frame staging buffer.
PIO-lite uses explicit, exclusive application ownership: default TX borrows
channel 3 only after the current bulk client has drained and released it;
default RX borrows channel 2 only after camera capture and all accepted DMA
writes have completed and camera ownership is released. Failure to acquire
either channel returns boundedly without stealing another client's channel.
PIO-lite has no private AXI master. CPU/FIFO and central-DMA access, selected
state machine, request readiness and completion follow [PIO-lite](piolite.md).
Retain the common DMA direct/TCD ABI, 32-bit Tiny datapath, at-most-16-beat
memory bursts, completion/error/W1C and abort-drain behavior. Replace the
baseline's blanket Tiny stream rejection with truthful endpoint capabilities;
@@ -602,6 +667,10 @@ Crypto, I2S and DVP host streams in PCLK, without adding CDC inside the shared
stream contracts. Existing request thresholds and cross-domain XPI
completion/request signals require
proper synchronization/handshake at the product boundary.
PIO-lite's engine, APB and host-side DMA endpoints remain in PCLK. Requests
14/15 MUST stay unsupported until `PIOLITE-P3` connects their complete paths;
an allocation or tie-off is not a capability. The existing PCLK-to-SYS
central-DMA bridge retains its request/response and reset responsibilities.
R2 replaces the global read-or-write lock with independent target admission,
owner state and response storage. The external owners remain merged CPU slow
@@ -981,7 +1050,7 @@ remain clocked while XIN runs and MUST NOT be software-gated.
| AON / REF24 | RCU, CLINT, ArchInfo; RTC/WDG functional clocks | 24 MHz | 24 MHz | 24 MHz | 24 MHz |
| SYS | CPU I/D and slow adapter, actual main-SRAM macros, four bank frontends/control, AXI32 fabric, SDIO including its APB and private DMA | 24 MHz | 96 MHz | 192 MHz | 240 MHz |
| MEM | XPI, including its control interface | 24 MHz | 96 MHz | 96 MHz | 120 MHz |
| PCLK | Eight-channel DMA, GPIO, UART0, I2C0, timers, PWM, RNG, CRC, WS2812, Crypto, I2S/DVP hosts; RTC/WDG APB | 24 MHz | 48 MHz | 48 MHz | 60 MHz |
| PCLK | Eight-channel DMA, GPIO, UART0, I2C0, timers, PWM, RNG, CRC, WS2812, Crypto, I2S/DVP hosts, PIO-lite engine/APB/DMA endpoints; RTC/WDG APB | 24 MHz | 48 MHz | 48 MHz | 60 MHz |
| AUDIO | I2S audio PHY and existing audio-side FIFOs | External | External | External | External |
| PIXCLK | DVP pixel path and existing pixel-side FIFO | External | External | External | External |
| JTAG | TAP/DTM | Separate TCK | Separate TCK | Separate TCK | Separate TCK |
@@ -1011,6 +1080,14 @@ or lower both together through an explicitly reviewed profile; never restore
CPU240/SRAM120 as a fallback. The target frequencies remain unqualified until
the required physical evidence passes.
PIO-lite inherits the committed PCLK rate and divides execution using integer
clock enables; it introduces no independent clock, PLL or external pin clock.
Its 24/48/60 MHz engine targets are not pad toggle or serial bit-rate claims.
Before a PCLK change, software MUST quiesce PIO state machines, drain accepted
DMA/APB work and satisfy the lifecycle in [PIO-lite](piolite.md). Restart uses
the new committed rate and explicitly initialized timing state; a clock change
does not transparently preserve an in-flight protocol waveform.
CLINT's counter/control stays in AON with a synchronous 1 MHz tick enable.
Its timebase does not change or lose ticks during SYS transitions. CLINT
interrupt levels cross into SYS through synchronizers. RTC and watchdog
@@ -1259,7 +1336,7 @@ reachable through an acknowledged APB bridge while the system is running.
| `0x14C` | `MEM_HZ` | RO / 24000000 | Committed divided XPI MEM-domain frequency, not main-SRAM frequency |
| `0x150` | `PCLK_HZ` | RO / 24000000 | Committed peripheral frequency |
| `0x154` | `CLINT_HZ` | RO / 1000000 | CLINT tick rate |
| `0x158` | `TARGET_CAPABILITY` | RO / build-dependent | Implemented gate targets; `0x00003FFF` before DVP integration, `0x00007FFF` when all Gen1 targets exist; reset excludes CPU bit 0 |
| `0x158` | `TARGET_CAPABILITY` | RO / build-dependent | Implemented gate targets; full sets are `0x00003FFF` before DVP/PIO, `0x00007FFF` with DVP but no PIO, and `0x0000FFFF` with DVP and PIO; absent target bits stay clear; reset excludes CPU bit 0 |
| `0x15C` | `CLKOUT_CONTROL` | RW / 0 | Source `[2:0]`; half-period divisor `[23:8]`; output is off after reset |
Clock profile 0 is SAFE24. Profile 1 is external XIN at its declared frequency
@@ -1275,11 +1352,14 @@ identity and manifest must identify the model rather than physical qualification
The target-mask bits are Tiny integration identifiers, not Mini register ABI:
0 CPU, 1 GPIO, 2 UART0, 3 I2C0, 4 timer0, 5 timer1, 6 PWM, 7 I2S, 8 SDIO,
9 central DMA, 10 WS2812, 11 RNG, 12 CRC, 13 Crypto and 14 DVP. Bits 15-31
are reserved. Bit 14 is an additive target allocation; existing offsets/bits
and RCU ABI 1.0 semantics remain unchanged. R2-P7 may reserve the control plumbing
9 central DMA, 10 WS2812, 11 RNG, 12 CRC, 13 Crypto, 14 DVP and 15 PIO-lite.
Bits 16-31 are reserved. Bits 14/15 are additive target allocations; existing
offsets/bits and RCU ABI 1.0 semantics remain unchanged. R2-P7 may reserve the
control plumbing
but MUST report bit 14 clear and reject its commands until R2-P9 instantiates
the complete DVP idle/reset/CDC path. No capability is inferred from a tie-off.
the complete DVP idle/reset/CDC path. It MUST report bit 15 clear and reject
its commands until `PIOLITE-P3` instantiates the complete PIO-lite idle/reset
path. No capability is inferred from a tie-off.
CPU gating means permission to gate only while WFI/idle with no pending IRQ or
debug request; it is not an immediate software stop. RCU/REF24, AXI, main
SRAM, XPI, CLINT, ArchInfo and RTC/WDG functional clocks cannot be gated or
@@ -1288,6 +1368,13 @@ individually reset through these masks. System reset owns their reset.
GATE_APPLY commits all selected gate changes only after the corresponding
idle/drain checks; a timeout preserves the previous gate configuration.
PERIPHERAL_RESET requires a nonzero supported mask and ungated targets.
GPIO target-1 gate or peripheral-reset commands MUST be rejected while any
PIO-lite pad ownership remains, with no partial gate/reset commit. This veto
also applies to multi-target commands naming both GPIO and PIO-lite: first
stop/drain PIO-lite and explicitly release its pins, then issue the GPIO
command. PIO target-15 gate/reset and CLOCK_APPLY require the PIO-lite
quiesce/drain checks defined in [piolite.md](piolite.md); preserve bounded
failure and continued control access when a machine is stalled on input/FIFO.
After draining associated DMA and accesses, hold each local reset for at
least five running local cycles and apply the five-edge release/barrier
sequence. RESET_DONE acknowledges the reset sequence, not Crypto erasure or
@@ -1648,6 +1735,14 @@ are not QFN64/192/240 MHz signoff. Do not reduce the fixed pad budget, waive
macro period failures through wait states, promote warning/metric policy, or
claim complete Gen1 while named shared-IP or physical prerequisites remain open.
The separately approved PIO-lite standard-product extension has its own
`PIOLITE-P0` through `PIOLITE-P5` development order in [piolite.md](piolite.md).
R2-P6/P7 supply platform prerequisites for `PIOLITE-P3`; they do not implement
PIO-lite merely by reserving its identifiers. `PIOLITE-P5` and R2-P11 may
share evidence only when it covers the same PIO-inclusive source revision,
configuration, PDK/corners and all requirements from both contracts. An R2
run without PIO-lite cannot close the extended standard-product release.
### R2 validation entrypoints
Use the committed baseline commands below plus directed tests and each new
+10
View File
@@ -62,6 +62,16 @@ order with sequential `TINY-R2-P0` through `TINY-R2-P11`; the original
Existing generated datasheets describe the baseline, not completed R2
implementation or qualification.
The separately approved 2026-10-04 [PIO-lite extension](ip/piolite.md) is a
future standard Tiny feature, not part of the historical performance-only R2
approval or current RTL baseline. Its two PCLK state machines share 32x16
instructions, use the existing 32 GPIO through USER ownership and borrow central
DMA requests 14/15 without adding pads, user-SRAM capacity or an AXI master.
Its independent `PIOLITE-P0..P5` gates preserve all R2 IDs and require fresh
PIO-inclusive application, timing and physical evidence. Other products remain
outside this feature scope; the [verification ledger](ip/piolite-verification.md)
records the unimplemented and unqualified boundary.
### Gen1 Product and Package Target
| Area | Tiny Gen1 target |
+7
View File
@@ -10,6 +10,13 @@ in `core`, AXI adapters in `interconnect`, and native AXI SRAM in `memory`.
Both products reference these shared files directly in their own filelists.
Tiny does not select any RIB/RIBP module.
The [PIO-lite contract](../../docs/ip/piolite.md) specifies a future owned
programmable-I/O block for Tiny, with shared GPIO ownership and DMA V2.1
integration changes. Its planned hierarchy is not present in the active
filelists yet. The [verification ledger](../../docs/ip/piolite-verification.md)
keeps model, RTL, integration and physical gates separate from design freeze;
shared DMA/GPIO changes must preserve Mini behavior without enabling PIO there.
experimental contains retained inactive RTL. It is not included by any active
filelist and must not become a build dependency without an explicit integration
change and matching validation.
+18
View File
@@ -39,6 +39,24 @@ the contract history. The committed RTL/profile still implements the initial
24 MHz/no-PLL/four-channel design; no faster CPU/SRAM or PLL timing support
follows from this freeze or the `HAVE_PLL` selector alone.
The separately approved [PIO-lite extension](../../docs/ip/piolite.md) is part
of the future standard Tiny product, with its own `PIOLITE-P0` through
`PIOLITE-P5` phases. It adds two state machines, shared 32 x 16-bit program
storage, 32-bit ISR/OSR, 16-bit X/Y and per-machine 8 x 32-bit TX/RX FIFOs in
PCLK. `USER_SELECT` reaches all 32 user GPIO without replacing ALT0/ALT1
assignments or changing the QFN64 pad budget. Planned allocations are APB4
`0x1001C000..0x1001CFFF`, IRQ24, RCU target15 and DMA requests
`PIOLITE_TX=14` / `PIOLITE_RX=15`. TX borrows
bulk channel3 and RX borrows channel2 only after the previous owner releases
it; the eight-channel target and three external AXI owners are unchanged.
PIO-lite is not present in the committed 24 MHz RTL/profile. Integration
depends on the applicable R2-P6/P7 DMA/RCU functionality; GPIO gate/reset must
be rejected while PIO owns any pad. PCLK24/48/60 are engine targets, not
qualified external-I/O rates. `PIOLITE-P5` may join R2-P11 physical work only
on the same PIO-inclusive source and configuration with both evidence sets.
The original R2 phase IDs/titles and performance-only scope remain intact.
Camera GPIO12-23 ALT1 remains mutually exclusive with I2S. DMA2/request 11,
optional XPI NSS1 PSRAM at `0x54000000` through GPIO29 and shared CAM_XCLK
retain their existing target contracts. RCU target 14 and DVP capabilities