# 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.
