ec82764bef
RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression (272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps, and all dump-derived textures/traces) is excluded via .gitignore and stays local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
322 lines
9.1 KiB
Markdown
322 lines
9.1 KiB
Markdown
# Wave 2.6 Mini-Plan: Multi-Beat DMAC to GIF to GS
|
|
|
|
This document defines the next consolidation step after the completed
|
|
Wave 2.5 `memory-backed BGCOLOR via DMA/GIF` milestone.
|
|
|
|
Goal:
|
|
|
|
- prove the DMAC/GIF path across more than one qword,
|
|
- validate address stepping from `MADR`,
|
|
- validate end-of-packet signaling on the final beat only,
|
|
- preserve the visible Milestone A+ outcome through the existing GS/platform
|
|
chain,
|
|
- do all of that without expanding packet-format scope prematurely.
|
|
|
|
Working milestone name:
|
|
|
|
`multi-beat BGCOLOR via DMA/GIF`
|
|
|
|
That means:
|
|
|
|
- DMAC channel 2 is programmed with `QWC = 2`,
|
|
- DMAC performs two memory-backed qword fetches,
|
|
- GIF accepts two qwords as two standalone register-write packets,
|
|
- GS observes two consecutive writes,
|
|
- platform video reflects the final written color,
|
|
- traces prove beat ordering, source-address stepping, and `gif_tag_last`
|
|
behavior.
|
|
|
|
## Why this goes before memory-map routing
|
|
|
|
Wave 2.5 established the right ownership seam:
|
|
|
|
- DMAC is now a memory client,
|
|
- `MADR` is real,
|
|
- RAM is owned by the memory subsystem,
|
|
- the graphics-visible path is intact.
|
|
|
|
The next most valuable risk to retire is not topology, it is transfer shape.
|
|
|
|
Multi-beat transfer support is the first place where subtle bugs are likely to
|
|
hide:
|
|
|
|
- off-by-one address stepping,
|
|
- incorrect remaining-count bookkeeping,
|
|
- `gif_tag_last` asserted too early or too late,
|
|
- state-machine stalls between fetch and send,
|
|
- final-color behavior when multiple writes land back-to-back.
|
|
|
|
Once that is stable, routing the same traffic through `ee_memory_map_stub`
|
|
becomes a narrower structural refactor instead of a behavioral and structural
|
|
change combined.
|
|
|
|
## Deliverables
|
|
|
|
The first Wave 2.6 pass should land:
|
|
|
|
1. an updated `rtl/dmac/dmac_reg_stub.sv`
|
|
2. a small comment/README update in `rtl/gif_gs/gif_path_stub.sv` if needed to
|
|
make multi-beat behavior explicit
|
|
3. an updated `sim/tb/integration/tb_bgcolor_via_dma.sv`
|
|
4. `sim/Makefile` updates only if the run flow changes
|
|
5. optional README note if the integration-TB expectations materially change
|
|
|
|
No new subsystem contracts or decision records are required for this step.
|
|
|
|
## Scope boundary
|
|
|
|
This plan is intentionally narrow.
|
|
|
|
It does not attempt to implement:
|
|
|
|
- real GIFtag decode,
|
|
- packed register lists,
|
|
- chain mode,
|
|
- linked-list DMA,
|
|
- path arbitration,
|
|
- full EE memory-map routing,
|
|
- any IOP or SIF behavior,
|
|
- GS drawing primitives or VRAM.
|
|
|
|
The purpose is to prove:
|
|
|
|
`QWC > 1` works correctly on the already-established temporary topology.
|
|
|
|
## Transfer length scope
|
|
|
|
Recommendation:
|
|
|
|
- sign off this phase on `QWC = 2`
|
|
|
|
Do not require `QWC = 4` for first signoff.
|
|
|
|
### Why two qwords is enough
|
|
|
|
Two beats cover every new behavior category this phase is meant to validate:
|
|
|
|
- beat 0 source address = `MADR`
|
|
- beat 1 source address = `MADR + 16`
|
|
- beat 0 has `gif_tag_last = 0`
|
|
- beat 1 has `gif_tag_last = 1`
|
|
- the transfer must remain active across an intermediate beat
|
|
- the final beat must retire cleanly into `DMA_DONE`
|
|
|
|
Four beats would add more distance but not a new category of behavior.
|
|
If the implementation naturally supports `QWC > 2`, that is welcome, but the
|
|
required directed proof for this phase should stay at `2`.
|
|
|
|
## Payload semantics
|
|
|
|
Recommendation:
|
|
|
|
- keep the current project-local packet model:
|
|
- one qword = one standalone GS register write
|
|
- use the same destination register twice:
|
|
- `BGCOLOR` on beat 0
|
|
- `BGCOLOR` again on beat 1 with a different RGB value
|
|
|
|
This is the simplest high-signal option.
|
|
|
|
### Why this goes over the alternatives
|
|
|
|
Using one register twice keeps the focus on transport, not packet-model growth.
|
|
|
|
It gives us:
|
|
|
|
- two visible GS-side events,
|
|
- two visible GIF-side accepts,
|
|
- a deterministic final platform-visible color,
|
|
- no need to invent a tag-qword/data-qword pairing before we are ready to
|
|
tackle real GIFtag structure.
|
|
|
|
Using two different GS registers would blur the phase boundary by making the
|
|
test partly about GS register-surface breadth. That coverage already exists in
|
|
the single-register-path and can expand later when GIFtag work begins.
|
|
|
|
### Recommended concrete payload
|
|
|
|
Preload two qwords at consecutive addresses:
|
|
|
|
- beat 0 packet:
|
|
- register = `BGCOLOR`
|
|
- value = a clearly non-final color, for example blue
|
|
- beat 1 packet:
|
|
- register = `BGCOLOR`
|
|
- value = the intended final visible color, for example red
|
|
|
|
That gives a clean final assertion:
|
|
|
|
- two `EV_BGCOLOR` events occurred,
|
|
- final `bg_*` equals the second payload.
|
|
|
|
## `dmac_reg_stub` exact scope
|
|
|
|
Status target:
|
|
|
|
- the current state machine becomes genuinely multi-beat for the signoff case
|
|
|
|
### Owns in this phase
|
|
|
|
- repeated qword fetches based on `QWC`
|
|
- source-address stepping by `16` bytes per beat
|
|
- repeated send/accept handshakes into `gif_path_stub`
|
|
- correct `gif_tag_last` behavior on the final beat only
|
|
- transfer completion only after the final beat is accepted
|
|
|
|
### Explicit non-goals
|
|
|
|
- channel arbitration
|
|
- chain-mode `TADR` behavior
|
|
- interrupt-driven completion semantics
|
|
- routing through `ee_memory_map_stub`
|
|
|
|
### Required behavioral rules
|
|
|
|
For `QWC = 2`:
|
|
|
|
1. `DMA_START.arg2` reports the latched `MADR`
|
|
2. beat 0 fetch/read uses `MADR`
|
|
3. beat 1 fetch/read uses `MADR + 16`
|
|
4. beat 0 emits `gif_tag_last = 0`
|
|
5. beat 1 emits `gif_tag_last = 1`
|
|
6. `DMA_DONE` occurs only after beat 1 is accepted downstream
|
|
|
|
Implementation note:
|
|
|
|
- if the RTL naturally supports arbitrary `QWC > 0`, that is fine
|
|
- the TB and acceptance criteria only need to lock `QWC = 2`
|
|
|
|
## `gif_path_stub` behavior in Wave 2.6
|
|
|
|
Recommendation:
|
|
|
|
- keep `gif_path_stub` stateless with respect to packet framing
|
|
- keep the current project-local interpretation:
|
|
- every accepted qword is one standalone register write
|
|
- preserve `in_last` as trace-visible metadata only
|
|
|
|
This means no new internal "tag phase vs. data phase" state is added yet.
|
|
|
|
### Why this is the right boundary
|
|
|
|
Wave 2.6 is about transfer length, not packet-model realism.
|
|
|
|
If we introduce tag/data pairing now, we turn one scoped extension into two:
|
|
|
|
- multi-beat DMA sequencing
|
|
- a new packet parser contract
|
|
|
|
That is exactly the kind of scope expansion we have been avoiding well so far.
|
|
|
|
## Trace policy
|
|
|
|
No new event names are required for Wave 2.6.
|
|
|
|
Reuse the current vocabulary:
|
|
|
|
- `EV_DMA_CFG`
|
|
- `EV_DMA_START`
|
|
- `EV_DMA_BEAT`
|
|
- `EV_DMA_DONE`
|
|
- `EV_GIFTAG`
|
|
- `EV_BGCOLOR`
|
|
|
|
### Required trace-visible facts
|
|
|
|
The Wave 2.6 proof must make the following visible in traces:
|
|
|
|
- two DMAC-backed RAM reads from consecutive qword addresses
|
|
- two `EV_DMA_BEAT` events with:
|
|
- beat index `0`, source address `MADR`
|
|
- beat index `1`, source address `MADR + 16`
|
|
- two `EV_GIFTAG` events with:
|
|
- `flags[0] = 0` on beat 0
|
|
- `flags[0] = 1` on beat 1
|
|
- two GS-side `EV_BGCOLOR` events
|
|
- one `EV_DMA_DONE` after the second beat completes
|
|
|
|
Cycle-perfect alignment between subsystems is not the primary comparison rule.
|
|
Order and causality are the primary rules:
|
|
|
|
- read for beat 0 precedes send for beat 0
|
|
- read for beat 1 precedes send for beat 1
|
|
- done follows final acceptance
|
|
|
|
## Integration testbench shape
|
|
|
|
Recommendation:
|
|
|
|
- update the existing `sim/tb/integration/tb_bgcolor_via_dma.sv`
|
|
|
|
Do not create a second near-duplicate integration TB for first signoff.
|
|
|
|
### Why update instead of fork
|
|
|
|
Wave 2.6 is a strict extension of the current Milestone A+ proof:
|
|
|
|
- same subsystem chain
|
|
- same top-level outcome
|
|
- same trace sinks
|
|
|
|
Keeping one canonical integration TB reduces maintenance churn and makes the
|
|
current path's expectations clearer.
|
|
|
|
If later we want a minimal single-beat smoke test, that can be added as a
|
|
focused DMAC unit TB rather than cloning the whole platform chain.
|
|
|
|
### TB preload shape
|
|
|
|
The TB should preload two qwords into `ee_ram_stub`:
|
|
|
|
- first qword at `MADR`
|
|
- second qword at `MADR + 16`
|
|
|
|
Suggested values:
|
|
|
|
- beat 0: `BGCOLOR = blue`
|
|
- beat 1: `BGCOLOR = red`
|
|
|
|
### TB pass criteria
|
|
|
|
At minimum, the updated integration TB should require:
|
|
|
|
1. `mem_reads_dmac >= 2`
|
|
2. `dma_cfg_count >= 3`
|
|
3. `dma_start_count == 1`
|
|
4. `dma_beat_count == 2`
|
|
5. `dma_done_count == 1`
|
|
6. `giftag_count == 2`
|
|
7. `gs_bgcolor_count == 2`
|
|
8. first observed beat source address = `MADR`
|
|
9. second observed beat source address = `MADR + 16`
|
|
10. first GIF end-of-packet flag = `0`
|
|
11. second GIF end-of-packet flag = `1`
|
|
12. final `bg_*` equals the second payload color
|
|
13. platform still renders active pixels correctly after transfer completion
|
|
|
|
Optional but useful:
|
|
|
|
- count post-transfer frames as before
|
|
- assert that `DMA_DONE` is observed only after the second `EV_GIFTAG`
|
|
|
|
## Exit criteria
|
|
|
|
Wave 2.6 is complete when all of the following are true:
|
|
|
|
- `dmac_reg_stub` performs a two-beat memory-backed transfer
|
|
- `MADR` stepping is trace-visible and correct
|
|
- `gif_tag_last` is false on beat 0 and true on beat 1
|
|
- GIF accepts two qwords without new packet-state machinery
|
|
- GS observes two BGCOLOR writes
|
|
- platform video settles to the second color
|
|
- `make full_checks` remains green
|
|
|
|
## Next step after Wave 2.6
|
|
|
|
If this passes cleanly, the next recommended step is:
|
|
|
|
- route DMAC through `ee_memory_map_stub`
|
|
|
|
That is the right moment for topology cleanup, because the transfer behavior
|
|
itself will already be stable and trace-proven.
|