Stage 2 turns bus writes into commands. Software sees a register map; the datapath sees only one-cycle pulses, a frozen configuration snapshot and status events.
Byte offset / register | CP-1 fields and semantics |
|---|---|
0x00 CONTROL | bit0 enable RW only on non-command writes while idle; bit1 START WO pulse; bit2 ABORT WO pulse; bit3 RECOVER WO pulse. Command writes do not rewrite enable. Other bits reserved zero; unsupported mode writes return SLVERR. |
0x04 FORMAT | RO 0x00030F0F: input fractional bits [4:0]=15, output [12:8]=15, nearest-even bit16=1, saturate bit17=1. Writes return SLVERR; selectable modes are an extension. |
0x08 COEFF | RW signed Q1.15 in [15:0], upper bits read zero; reset 0x4000. Busy writes return SLVERR with no update; byte strobes apply. |
0x0C STATUS | busy bit0 RO; done bit1 W1C; error bit2 W1C; aborted bit3 W1C; recovery_ready bit4 RO; final_counter_snapshot_valid bit5 RO. Hardware set wins simultaneous clear; clearing error does not clear an unresolved fault. |
0x10 IRQ_ENABLE / 0x14 IRQ_STATUS | bits0/1/2 correspond to done/error/aborted; enable RW, pending W1C and hardware-set dominant. A pending bit retains a cause, not the number of events. |
0x18 ACCEPTED / 0x1C DELIVERED / 0x20 STALLS | RO 32-bit operation snapshots, published together after drain and DP acknowledgement; accepted/delivered count IO handshakes; STALLS counts output valid&&!ready IO cycles. |
0x24 CE / 0x28 UE / 0x2C DISCARDED | RO aligned final snapshots. CE/UE count delivered beats carrying the respective flag, once per output handshake, not all physical faults or storage-read events. DISCARDED counts accepted input owners cancelled by coordinated reset. IO-owned accounting survives local DP/interface flush. |
0x30 PACKETS | RW count 1..16, reset 1; busy writes and out-of-range values return SLVERR. Frozen with COEFF at START. |
Each command field is write-only. An accepted write becomes one internal pulse, committed on one edge; the FSM decides whether to accept it.
// snippet: command acceptance is a one-cycle internal event
assign abort_accept = abort_pulse && !recover_pulse && busy_q;
assign start_accept = start_pulse && !abort_pulse && !recover_pulse && !busy_q &&
enable_q && recovery_ready && config_valid;
assign recover_accept = recover_pulse && !start_pulse && !abort_pulse &&
fault_q && admission_closed && cancellation_complete &&
peer_clock_qualified;
assign irq_o = |(irq_pending_q & irq_enable_q);The FSM owns operation lifetime. The bus adapter never reaches into datapath state.
Pulses are committed operations. They come pre-edge from a one-shot adapter, not as levels held through APB wait states or AXI backpressure.
The response reports ownership, not completion. OKAY or SLVERR says whether the command was accepted; status and IRQ report completion later. A posted response must not claim success before rejection is decided.
Read each arrow as one committed event. STATUS.busy is high in every state except IDLE.
LAUNCH exists because stream acceptance may begin only after the datapath has the snapshot.
DRAINING finishes the open packet and every accepted beat; busy clears only after drain and the final counter return.
FAULTED is left only through RECOVERING, and a failed barrier returns there.
Every row is decided at the commit edge. Combinations not listed are not legal commands.
Command / state at commit edge | Response and action |
|---|---|
START idle, enabled, configured, recovered | OKAY; capture pre-edge COEFF/PACKETS into operation snapshot, allocate operation ID, set busy, clear snapshot-valid, hold snapshot until DP handshake acknowledges it; stream acceptance begins only then |
START busy, disabled, invalid or not recovered | SLVERR; no launch, no snapshot change; latch command-error cause without cancelling existing work |
ABORT busy | OKAY; latch abort_requested once, stop new packet ownership, finish any open packet and drain; repeated ABORT is idempotent; busy clears only after drain and final counter return |
ABORT idle | OKAY no-op; no new completion interrupt |
START and ABORT in one committed write | ABORT wins; no start snapshot or new operation ID. Busy: graceful abort; idle: no-op. Response OKAY under this explicit policy |
RECOVER alone, fault latched and admission closed | OKAY only if old owners are already delivered/cancelled, shared cancellation is complete and peer clock health is qualified. Start a fresh supervisor flush/release barrier; bus OKAY acknowledges this request, not recovery completion |
RECOVER while peer stopped, cancellation incomplete or no fault | SLVERR; remain closed/faulted, do not invent peer acknowledgement or discard an offered beat |
RECOVER combined with START or ABORT | SLVERR; no command action or new snapshot. This invalid combination is separate from the legal START+ABORT priority above |
COEFF/PACKETS/enable configuration while busy | SLVERR, no change; a STATUS/IRQ W1C remains legal and cannot restore recovery readiness |
The trace below follows one operation: idle COEFF = 0x4000, START at C0, a COEFF = 0x2000 write at C1, DP acknowledgement at C4, and START+ABORT in one write at C5.
Each slot shows the values just before edge C0 to C6, so a pulse in slot k is what edge Ck commits. state: 0 IDLE, 1 LAUNCH, 2 BUSY, 3 DRAINING.
C0: START commits while idle. The snapshot takes 0x4000 and state becomes 1 after the edge.
C1: the COEFF write commits while busy. It gets SLVERR, so coeff_q stays 4000 in every later slot.
C4: the DP acknowledgement (not drawn) commits; state becomes 2 and the first stream beat uses the 0x4000 snapshot.
C5: START and ABORT arrive in one write. ABORT wins: state 3 (drain), no second launch and no new snapshot.
A later idle write of 0x2000 affects only the next accepted START. Same-edge hardware status set beats W1C, so a newly completed cause stays pending.
RECOVER is the software-visible retry input to the always-on supervisor. It is accepted only from FAULTED with admission closed.
cancellation_complete means archived old-owner retirement and the shared interface-reset acknowledgement, not empty flags alone.
peer_clock_qualified is approved clock-health status, not one stale alive bit.
During the barrier, busy/fault containment stays in force.
On success: clear the active fault/busy state, set recovery_ready, keep old error/IRQ/accounting records and invalidate the old operation. Nothing launches automatically.
After success: software reads status, clears sticky causes as needed, then issues a separate START.
On failure: the block stays faulted and closed and needs another eligible RECOVER.
Stage 3 receives accepted start and abort pulses, a stable configuration snapshot, status events and counters. No AXI-Lite or APB channel signal crosses into the streaming datapath.
Accepted, delivered, stall, flagged-delivery and discard counts live in IO-owned state that survives local DP and stream-link recovery.
DP counter snapshots are separately identified diagnostic fields, not replacements for IO handshakes.
Final publication waits for processing/drain acknowledgement; a stopped peer leaves snapshot-valid low.
A whole-system POR is a new external session, outside the retained local-reset epoch contract.
A command is an event. Storing it risks retriggering or requiring software to clear it; the CSR converts an accepted write into one internal cycle.