Files
thejayman77 ec82764bef 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>
2026-06-29 20:10:50 -04:00

167 lines
6.2 KiB
Systemverilog

// 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