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,123 @@
|
||||
// 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
|
||||
Reference in New Issue
Block a user