// retroDE_ps2 — trace package // // Defines the shared trace vocabulary used by Wave 1 stubs. Kept small on // purpose: subsystem IDs, event codes, and string renderers only. See // docs/decisions/0000-trace-format.md and docs/stub_module_plan.md. // // Contract: // trace line = cycle subsystem event arg0 arg1 arg2 arg3 flags // // Event codes are globally unique (not per-subsystem) in Wave 1 to keep the // renderer trivial. Revisit if the namespace gets crowded. `ifndef RETRODE_PS2_TRACE_PKG_SV `define RETRODE_PS2_TRACE_PKG_SV `timescale 1ns/1ps package trace_pkg; typedef enum logic [3:0] { SUBSYS_EE = 4'h0, SUBSYS_MEM = 4'h1, SUBSYS_GS = 4'h2, SUBSYS_INTC = 4'h3, SUBSYS_SIF = 4'h4, SUBSYS_DMAC = 4'h5, SUBSYS_IOP = 4'h6, SUBSYS_GIF = 4'h7, SUBSYS_PLAT = 4'h8, SUBSYS_OTHER = 4'hF } subsys_e; typedef enum logic [7:0] { EV_RESET = 8'h00, EV_IFETCH = 8'h01, EV_READ = 8'h02, EV_WRITE = 8'h03, EV_UNMAPPED = 8'h04, EV_IRQ = 8'h05, EV_MODE = 8'h06, EV_BGCOLOR = 8'h07, // Wave 2 additions — DMAC / GIF / GS write-path visibility // (see docs/wave2_dma_gif_plan.md). EV_DMA_CFG = 8'h08, EV_DMA_START = 8'h09, EV_DMA_BEAT = 8'h0A, EV_DMA_DONE = 8'h0B, EV_GIFTAG = 8'h0C, EV_GS_WRITE = 8'h0D, // Ch76 — GS primitive-observer "primitive complete" pulse. // Fired by gs_stub when an XYZ2/XYZF2 vertex commit closes a // discrete primitive (POINT / LINE / TRI / SPRITE) per the // currently-latched PRIM[2:0]. arg0=prim_type, arg1=vert // threshold, arg2=cumulative prim count after this draw, // arg3=closing vertex data. No rasterization yet. EV_PRIM_DRAW = 8'h0E, EV_OTHER = 8'hFF } event_e; // ------------------------------------------------------------------ // Ch81 — structured GIF/GS field decoders // // The raw 64-bit XYZ2 / XYZF2 / RGBAQ payloads are an awkward // contract for the next layer of the pipeline (rasterizer or // pixel emit). These struct types carry the same data already // unpacked into channel components so a consumer doesn't have // to re-derive the bit slices. // // XYZ2 (PCSX2 GSRegs.h: bits[15:0]=X, [31:16]=Y, [63:32]=Z 32-bit) // XYZF2 (PCSX2 GSRegs.h: bits[15:0]=X, [31:16]=Y, [55:32]=Z 24-bit, // [63:56]=F fog byte) // RGBAQ (bits[7:0]=R, [15:8]=G, [23:16]=B, [31:24]=A, [63:32]=Q float) // // X and Y are PS2 12.4 fixed-point screen coordinates (top 12 // bits = integer pixel, low 4 bits = sub-pixel). Z is treated // as opaque in this package — depth interpretation depends on // the GS framebuffer/zbuffer config, which the recognition // layer doesn't model. Q is the texture-coordinate divisor // (IEEE single-precision float); we carry it verbatim. // // is_xyzf2 records the source format so a consumer can // disambiguate the 24-bit-Z + 8-bit-fog packing from the full // 32-bit-Z packing without re-reading the original reg#. // ------------------------------------------------------------------ typedef struct packed { logic is_xyzf2; // 1 = XYZF2 source, 0 = XYZ2 logic [7:0] fog; // valid iff is_xyzf2; else 0 logic [31:0] z; // 32-bit (XYZ2) or zero-extended 24-bit (XYZF2) logic [15:0] y; // 12.4 fixed-point screen Y logic [15:0] x; // 12.4 fixed-point screen X } vertex_t; typedef struct packed { logic [31:0] q; // texture-coord divisor (IEEE float) logic [7:0] a; logic [7:0] b; logic [7:0] g; logic [7:0] r; } color_t; function automatic vertex_t decode_vertex(input logic [63:0] data, input logic is_xyzf2); vertex_t v; v.x = data[15:0]; v.y = data[31:16]; v.is_xyzf2 = is_xyzf2; if (is_xyzf2) begin v.z = {8'd0, data[55:32]}; // zero-extend 24 bits v.fog = data[63:56]; end else begin v.z = data[63:32]; v.fog = 8'd0; end return v; endfunction function automatic color_t decode_color(input logic [63:0] data); color_t c; c.r = data[7:0]; c.g = data[15:8]; c.b = data[23:16]; c.a = data[31:24]; c.q = data[63:32]; return c; endfunction function automatic string subsys_str(input subsys_e s); case (s) SUBSYS_EE: return "EE"; SUBSYS_MEM: return "MEM"; SUBSYS_GS: return "GS"; SUBSYS_INTC: return "INTC"; SUBSYS_SIF: return "SIF"; SUBSYS_DMAC: return "DMAC"; SUBSYS_IOP: return "IOP"; SUBSYS_GIF: return "GIF"; SUBSYS_PLAT: return "PLAT"; default: return "OTHER"; endcase endfunction function automatic string event_str(input event_e e); case (e) EV_RESET: return "RESET"; EV_IFETCH: return "IFETCH"; EV_READ: return "READ"; EV_WRITE: return "WRITE"; EV_UNMAPPED: return "UNMAPPED"; EV_IRQ: return "IRQ"; EV_MODE: return "MODE"; EV_BGCOLOR: return "BGCOLOR"; EV_DMA_CFG: return "DMA_CFG"; EV_DMA_START: return "DMA_START"; EV_DMA_BEAT: return "DMA_BEAT"; EV_DMA_DONE: return "DMA_DONE"; EV_GIFTAG: return "GIFTAG"; EV_GS_WRITE: return "GS_WRITE"; EV_PRIM_DRAW: return "PRIM_DRAW"; default: return "OTHER"; endcase endfunction endpackage : trace_pkg `endif // RETRODE_PS2_TRACE_PKG_SV