# Ch305 closeout — DSUBU; THIRD inflection (+1.46M retires); EE-core reality checkpoint queued **Status:** Closed. **Verdict from re-running qbert.elf:** `elf_timeout_with_hot_pc (1489428 retires, hot_pc=0x00106154)` — qbert advanced 29,417 → **1,489,428 retires (+1,460,011)**, a **third inflection**, then hit a new steady-state wait loop in a different code region. ## What landed — `rtl/ee/ee_core_stub.sv` (4 edits) R5900 DSUBU (SPECIAL funct 0x2F), the 64-bit-subtract sibling of Ch272's DADDU. Modelled as SUBU on the low 32 bits, no overflow trap: 1. `localparam FUNC_DSUBU = 6'h2F`. 2. `is_dsubu = is_special && (func == FUNC_DSUBU)`. 3. Added `is_dsubu` to `is_rtype_alu` (which auto-excludes it from `is_nop_class` via the SPECIAL clause — no separate nop_class edit needed). 4. Extended the SUBU writeback arm: `is_sub || is_subu || is_dsubu` → `rs_val - rt_val`. ## Focused TB — `tb_ee_core_dsubu.sv` Three cases, all PASS: 1. Normal: `dsubu $t0, $a0, $a1` (8 - 3 = 5). 2. **Exact qbert encoding asserted** `0x0062102F` = `dsubu $v0, $v1, $v0` (10 - 4 = 6). 3. Underflow: `dsubu $t3, $0, $a3` (0 - 1 = 0xFFFFFFFF, no trap). Result: `$t0=5 $v0=6 $t3=0xFFFFFFFF errors=0 PASS`. ## qbert progression — third inflection | Chapter | retire_count | verdict | |---------|--------------|---------| | Post-Ch304 (0x6B) | 29,417 | opcode trap (DSUBU) | | **Post-Ch305 (DSUBU)** | **1,489,428** | **timeout_with_hot_pc** | +1.46M retires. The third time a single opcode/syscall addition has unlocked a >1M-retire stretch (after Ch293's syscall 0x7A and Ch297's syscall 0x77). DSUBU was the last blocker in a hot numeric-init path; clearing it let qbert run deep into a new region (hot_pc 0x00106154 — note 0x00106xxx, *lower* than all prior blockers, so a different/earlier-linked function). The new wait loop at 0x00106154 is a Ch307+ autopsy candidate — **deferred** in favor of the Ch306 reality checkpoint per the strategic decision below. ## Strategic pivot — Ch306 = EE core reality checkpoint Codex and the project owner have (correctly) called the question: **the qbert track is building a behavioral compatibility oracle, not a synthesizable R5900.** Before sinking more chapters into either track, Ch306 is a recon/design checkpoint that splits the roadmap into two explicit tracks: - **Track A — EE Behavioral Oracle** (`ee_core_stub`): continue qbert only to *discover* required instructions/syscalls/MMIO. Output = a living compliance checklist. - **Track B — Synthesizable EE Core**: a separate, deliberate RTL plan. Must NOT grow accidentally from the stub. Ch306's job (a workflow): inventory every `ee_core_stub` feature and classify each as: 1. **architectural instruction** → graduates to real RTL, 2. **HLE syscall behavior** → BIOS/kernel, lives in ROM or an HLE companion, NOT the CPU, 3. **TB-only / qbert-specific hack** (gate pokes, $a0-aware returns, Ch215 shim) → pure scaffolding for missing async hardware, NEVER graduates, 4. **unsynthesizable / sim-only** (trace ports, hierarchical peeks) → must be stripped or gated for synthesis. Plus: a go/no-go on whether a simple multicycle/interpreter-style R5900 subset fits the Agilex 5 and passes the existing ~178 TBs. The qbert-focused TBs become the compliance suite for Track B. **The validation answer** (the concern that triggered this pivot): we *can* validate a real R5900 RTL — the 178 TBs + qbert boot path already ARE the harness. We've been writing a spec-by-execution for 35 chapters; Ch306 makes it explicit and decides the graduation path before, not after, building Track B. ## Files changed - `rtl/ee/ee_core_stub.sv` — 4 DSUBU edits. - `sim/tb/integration/tb_ee_core_dsubu.sv` — new focused TB. - `sim/Makefile` — target + both regression lists. ## Regression **178/178 PASS** — clean full regression covering both Ch304 (syscall 0x6B) and Ch305 (DSUBU), with tb_ee_core_dsubu in the suite. (Was 177 in Ch304; +1 for the new DSUBU TB.)