Initial commit: retroDE_ps2 — first-of-its-kind PS2 GS FPGA core (DE25-Nano / Agilex 5)
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>
This commit is contained in:
@@ -0,0 +1,433 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user