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>
124 lines
4.6 KiB
Systemverilog
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
|