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

81 lines
3.1 KiB
Systemverilog
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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