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

124 lines
4.6 KiB
Systemverilog

// retroDE_ps2 — bios_rom_stub
//
// Simulation stub for the 4 MiB BIOS ROM window. Gives Milestone B a
// deterministic instruction source before the rest of the memory system
// exists.
//
// Contract refs:
// docs/stub_module_plan.md (Wave 1, item 2)
// docs/contracts/memory.md (memory owns BIOS storage/visibility)
// docs/contracts/iop.md (IOP owns BIOS behavior — NOT here)
// docs/decisions/0002-bios-policy.md (real BIOS + narrow stubs; this stub
// is the storage adapter, not firmware
// behavior, and needs no stub-policy
// tracking)
//
// Backing store:
// - If IMAGE_FILE is a non-empty string, `$readmemh` loads it at
// elaboration. Caller is responsible for supplying a hex image produced
// from a user-supplied BIOS dump. No BIOS image is shipped with this
// repository (see third_party/LICENSING.md).
// - If IMAGE_FILE is empty (default), a synthetic fixture is generated:
// mem[word_i] = 32'h00000000 (MIPS NOP: sll $0, $0, 0)
// Rationale: straight-line valid MIPS so the fixture is a legitimate
// execution target for any future emulator comparison. This aligns
// with sim/golden/trace_compare_spec.md ("first comparison target").
// Earlier versions used 32'hBFC00000 | word_index for trace-distinct
// inspection, but the spec explicitly rules out fixtures whose words
// are not a sensible execution target.
//
// Interface:
// - Byte-addressed within the 4 MiB window. The lower 2 bits of rd_addr
// are ignored (word-aligned fetch). Upstream address decode is owned
// by ee_memory_map_stub; this block does not validate the window itself.
// - One-cycle read latency: rd_en pulses on cycle N, rd_data/rd_valid
// present on cycle N+1.
// - Each completed read emits a MEM.READ trace event.
//
// Trace payload schema (per stub plan):
// MEM READ arg0=addr arg1=data arg2=master arg3=region
// master: 0=EE_IFETCH (only source wired in Wave 1)
// region: 0=BIOS
`timescale 1ns/1ps
module bios_rom_stub
import trace_pkg::*;
#(
parameter int SIZE_BYTES = 4 * 1024 * 1024,
parameter string IMAGE_FILE = ""
) (
input logic clk,
input logic rst_n,
input logic rd_en,
input logic [$clog2(SIZE_BYTES)-1:0] rd_addr,
output logic [31:0] rd_data,
output logic rd_valid,
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
);
localparam int WORD_COUNT = SIZE_BYTES / 4;
localparam int ADDR_WIDTH = $clog2(SIZE_BYTES);
localparam int WORD_INDEX_WIDTH = ADDR_WIDTH - 2;
logic [31:0] mem [0:WORD_COUNT-1];
initial begin
if (IMAGE_FILE != "") begin
$display("[bios_rom_stub] loading image: %0s", IMAGE_FILE);
$readmemh(IMAGE_FILE, mem);
end else begin
for (int i = 0; i < WORD_COUNT; i++) begin
mem[i] = 32'h00000000; // MIPS NOP
end
$display("[bios_rom_stub] synthetic NOP sled loaded (%0d words)", WORD_COUNT);
end
end
logic [WORD_INDEX_WIDTH-1:0] word_index;
assign word_index = rd_addr[ADDR_WIDTH-1:2];
always_ff @(posedge clk) begin
if (!rst_n) begin
rd_data <= 32'd0;
rd_valid <= 1'b0;
ev_valid <= 1'b0;
ev_subsys <= SUBSYS_MEM;
ev_event <= EV_READ;
ev_arg0 <= 64'd0;
ev_arg1 <= 64'd0;
ev_arg2 <= 64'd0;
ev_arg3 <= 64'd0;
ev_flags <= 32'd0;
end else begin
rd_valid <= rd_en;
if (rd_en) begin
rd_data <= mem[word_index];
ev_valid <= 1'b1;
ev_subsys <= SUBSYS_MEM;
ev_event <= EV_READ;
ev_arg0 <= {{(64-ADDR_WIDTH){1'b0}}, rd_addr};
ev_arg1 <= {32'd0, mem[word_index]};
ev_arg2 <= 64'd0; // master: EE_IFETCH
ev_arg3 <= 64'd0; // region: BIOS
ev_flags <= 32'd0;
end else begin
ev_valid <= 1'b0;
end
end
end
endmodule : bios_rom_stub