# Golden Trace and Diff Spec

This document defines the first useful scope for the golden-reference harness
after DobieStation runtime blocked at checkpoint 2.

The immediate target is not "full live-emulator comparison." The immediate
target is:

- generated golden trace for a straight-line synthetic image,
- normalization into the common envelope,
- deterministic diff tooling,
- a clean upgrade path to live emulator traces later.

This spec is intentionally narrow so the harness plumbing can land now without
waiting for a full EE implementation or a revived DobieStation runtime.

## Scope

Phase covered by this spec:

- generated golden trace for a NOP-sled BIOS image,
- comparison against RTL `ee_fetch.trace`,
- event class limited to `EE IFETCH`.

Not in scope yet:

- real BIOS comparison,
- DobieStation runtime recovery,
- PCSX2 instrumentation,
- multi-event or multi-subsystem trace correlation,
- cycle-accurate timing comparison.

## Comparison target

The first comparison target is a dedicated straight-line synthetic BIOS image.

Required properties:

- valid MIPS instruction stream,
- no branches in the compared window,
- no data loads or stores needed for correctness,
- deterministic sequential fetch progression.

For the first implementation, use a `NOP` sled:

- instruction word: `0x00000000`
- image size: 4 MiB to match the BIOS window
- reset vector fetch starts at `0xBFC00000`

Why this target:

- simple enough to reason about by inspection,
- valid execution stream for an emulator,
- meaningful now even with the current `ee_fetch_stub`,
- avoids comparing against the existing synthetic fixture whose words are not a
  sensible execution target.

## Golden trace shape

The generated golden trace must use the project common envelope:

```text
cycle subsystem event arg0 arg1 arg2 arg3 flags
```

Header lines:

- must begin with `#`
- should identify source, scenario, and schema version

Example:

```text
# retroDE_ps2 golden trace, schema v1, source=generated, scenario=nop_sled
# columns: cycle subsystem event arg0 arg1 arg2 arg3 flags
0 EE IFETCH 0x00000000bfc00000 0x0000000000000000 0x0000000000000000 0x0000000000000000 -
1 EE IFETCH 0x00000000bfc00004 0x0000000000000000 0x0000000000000000 0x0000000000000000 -
2 EE IFETCH 0x00000000bfc00008 0x0000000000000000 0x0000000000000000 0x0000000000000000 -
```

Field rules for the generated `NOP` golden:

- `cycle`: monotonic ordinal index starting at `0`
- `subsystem`: `EE`
- `event`: `IFETCH`
- `arg0`: fetch PC
- `arg1`: fetched instruction word, always `0x00000000`
- `arg2`: response kind, `0x0000000000000000`
- `arg3`: unused, `0x0000000000000000`
- `flags`: `-`

## RTL input expected by the diff

For the first compare, the RTL-side input is:

- `sim/traces/rtl/ee_fetch.trace`

The diff tool must ignore:

- comment lines beginning with `#`
- blank lines
- non-matching event classes if filtering is enabled

For the first compare, the tool should operate on `EE IFETCH` records only.

`EE RESET` lines are intentionally excluded from the first comparison target.
They are useful trace events, but they are not part of the first golden fetch
stream contract.

## Normalized record model

The diff tool should parse each non-comment line into:

- `cycle`
- `subsystem`
- `event`
- `arg0`
- `arg1`
- `arg2`
- `arg3`
- `flags`

All numeric payloads should be normalized to integers internally.

`flags` normalization:

- `-` means zero
- `0x...` means the parsed integer value

## Diff semantics

### Record selection

For the first implementation, compare records after filtering to:

- `subsystem == EE`
- `event == IFETCH`

### Match strategy

Compare by `record order`, not by `cycle`.

Rationale:

- current RTL and future emulator traces may use different cycle/time bases,
- the first useful question is whether the fetch sequence matches,
- order-based comparison is the right fit for the current straight-line target.

### Fields that must match

After filtering, the following fields must match exactly:

- `subsystem`
- `event`
- `arg0`
- `arg1`
- `arg2`
- `arg3`
- `flags`

### Fields that are informational only

- `cycle`

The tool should still validate that cycle values are monotonic within each
input trace, but cycle mismatch alone must not fail the compare.

## Length mismatch policy

Length mismatch is a hard failure.

Cases:

- RTL shorter than golden: fail
- RTL longer than golden: fail
- either side empty after filtering: fail

Error output should report:

- filtered record counts on both sides,
- first missing index,
- which side ended early

## Malformed input policy

Malformed input is a hard failure.

Examples:

- wrong number of columns,
- unparseable hex field,
- unknown event token in a filtered record,
- non-monotonic cycle values inside one trace

The tool should report:

- filename
- 1-based line number in the original file
- reason for rejection

## Exit code contract

Suggested exit codes:

- `0`: comparison passed
- `1`: semantic mismatch
- `2`: usage or missing-file error
- `3`: malformed input / parse failure

This keeps "compare failed" distinct from "tool invocation broke."

## Console output contract

On pass, print a concise summary:

```text
PASS: matched 32 EE/IFETCH records (cycle ignored, order-based compare)
```

On mismatch, print:

- failing record index
- RTL record
- golden record
- short field-level mismatch summary

Example:

```text
FAIL: mismatch at filtered record 5
  rtl:    EE IFETCH arg0=0x... arg1=0x...
  golden: EE IFETCH arg0=0x... arg1=0x...
  diff:   arg1 differs
```

## Acceptance criteria

The first golden harness is accepted when all of the following are true:

1. A generated NOP-sled golden trace can be produced in the common envelope.
2. The diff tool can compare that golden trace against `sim/traces/rtl/ee_fetch.trace`.
3. The tool ignores `EE RESET` and compares only filtered `EE IFETCH` records.
4. A clean run against the current Wave 1 EE fetch path returns exit code `0`.
5. A deliberate corruption of one fetched word in either input produces exit
   code `1` and reports the first mismatching filtered record.
6. A malformed trace line produces exit code `3`.

## Upgrade path

Once live emulator traces are available, reuse the same diff semantics with
only two changes:

- replace the generated golden input with a normalized emulator trace,
- widen the compared window as far as the current RTL implementation remains
  meaningfully comparable.

Recommended next live-emulator order:

1. PCSX2, if a live source is needed before DobieStation runtime is recovered
2. DobieStation later, if the runtime block is removed
