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,128 @@
|
||||
// retroDE_ps2 — gif_path_stub
|
||||
//
|
||||
// Narrow GIF ingress stub for Wave 2. Accepts qword payloads from
|
||||
// dmac_reg_stub, interprets them as register-write packets (project-local
|
||||
// format — see below), and forwards register writes into gs_stub.
|
||||
//
|
||||
// This is NOT real GIFtag decode. Real GIFtag/PACKED/REGLIST/IMAGE formats
|
||||
// arrive in Wave 3. The wire format here is a project-local shortcut sized
|
||||
// to the "programmable BGCOLOR via DMA/GIF" target in
|
||||
// docs/wave2_dma_gif_plan.md.
|
||||
//
|
||||
// Project-local Wave 2 packet format (per qword):
|
||||
// bits [ 15: 0] = target register offset within GS privileged block
|
||||
// (e.g., 0x00E0 for BGCOLOR)
|
||||
// bits [ 79: 16] = 64-bit register value (low 24 bits are RGB for BGCOLOR)
|
||||
// bits [127: 80] = reserved, must be zero
|
||||
//
|
||||
// Each qword produced by the DMAC is treated as one standalone register
|
||||
// write. This module is stateless with respect to packet framing —
|
||||
// multi-beat transfers (Wave 2.6 onward) work transparently because every
|
||||
// accepted qword is independently decoded. `in_last` is preserved as
|
||||
// trace-visible metadata in ev_flags[0] but does not gate decode. Real
|
||||
// GIFtag/PACKED/REGLIST/IMAGE format decode, along with tag-phase vs.
|
||||
// data-phase state, is deferred to Wave 3.
|
||||
//
|
||||
// PATH selection is hard-scoped to the DMAC channel-2 path (PATH id 2)
|
||||
// since no arbitration exists yet.
|
||||
//
|
||||
// Trace payload schema:
|
||||
// GIF GIFTAG arg0=path_id arg1=packet_type arg2=reg_offset arg3=payload_lo
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module gif_path_stub
|
||||
import trace_pkg::*;
|
||||
#(
|
||||
parameter logic [3:0] PATH_ID = 4'd2
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
// Upstream from DMAC
|
||||
input logic in_valid,
|
||||
input logic [127:0] in_data,
|
||||
input logic in_last,
|
||||
output logic in_ready,
|
||||
|
||||
// Downstream to gs_stub (register-write style)
|
||||
output logic gs_wr_en,
|
||||
output logic [15:0] gs_wr_addr,
|
||||
output logic [63:0] gs_wr_data,
|
||||
|
||||
// Trace
|
||||
output logic ev_valid,
|
||||
output subsys_e ev_subsys,
|
||||
output event_e ev_event,
|
||||
output logic [63:0] ev_arg0,
|
||||
output logic [63:0] ev_arg1,
|
||||
output logic [63:0] ev_arg2,
|
||||
output logic [63:0] ev_arg3,
|
||||
output logic [31:0] ev_flags
|
||||
);
|
||||
|
||||
// Wave 2 packet-type magic — one value for "register-write packet".
|
||||
// Future waves will add real GIFtag formats.
|
||||
localparam logic [15:0] PKT_TYPE_REG_WRITE = 16'hA01A;
|
||||
|
||||
// Always ready in Wave 2 — no internal backpressure.
|
||||
assign in_ready = 1'b1;
|
||||
|
||||
logic accept;
|
||||
assign accept = in_valid && in_ready;
|
||||
|
||||
// Decode fields from the qword.
|
||||
logic [15:0] decoded_offset;
|
||||
logic [63:0] decoded_value;
|
||||
|
||||
assign decoded_offset = in_data[15:0];
|
||||
assign decoded_value = in_data[79:16];
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Downstream to gs_stub (registered one-shot pulse)
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
gs_wr_en <= 1'b0;
|
||||
gs_wr_addr <= 16'd0;
|
||||
gs_wr_data <= 64'd0;
|
||||
end else begin
|
||||
gs_wr_en <= accept;
|
||||
if (accept) begin
|
||||
gs_wr_addr <= decoded_offset;
|
||||
gs_wr_data <= decoded_value;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Trace emission
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!rst_n) begin
|
||||
ev_valid <= 1'b0;
|
||||
ev_subsys <= SUBSYS_GIF;
|
||||
ev_event <= EV_GIFTAG;
|
||||
ev_arg0 <= 64'd0;
|
||||
ev_arg1 <= 64'd0;
|
||||
ev_arg2 <= 64'd0;
|
||||
ev_arg3 <= 64'd0;
|
||||
ev_flags <= 32'd0;
|
||||
end else if (accept) begin
|
||||
ev_valid <= 1'b1;
|
||||
ev_subsys <= SUBSYS_GIF;
|
||||
ev_event <= EV_GIFTAG;
|
||||
ev_arg0 <= {60'd0, PATH_ID};
|
||||
ev_arg1 <= {48'd0, PKT_TYPE_REG_WRITE};
|
||||
ev_arg2 <= {48'd0, decoded_offset};
|
||||
ev_arg3 <= {{32{1'b0}}, decoded_value[31:0]};
|
||||
// flags[0] marks end-of-packet (tracks DMAC's in_last)
|
||||
ev_flags <= {31'd0, in_last};
|
||||
end else begin
|
||||
ev_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule : gif_path_stub
|
||||
Reference in New Issue
Block a user