# rtl/intc Interrupt controller scaffolding. Matches `docs/contracts/intc.md`. ## Current contents - `intc_stub.sv` — generic PS2-style INTC register shell. Register-visible INTC_STAT / INTC_MASK (offsets parameterized) plus a 16-source injection port `irq_src[15:0]`. The aggregate output `cpu_irq` is polarity-neutral: the same module is instantiated both as the EE INTC and as the IOP INTC (with appropriate offsets and a different set of wired sources in each case). ## Register semantics - `INTC_STAT` (offset is a parameter; default 0x00): W1C on writes; sticky until cleared. `irq_src` sets bits on each cycle they're observed; same-cycle inject-over-W1C collisions keep the pending bit — interrupts are never silently swallowed. - `INTC_MASK` (offset is a parameter; default 0x10): plain write-to-set. Real PS2 uses XOR/toggle semantics on mask writes; stub uses plain write for simplicity. Escalate if a BIOS trace demands it. ## Instantiation conventions - **EE INTC**: default offsets (STAT=0x00, MASK=0x10). Instantiated stand-alone in most benches; the EE memory map does not route INTC addresses yet (deferred). - **IOP INTC**: parameterized to STAT=0x70, MASK=0x74 to match real PS2 IOP INTC placement. Reached through `iop_memory_map_stub` at physical address 0x1F80_1070+ (region id = 5). ## Wired sources (current) - EE INTC bit 0 = EE DMAC completion (`dmac_reg_stub.irq_completion_o`). - IOP INTC bit 0 = IOP DMAC ch9 completion (`iop_dmac_reg_stub.irq_completion_o`). Both are one-cycle pulses driven from the respective DMAC's `S_DONE` state. The INTC latches them into its own pending bit; software (the TB, for now) reads STAT through the architectural register port and acks with a W1C write. ## Scope boundary Module is side-neutral by design. Source-routing from other real subsystems (timers, GIF/GS, IPU, SPU2, bridge `last_seen_o`) is the next natural expansion. Re-arm / re-assertion ordering is already proven in the integration benches.