# Wave 2 Mini-Plan: DMAC Channel 2 to GIF to BGCOLOR This document defines the first Wave 2 implementation target after the completed Wave 1 milestones and the generated-golden Phase 1 harness. The target is deliberately narrow: - establish DMAC as real transfer ownership, not just register plumbing, - establish GIF as the first programmatic ingress into the GS path, - produce a visible result through the existing Milestone A video chain. Working milestone name: `programmable BGCOLOR via DMA/GIF` That means: - software- or testbench-visible programming of DMAC channel 2 intent, - a minimal packet path into GIF, - a narrow GIF-to-GS handoff that updates `gs_stub` BGCOLOR, - visible raster output change through `platform_video_stub`, - end-to-end traces proving each stage participated. ## Why this path goes first This is the best next Wave 2 target because it: - starts from the DMAC contract, which is central PS2 structure, - keeps the first new ingress path graphics-visible, - extends Milestone A instead of redoing it, - avoids pulling in IOP/SIF policy too early, - sets up a natural bridge into later VIF/VU and broader GIF work. ## Deliverables The first Wave 2 pass should land: 1. `rtl/dmac/dmac_reg_stub.sv` 2. `rtl/gif_gs/gif_path_stub.sv` 3. one integrated testbench: - `sim/tb/integration/tb_bgcolor_via_dma.sv` 4. trace vocabulary additions in: - `rtl/debug/trace_pkg.sv` 5. a short README or note in the integration TB directory if one does not already exist ## Scope boundary This plan is not trying to implement: - generic EE main RAM, - full DMAC arbitration, - full GIF decoding, - any drawing primitive, - GS VRAM, - VIF/VU, - SIF, - IOP interaction. The point is to create the smallest correct-shaped programmatic path: `channel 2 intent -> minimal DMA payload -> minimal GIF packet -> gs_stub BGCOLOR` ## `dmac_reg_stub` exact scope Status target: - channel-2-focused, not a pretend full DMAC ### Owns in this phase - selected DMAC register shell for channel 2, - channel state machine for a single programmed transfer, - transfer-start / transfer-active / transfer-done transitions, - narrow payload handoff into `gif_path_stub`, - trace events for register writes and transfer lifecycle. ### Explicit non-goals - multi-channel fairness or arbitration, - linked-list / chain mode completeness, - stall/ring semantics, - interrupt-controller integration beyond trace-visible placeholders, - memory-backed payload fetch from real EE RAM. ### First-pass data source For the first integrated proof, allow a testbench-provided or locally-loaded payload path rather than requiring real main RAM first. Acceptable phase-1 shapes: - a tiny internal payload register/FIFO loaded through a narrow debug/test port, - or a direct payload input interface used only by the integration testbench. Not acceptable: - a `dmac_reg_stub` that stops at register writes and never emits payload. ### Recommended channel-2 register surface Implement only what is needed to express one narrow transfer cleanly. Suggested first surface: - `CHCR` for channel 2 - start bit / direction / mode subset as needed - `MADR` - recorded for trace and future upgrade path - `QWC` - transfer length in 16-byte units - optional `TADR` - only if the implementation wants to reserve chain-mode shape early Suggested interpretation for first pass: - one direct transfer mode only - `QWC == 1` is sufficient for the first visible proof - `MADR` may be recorded and traced even if the payload is not yet fetched from real memory ### Minimal state machine Recommended states: - `IDLE` - `ARMED` - `ACTIVE` - `DONE` Behavior: - CPU/testbench writes register values - start condition on `CHCR` - one payload issued toward `gif_path_stub` - wait for `gif_path_stub` accept/done handshake - transition to `DONE` - optionally clear busy/start-visible state and return to `IDLE` ### `dmac_reg_stub` acceptance criteria `dmac_reg_stub` is not "done" when registers can be written. It is done for this phase when: 1. channel 2 can be programmed into a single transfer sequence, 2. it emits a payload/handshake toward `gif_path_stub`, 3. traces show start, active transfer, and done, 4. the integrated testbench proves that this sequence ultimately changes `gs_stub` BGCOLOR. ## `gif_path_stub` exact scope Status target: - minimal GIF ingress and decode sufficient for BGCOLOR update only ### Owns in this phase - accepting one narrow DMA-fed packet stream, - extracting just enough tag/selection information to identify the path, - decoding only the BGCOLOR-relevant payload form, - forwarding a GS privileged-register-style write into `gs_stub`, - trace events for GIF tag and GS-write handoff. ### Explicit non-goals - PATH arbitration completeness, - packed register lists beyond what BGCOLOR requires, - image transfer paths, - primitive drawing, - texture or VRAM-visible behavior. ### Recommended first packet shape Keep the first proof simple and explicit. Suggested approach: - a synthetic single-packet format representing: - PATH source = channel 2 / GIF - destination register = BGCOLOR - payload = 24-bit RGB value This can be encoded as either: - a tiny project-local "GIF-like" packet for the first integrated proof, or - a very narrow real GIFtag/register pair if Claude wants to stay closer to the real packet model immediately. My recommendation: - use a narrow real-looking shape, but only if it stays easy to trace - otherwise use a project-local packet format and document it clearly as a temporary ingress format ### PATH selection For this phase, hard-scope the path to one source: - PATH = channel 2 / DMAC GIF path No arbitration needed yet. Just make the trace name the source explicitly so future work can preserve the boundary. ### `gif_path_stub` acceptance criteria 1. accepts one payload from `dmac_reg_stub` 2. emits a trace that identifies a GIF-side handoff/tag 3. issues one BGCOLOR update into `gs_stub` 4. integrated testbench sees the new color on the platform video side ## Trace vocabulary additions Wave 2 needs trace events that express transfer ownership and GIF ingress without overfitting future behavior. Recommended additions to `trace_pkg.sv`: - `EV_DMA_CFG` - `EV_DMA_START` - `EV_DMA_BEAT` - `EV_DMA_DONE` - `EV_GIFTAG` - `EV_GS_WRITE` These names keep the event model readable while leaving room for later detail. ### Recommended payload schemas #### `DMAC EV_DMA_CFG` - `arg0 = channel` - `arg1 = CHCR subset` - `arg2 = MADR` - `arg3 = QWC` - `flags = optional mode bits` #### `DMAC EV_DMA_START` - `arg0 = channel` - `arg1 = qwc` - `arg2 = payload words/beats planned` - `arg3 = path id` #### `DMAC EV_DMA_BEAT` - `arg0 = channel` - `arg1 = beat index` - `arg2 = low payload word or packet id` - `arg3 = remaining count` For wide payloads, trace summary over full raw data is acceptable in this phase. #### `DMAC EV_DMA_DONE` - `arg0 = channel` - `arg1 = beats transferred` - `arg2 = completion code` - `arg3 = path id` #### `GIF EV_GIFTAG` - `arg0 = path source` - `arg1 = tag summary or local packet type` - `arg2 = register target` - `arg3 = payload summary` #### `GS EV_GS_WRITE` - `arg0 = register offset` - `arg1 = write value` - `arg2 = source id` - `arg3 = reserved` ### Trace policy note Do not delete or overload `EV_MODE` / `EV_BGCOLOR`. Wave 2 should add ingress/transfer visibility, not destroy the simple Wave 1 events that already make debugging easy. ## Integrated testbench shape Recommended file: - `sim/tb/integration/tb_bgcolor_via_dma.sv` This should be the first cross-subsystem Wave 2 harness. ### DUT chain - `dmac_reg_stub` - `gif_path_stub` - `gs_stub` - `platform_video_stub` - `trace_sink_stub` instances for at least: - DMAC - GIF - GS - PLAT ### Suggested stimulus model Use a fully controlled synthetic transfer first. Sequence: 1. reset chain 2. confirm default mid-grey frame behavior 3. configure channel 2 registers 4. provide one payload representing a BGCOLOR update 5. trigger transfer start 6. wait for transfer-done trace/event 7. confirm: - GIF saw a tag/payload - GS latched the new BGCOLOR - platform output changed on active pixels - frame event occurred after the color change ### Recommended checks - one `EV_DMA_CFG` - one `EV_DMA_START` - at least one `EV_DMA_BEAT` - one `EV_DMA_DONE` - one `EV_GIFTAG` - one GS-side write event (`EV_GS_WRITE` and/or `EV_BGCOLOR`) - visible raster color change during active pixels ### Pass criteria Suggested summary line: ```text [tb_bgcolor_via_dma] dma_start=1 dma_done=1 giftag=1 gs_write=1 frames=... errors=0 ``` A pass requires: - zero errors - at least one trace event from each stage - end-to-end visible color change ## Implementation order inside Wave 2 Recommended order: 1. extend `trace_pkg.sv` with Wave 2 events 2. implement `dmac_reg_stub` 3. implement `gif_path_stub` 4. add integration TB 5. wire `Makefile` target(s) 6. update `sim/README.md` Rationale: - event vocabulary first keeps instrumentation coherent - DMAC first preserves ownership - GIF second provides the first consumer - the integration TB defines success better than isolated unit benches here ## Interaction with existing milestones This work does not replace Wave 1 milestones. It creates a new intermediate milestone: `Milestone A+`: visible screen color change driven through DMAC/GIF ownership That is the right next visible proof before: - fuller EE work, - real memory-backed command fetch, - IOP/SIF bring-up. ## Guardrails - Do not let `dmac_reg_stub` become a dead-end register shell. - Do not let `gif_path_stub` accept direct testbench writes that bypass DMAC in the integrated proof. - Do not broaden to generic drawing before the BGCOLOR path is working. - Do not pull in IOP/SIF just to make Wave 2 feel larger. ## Exit criteria for mini-plan acceptance This mini-plan is accepted when Claude can implement: 1. a channel-2-focused `dmac_reg_stub`, 2. a narrow `gif_path_stub`, 3. one integrated DMA/GIF/BGCOLOR testbench, 4. with traces proving each stage, not just end-state color.