# Stub Module Plan This document translates the locked Phase 0 decisions and current subsystem contracts into an implementation-oriented stub plan. Goal: - start real code with the smallest set of modules that produce meaningful signal, - keep each stub aligned with a contract, - make Milestone A and Milestone B independently achievable, - avoid building "temporary" code that has no upgrade path. This is the handoff point from planning docs to first RTL. ## Planning anchors This plan is shaped by the following locked decisions: - posture: `staged subset on current hardware` - BIOS policy: `real BIOS plus narrow debug stubs` - golden references: `DobieStation` and `PCSX2` with role separation - first milestone: split into platform/video proof and EE/BIOS trace proof - trace format: common text envelope plus subsystem-specific payloads ## First implementation rule Every stub in this plan must have: - a matching contract under `docs/contracts/`, - an explicit success condition, - a trace output, - a stated replacement path. If a stub participates in BIOS behavior, it must also be tracked with: - owner, - scope boundary, - removal condition. ## Immediate deliverables The first RTL wave should target these deliverables: 1. `Milestone A`: visible GS-stub test pattern through the platform video path. 2. `Milestone B`: EE BIOS fetch and early trace agreement against DobieStation. 3. A minimal trace pipeline that both RTL stubs and golden-reference tooling can emit. ## Initial trace format choice Decision `0000` deliberately left room for either key/value text or stable columns. For the first stub wave, choose `stable columns`. Initial common envelope: ```text cycle subsystem event arg0 arg1 arg2 arg3 flags ``` Field intent: - `cycle`: simulation cycle or monotonic step count - `subsystem`: short id such as `EE`, `MEM`, `GS`, `SIF`, `INTC` - `event`: stable event code such as `IFETCH`, `READ`, `WRITE`, `IRQ`, `MODE` - `arg0..arg3`: subsystem-defined fields documented per stub - `flags`: compact auxiliary bits or `-` when unused Rules: - whitespace-delimited ASCII text - one event per line - comment/header lines start with `#` - each trace file starts with a header describing the subsystem schema This gives the project a simple diffable format now without closing the door on future binary logging. ## Wave 1: foundation stubs These are the first modules worth implementing. ### 1. `rtl/debug/trace_sink_stub.sv` Purpose: - centralize text-trace event formatting at the testbench boundary, - avoid each stub inventing its own ad-hoc logging path. Owns: - accepting normalized event records from stubs, - emitting them in the shared column format for simulation. Success condition: - testbench can capture deterministic trace lines from multiple subsystems. Replacement path: - grows into the normal simulation trace path; not expected to be thrown away. ### 2. `rtl/platform/platform_video_stub.sv` Purpose: - create the smallest retroDE-facing video path needed for Milestone A. Owns: - accepting a simple pixel or test-pattern source from the GS stub, - adapting it into the platform-facing display signals used by the top level. Success condition: - stable visible output on the chosen platform path in simulation, and later on hardware. Replacement path: - remains as the platform adaptation layer while the upstream source changes from GS stub output to fuller GS/PCRTC output. ### 3. `rtl/gif_gs/gs_stub.sv` Purpose: - provide Milestone A without waiting for DMAC, GIF, or full GS behavior. Minimum scope: - accept direct privileged register writes from a local test harness or top-level stub control path, - implement `BGCOLOR` and the minimum mode/state needed to drive a visible pattern, - emit trace events on display-mode and color changes. Success condition: - a fixed or controllable color/test pattern appears through the platform video path and produces repeatable traces. Replacement path: - keep the register shell and extend inward toward fuller GS behavior. ### 4. `rtl/memory/bios_rom_stub.sv` Purpose: - give the EE stub a realistic instruction source for Milestone B. Minimum scope: - expose a BIOS window at the agreed address range, - back reads with either a user-supplied image path or a simulation fixture, - emit trace lines for fetch-visible ROM reads. Success condition: - instruction fetches from BIOS space return deterministic data. Replacement path: - should survive as the BIOS storage/mapping implementation even after the rest of the memory system becomes more complete. ### 5. `rtl/memory/ee_memory_map_stub.sv` Purpose: - provide only enough EE-visible address decoding for early BIOS fetch progress. Minimum scope: - decode BIOS ROM window, - decode unmapped space into deterministic fault/idle responses, - optionally reserve placeholders for RAM and EE I/O windows, - emit `READ`, `WRITE`, and `UNMAPPED` traces. Success condition: - the EE stub can request BIOS fetches and get predictable answers. Replacement path: - grows into the broader memory-map and arbitration layer defined by `memory.md`. ### 6. `rtl/intc/intc_stub.sv` Purpose: - keep interrupt ownership explicit from the start, - support early directed tests even before real interrupt sources exist. Minimum scope: - register-visible status/mask shell, - synthetic interrupt injection path for tests, - trace on assert/mask/clear. Success condition: - directed tests can prove the EE-side interrupt-visible shell behaves deterministically. Replacement path: - extend source inputs and timing behavior without changing ownership. ### 7. `rtl/ee/ee_fetch_stub.sv` Purpose: - achieve Milestone B without a full R5900 implementation. Minimum scope: - reset into BIOS fetch address space, - generate sequential instruction fetch requests, - maintain a minimal PC, - log fetch trace lines in the common envelope. Non-goals for this wave: - full decode, - exceptions beyond deterministic fault handling, - FPU/MMI behavior, - instruction retirement fidelity. Success condition: - trace shows stable BIOS fetch progression for a chosen window of cycles. Replacement path: - replace with or wrap a fuller EE core while preserving the memory-facing and trace-facing interfaces where practical. ## Wave 2: bridging stubs These are the next modules after the foundation wave. ### 8. `rtl/dmac/dmac_reg_stub.sv` Purpose: - establish EE DMAC register ownership and traces before real transfers exist. Minimum scope: - register file for selected channels, - start/stop visibility, - channel-state traces, - no real data movement yet. Success condition: - directed tests can program DMAC-visible state and see deterministic events. ### 9. `rtl/gif_gs/gif_path_stub.sv` Purpose: - bridge the eventual gap between DMAC channel 2 and the GS stub. Minimum scope: - accept a minimal packet stream, - log GIF tags and path source, - optionally forward only a very narrow subset into the GS stub. Success condition: - a synthetic packet stream can be observed and, if enabled, drive a GS-stub state change. ### 10. `rtl/sif/sif_mailbox_stub.sv` Purpose: - establish EE<->IOP coordination points before full dual-CPU bring-up. Minimum scope: - mailbox/flag shell, - deterministic reads/writes, - trace on transitions. Success condition: - SIF directed tests can prove basic flag and mailbox visibility. ### 11. `rtl/iop/iop_boot_stub.sv` Purpose: - create a place for BIOS-side IOP boot sequencing behavior without forcing a full IOP implementation immediately. Minimum scope: - explicit stub-only progress markers, - optional fake acknowledgement path if needed for a narrowly-scoped BIOS step, - trace lines that make stub behavior unmistakable. Guardrail: - this stub must be tracked under the BIOS-stub policy with owner and removal condition. Success condition: - if used, it unlocks one clearly named early BIOS milestone and nothing more. ### 12. `rtl/peripherals/sio2_input_stub.sv` Purpose: - start the controller-facing story with a deterministic placeholder. Minimum scope: - device-present shell, - synthetic event injection for tests, - no attempt at full SIO2 transaction fidelity yet. Success condition: - testbench can prove the platform/input handoff path exists. ## Wave 3: first upgrade targets These are not the first stubs to write, but they are the first likely promotions from stub to semi-real implementation. - `ee_fetch_stub` -> fuller EE front-end or wrapped EE core - `ee_memory_map_stub` -> RAM plus wider I/O decode - `gs_stub` -> privileged-register shell plus simple draw/VRAM path - `dmac_reg_stub` -> one real functional channel, likely GIF-facing first - `sif_mailbox_stub` -> broader SIF-visible coordination ## Recommended implementation order 1. `trace_sink_stub` 2. `bios_rom_stub` 3. `ee_memory_map_stub` 4. `ee_fetch_stub` 5. `platform_video_stub` 6. `gs_stub` 7. `intc_stub` 8. `dmac_reg_stub` 9. `gif_path_stub` 10. `sif_mailbox_stub` 11. `iop_boot_stub` only if a specific milestone truly needs it 12. `sio2_input_stub` Why this order: - it gets Milestone B moving first with the smallest dependency stack, - it gets Milestone A moving in parallel without waiting for DMAC/GIF, - it avoids premature IOP complexity, - it keeps BIOS-policy-sensitive stubs later and narrower. ## Initial testbench plan The first stub wave should be paired with these testbenches: ### `sim/tb/ee/tb_ee_fetch_stub.sv` Checks: - reset PC, - BIOS-window fetches, - unmapped access handling, - trace line emission. ### `sim/tb/gif_gs/tb_gs_stub.sv` Checks: - direct register writes to `BGCOLOR`, - stable output state, - trace on mode/color changes. ### `sim/tb/intc/tb_intc_stub.sv` Checks: - mask/set/clear behavior, - synthetic interrupt injection, - trace on state transitions. ## Initial trace schemas The first wave should document these event schemas in the testbench headers or adjacent notes: - `EE IFETCH`: `arg0=pc arg1=data arg2=resp_kind arg3=-` - `MEM READ`: `arg0=addr arg1=data arg2=master arg3=region` - `MEM UNMAPPED`: `arg0=addr arg1=master arg2=access_kind arg3=-` - `GS MODE`: `arg0=mode arg1=value arg2=- arg3=-` - `GS BGCOLOR`: `arg0=r arg1=g arg2=b arg3=-` - `INTC IRQ`: `arg0=source arg1=masked arg2=pending arg3=ack` ## Stub ownership map Suggested ownership split for early implementation: - `EE/MEM/INTC/trace` stubs: one coherent bring-up lane - `GS/platform-video` stubs: one coherent bring-up lane - `DMAC/GIF/SIF/IOP-peripheral` stubs: follow once the first two lanes are stable This is meant to support parallel work without overlapping write ownership. ## Guardrails - No stub should pretend to be real hardware silently; every stub-only path should trace clearly. - No BIOS-affecting stub should land without recorded owner and removal condition. - No subsystem should invent a private trace format. - No Wave 2 stub should block Milestone A or Milestone B if Wave 1 can already produce useful signal. ## Exit criteria for stub-plan acceptance - Claude can implement Wave 1 without reopening core architecture questions. - Each Wave 1 module has a clear contract owner and success condition. - Milestone A and Milestone B are both directly represented in the plan. - The trace format is concrete enough for the first testbenches.