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>
9.1 KiB
Wave 2.5 Mini-Plan: Memory-Backed DMAC Payload
This document defines the consolidation step between Wave 2's
programmable BGCOLOR via DMA/GIF proof and later expansion into wider DMAC,
GIF, and EE-side behavior.
Goal:
- retire the biggest remaining Wave 2 shortcut,
- make
MADRreal instead of trace-only, - keep the current Milestone A+ proof intact,
- improve ownership boundaries before expanding into SIF/IOP or wider GIF work.
Working milestone name:
memory-backed BGCOLOR via DMA/GIF
That means:
- DMAC channel 2 is programmed with a real source address,
- DMAC fetches payload from an addressable memory block,
- GIF receives the fetched payload,
- GS updates
BGCOLOR, - platform video reflects the new color,
- traces show the fetch path as well as the transfer path.
Why this goes before SIF/IOP
The current Wave 2 path is structurally good but still has one major artificial seam:
- the testbench injects payload directly into DMAC.
Before opening the EE↔IOP front, the design benefits more from tightening that EE-side ownership seam than from starting a second subsystem family.
This step:
- makes
MADRmeaningful, - introduces a real read-master relationship,
- prepares the ground for multi-beat transfers,
- keeps the work inside the already-active DMAC/GIF/GS lane.
Deliverables
The first Wave 2.5 pass should land:
rtl/memory/ee_ram_stub.sv- an updated
rtl/dmac/dmac_reg_stub.svwith a memory-read master port - an updated
sim/tb/integration/tb_bgcolor_via_dma.sv - any trace-schema refinements needed for DMAC fetch visibility
Makefile/sim/README.mdupdates if the run flow changes
Ownership decision: memory source shape
Recommendation:
- add a new
rtl/memory/ee_ram_stub.sv
Do not:
- extend
bios_rom_stubinto a read-write block, - add a DMAC-private payload RAM that lives inside
rtl/dmac/.
Why ee_ram_stub.sv
This is the cleanest ownership boundary for future growth:
- memory remains owned by the memory subsystem,
- DMAC becomes a memory client, not a memory owner,
ee_memory_map_stubcan grow toward multiple mapped regions without refactoring a DMAC-private storage hack back out later.
It also tells the right architectural story:
- BIOS is ROM,
- EE RAM is RAM,
- DMAC reads from memory through an explicit master interface.
ee_ram_stub.sv exact scope
Status target:
- tiny, addressable, read-first memory block for DMAC-backed tests
Owns in this phase
- a small read/write memory array,
- byte-addressed external interface,
- one-cycle read latency,
- optional simple write port for testbench preload,
- trace events for read and write activity if useful.
Explicit non-goals
- full 32 MiB EE RAM sizing,
- cache behavior,
- arbitration among multiple masters,
- full integration into the EE-visible memory map,
- timing fidelity beyond a simple deterministic latency.
Recommended size
Use something small but qword-friendly:
- default
SIZE_BYTES = 4 KiBor16 KiB
That is large enough for:
- multiple DMAC packets,
- future directed tests,
- no simulator pain.
Recommended interface
Keep it simple and aligned with the current stub ecosystem.
Suggested external interface:
- read request:
rd_enrd_addrrd_datard_valid
- write request:
wr_enwr_addrwr_datawr_be
Recommended data width:
128-bitdata path for read and write
Reason:
- aligns with current DMAC qword semantics,
- avoids extra packing/unpacking for the first memory-backed DMA proof,
- keeps the first step focused on ownership, not bus-width adaptation.
Addressing:
- qword-aligned externally
- low address bits ignored as needed
Preload mechanism
For the first implementation, allow either:
- testbench writes through the normal write port, or
- optional
$readmemhpreload file parameter
Recommendation:
- use the normal write port in the integration testbench first
Why:
- makes the preload path explicit and testable,
- avoids adding file-format work unless it becomes useful later.
DMAC fetch interface
The direct payload input should be retired from the integrated proof path.
Recommended new DMAC-side interface:
mem_rd_enmem_rd_addrmem_rd_datamem_rd_valid
That is enough for the first qword-fetch path.
Ownership and routing
For Wave 2.5:
- connect
dmac_reg_stubdirectly toee_ram_stub
Do not route the fetch through ee_memory_map_stub yet.
Reason:
ee_memory_map_stubcurrently only decodes BIOS and unmapped space,- forcing DMAC through it now would either require a larger memory-map rewrite or add a fake bypass anyway,
- direct connection still preserves the key ownership boundary: DMAC is a memory client and RAM is a memory block.
This should be documented as a temporary topology, not the final architecture.
MADR behavior in Wave 2.5
MADR stops being "recorded but ignored" and becomes the actual qword fetch
source address.
Recommended behavior:
- on
DMA_START, latchMADR - issue one or more qword reads starting at that address
- increment by
16bytes per beat
Trace consequence:
- DMAC trace should show the fetch source address clearly
- memory trace should show the corresponding RAM read(s)
QWC scope
Recommendation:
- support
QWC == 1in the first Wave 2.5 implementation - make the internal design compatible with
QWC > 1 - do not require multi-beat support for initial signoff
Reason:
- the point of 2.5 is memory-backed ownership, not throughput expansion
QWC > 1becomes more valuable once the fetch path is stable
Suggested follow-up:
- call
QWC > 1aWave 2.6orWave 3aextension unless it falls out naturally with low risk
Trace schema additions / refinements
Wave 2 already added:
EV_DMA_CFGEV_DMA_STARTEV_DMA_BEATEV_DMA_DONEEV_GIFTAGEV_GS_WRITE
Wave 2.5 does not require new event names if the payloads are refined well.
Recommended refinement:
DMAC EV_DMA_START
arg0 = channelarg1 = qwcarg2 = MADRarg3 = path id
This is more useful now that MADR matters.
DMAC EV_DMA_BEAT
arg0 = channelarg1 = beat indexarg2 = source address for this beatarg3 = remaining count
MEM READ from ee_ram_stub
Reuse existing MEM READ event shape:
arg0 = addressarg1 = low data summary or full qword-low summaryarg2 = master idarg3 = region id
Suggested ids for this phase:
- master id:
1 = DMAC - region id:
1 = EE_RAM
This lets traces show the DMAC→RAM→GIF ownership chain without inventing a new event family.
dmac_reg_stub internal changes
Recommended state flow:
IDLEFETCH_WAITACTIVE_SENDDONE
Suggested behavior:
- CPU/testbench writes
MADR,QWC,CHCR DMA_START- issue memory read at
MADR + beat_index * 16 - wait for
mem_rd_valid - present fetched qword to GIF
- on accept, increment beat count
- if beats remain, fetch next qword
- otherwise
DMA_DONE
Guardrail
Do not keep both the direct payload port and the memory-fetch path active in the integrated milestone as equal options.
If a compatibility/debug path is retained temporarily, it must be:
- clearly labeled as deprecated,
- unused by the main integration testbench.
Integration testbench migration
tb_bgcolor_via_dma.sv should stop driving the direct payload port and instead:
- reset the chain
- preload one qword into
ee_ram_stubthrough its write port - program
MADRto that location - program
QWC = 1 - trigger
CHCR.start - wait for
DMA_DONE - verify the same visible color-change outcome as before
Payload preload mechanism
Recommended first mechanism:
- direct writes into
ee_ram_stubthrough its write port from the testbench
This keeps the setup explicit and simple.
Integrated testbench pass criteria
Keep the current Wave 2 pass criteria stable, with the following additions:
- at least one
MEM READfromee_ram_stubattributable to DMAC DMA_STARTtrace includes a meaningfulMADRDMA_BEATsource-address trace lines match the programmedMADR
Suggested summary line:
[tb_bgcolor_via_dma] mem_reads=1 dma_start=1 dma_done=1 giftag=1 gs_bgcolor=1 bg=(ff,00,00) errors=0
Recommended implementation order
- add
ee_ram_stub.sv - update
dmac_reg_stub.svto fetch from memory - update
tb_bgcolor_via_dma.svto preload RAM and driveMADR - adjust trace payload details if needed
- wire docs / Makefile updates
Guardrails
- Do not route DMAC through
ee_memory_map_stubyet unless Claude wants to deliberately broaden scope. - Do not broaden to
QWC > 1unless it falls out naturally. - Do not let the preload mechanism become a hidden debug-only side channel.
- Do not erase the existing Wave 2 trace visibility while refactoring the fetch path.
Exit criteria for mini-plan acceptance
This mini-plan is accepted when Claude can implement:
- a new
ee_ram_stub.sv, - a memory-master version of
dmac_reg_stub, - an updated
tb_bgcolor_via_dma.svthat preloads RAM rather than driving the direct payload port, - while preserving the visible Milestone A+ outcome and adding trace-visible
proof that
MADRis the actual payload source.