// 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