ec82764bef
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>
81 lines
3.1 KiB
Systemverilog
81 lines
3.1 KiB
Systemverilog
// 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
|