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

129 lines
4.2 KiB
Systemverilog

// retroDE_ps2 — ee_fetch_stub
//
// Minimal sequential-fetch stand-in for the R5900. Wave 1 scope only: enough
// to drive ee_memory_map_stub → bios_rom_stub for Milestone B.
//
// Contract refs:
// docs/stub_module_plan.md (Wave 1, item 4)
// docs/contracts/ee.md
//
// Behavior:
// - On reset, PC = RESET_VECTOR (default 0xBFC00000, the MIPS BIOS
// reset vector in kseg1).
// - Each cycle while `enable` is high: issue a read at PC, advance
// PC += 4. No decode, no branches, no exceptions, no retirement
// fidelity (all out-of-scope per plan).
// - Responses return 1 cycle later via rd_valid/rd_data from the
// memory map. The issued address is latched so the trace line can
// pair address with data.
//
// Non-goals for this wave (stub plan, explicit):
// - full decode,
// - exceptions beyond deterministic fault handling,
// - FPU/MMI behavior,
// - instruction retirement fidelity.
//
// Trace payload schema (per stub plan):
// EE RESET arg0=reset_vector
// EE IFETCH arg0=pc arg1=data arg2=resp_kind arg3=-
// resp_kind: 0=OK (only path in Wave 1)
`timescale 1ns/1ps
module ee_fetch_stub
import trace_pkg::*;
#(
parameter logic [31:0] RESET_VECTOR = 32'hBFC00000
) (
input logic clk,
input logic rst_n,
input logic enable,
// Memory-facing fetch port
output logic rd_en,
output logic [31:0] rd_addr,
input logic [31:0] rd_data,
input logic rd_valid,
// 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
);
// ------------------------------------------------------------------
// PC and one-cycle issued-address shadow
//
// pc is the address being issued THIS cycle (rd_addr)
// pc_d1 is the address whose response arrives THIS cycle on rd_valid
//
// pc_d1 only advances alongside pc when enable is high, so it stays
// aligned with the in-flight request.
// ------------------------------------------------------------------
logic [31:0] pc;
logic [31:0] pc_d1;
always_ff @(posedge clk) begin
if (!rst_n) begin
pc <= RESET_VECTOR;
pc_d1 <= RESET_VECTOR;
end else if (enable) begin
pc_d1 <= pc;
pc <= pc + 32'd4;
end
end
assign rd_en = enable;
assign rd_addr = pc;
// ------------------------------------------------------------------
// Trace
// - Single EV_RESET pulse at reset exit.
// - EV_IFETCH one cycle after each rd_valid response.
// ------------------------------------------------------------------
logic reset_emit_pending;
always_ff @(posedge clk) begin
if (!rst_n) begin
ev_valid <= 1'b0;
ev_subsys <= SUBSYS_EE;
ev_event <= EV_RESET;
ev_arg0 <= 64'd0;
ev_arg1 <= 64'd0;
ev_arg2 <= 64'd0;
ev_arg3 <= 64'd0;
ev_flags <= 32'd0;
reset_emit_pending <= 1'b1;
end else if (reset_emit_pending) begin
ev_valid <= 1'b1;
ev_subsys <= SUBSYS_EE;
ev_event <= EV_RESET;
ev_arg0 <= {32'd0, RESET_VECTOR};
ev_arg1 <= 64'd0;
ev_arg2 <= 64'd0;
ev_arg3 <= 64'd0;
ev_flags <= 32'd0;
reset_emit_pending <= 1'b0;
end else if (rd_valid) begin
ev_valid <= 1'b1;
ev_subsys <= SUBSYS_EE;
ev_event <= EV_IFETCH;
ev_arg0 <= {32'd0, pc_d1};
ev_arg1 <= {32'd0, rd_data};
ev_arg2 <= 64'd0; // resp_kind: 0 = OK
ev_arg3 <= 64'd0;
ev_flags <= 32'd0;
end else begin
ev_valid <= 1'b0;
end
end
endmodule : ee_fetch_stub