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>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
// retroDE_ps2 — clut_stub (Ch97)
|
||||
//
|
||||
// Minimal palette RAM for indexed-color scanout. PSMT8 scanout
|
||||
// (Ch96) currently surfaces the index as grayscale; with this
|
||||
// CLUT wired in, the index is looked up to produce real RGB.
|
||||
//
|
||||
// Scope (intentionally minimal for Ch97):
|
||||
// - 256 entries × 32 bits (PSMCT32 ABGR per entry). PSMT4
|
||||
// (16 entries) uses the same RAM with a smaller index range.
|
||||
// - CSM2 (linear) addressing only. Index N reads entry N. CSA
|
||||
// (entry offset) is honored OUTSIDE this module — pcrtc
|
||||
// computes effective_idx = idx + (CSA << 4) and presents it
|
||||
// as `read_idx`. CSM1 (16×16 grid swizzle inside a CSPM
|
||||
// block) is deferred.
|
||||
// - Combinational read port for pcrtc (tight scanout latency).
|
||||
// - Single registered write port. Two writers exist at this
|
||||
// scope, picked by the wiring at the TB level:
|
||||
// (a) TB-direct programming for tests that want to lock
|
||||
// pcrtc-side decode in isolation (Ch97 PSMT8+CLUT TB,
|
||||
// Ch98 TEX0_1 CSA-flow TB).
|
||||
// (b) `clut_loader_stub` (Ch99/Ch100) — a small FSM that
|
||||
// copies 256 entries from VRAM[CBP*256] into this RAM
|
||||
// when a TEX0_1 GIF write commits with CLD!=0,
|
||||
// CSM=CSM2, and CPSM ∈ {PSMCT32, PSMCT16}. PSMCT16
|
||||
// entries are unpacked from RGB5A1 to PSMCT32 ABGR
|
||||
// inside the loader, so clut_stub always stores
|
||||
// PSMCT32 regardless of source. clut_stub doesn't know
|
||||
// which writer is in play; it just commits whatever
|
||||
// the wired write_* port carries.
|
||||
//
|
||||
// Real PS2 CLUT is held in a 1 KiB internal staging area and
|
||||
// loaded from VRAM[CBP] when CLD bits in TEX0 fire. Ch99/Ch100
|
||||
// model the load path for CPSM ∈ {PSMCT32, PSMCT16} with CSM2;
|
||||
// CSM1 swizzle, conditional CLD modes (2..7), CSA partial-window
|
||||
// loads (CLD=4), and CPSM ∉ {PSMCT32, PSMCT16} stay deferred.
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module clut_stub
|
||||
#(
|
||||
parameter int unsigned ENTRIES = 256
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
// TB-direct write port (no GIF TEX0 path yet).
|
||||
input logic write_en,
|
||||
input logic [7:0] write_idx,
|
||||
input logic [31:0] write_data,
|
||||
|
||||
// Combinational read port consumed by gs_pcrtc_stub (scanout).
|
||||
input logic [7:0] read_idx,
|
||||
output logic [31:0] read_data,
|
||||
|
||||
// Ch296 — SECOND combinational read port for the TEXTURE sampler
|
||||
// (gs_stub texel-fetch path). Independent of the pcrtc scanout port
|
||||
// above: the table is a tiny 256x32 LUT, so a second read fan-out is
|
||||
// free and keeps the two consumers (scanout vs sampler) decoupled.
|
||||
// PSMT8 indexed texturing looks up clut_stub[tex_read_idx] to turn a
|
||||
// fetched 8-bit index into a PSMCT32 color.
|
||||
input logic [7:0] tex_read_idx,
|
||||
output logic [31:0] tex_read_data
|
||||
);
|
||||
|
||||
logic [31:0] mem [0:ENTRIES-1];
|
||||
|
||||
initial begin
|
||||
for (int i = 0; i < ENTRIES; i++) mem[i] = 32'd0;
|
||||
end
|
||||
|
||||
assign read_data = mem[read_idx];
|
||||
assign tex_read_data = mem[tex_read_idx];
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst_n && write_en) begin
|
||||
mem[write_idx] <= write_data;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule : clut_stub
|
||||
Reference in New Issue
Block a user