diff --git a/src/Cpu/FetchStage.bsv b/src/Cpu/FetchStage.bsv index 5790e7d..d569feb 100644 --- a/src/Cpu/FetchStage.bsv +++ b/src/Cpu/FetchStage.bsv @@ -18,11 +18,17 @@ interface FetchStage_Ifc#(numeric type xlen); interface Get#(IF_ID#(xlen)) getIF_ID; interface ReadOnlyMemoryClient#(xlen, 32) memoryClient; + interface Get#(Bit#(xlen)) getNPC; + interface Put#(Bool) putStall; endinterface module mkFetchStage#(FetchStage_Cfg#(xlen) cfg)(FetchStage_Ifc#(xlen)); Wire#(PC_IF#(xlen)) pc_if <- mkWire; Wire#(IF_ID#(xlen)) if_id <- mkWire; + Wire#(Bit#(xlen)) npc <- mkWire; + + Reg#(Bool) stall <- mkReg(False); + Reg#(Bool) externalStall <- mkReg(False); // Memory request output Reg#(Bool) memoryRequestInFlight <- mkReg(False); @@ -31,6 +37,11 @@ module mkFetchStage#(FetchStage_Cfg#(xlen) cfg)(FetchStage_Ifc#(xlen)); // Memory response input (FIFO) FIFOF#(ReadOnlyMemoryResponse#(32)) memoryResponses <- mkFIFOF; + // + // processMemoryResponse - takes a memory response and returns an IF_ID containing + // the encoded instruction (or a trap if the original request + // was denied by the memory system) + // function IF_ID#(xlen) processMemoryResponse(ReadOnlyMemoryResponse#(32) response); IF_ID#(xlen) if_id_ = defaultValue; if_id_.common.pc = pc_if.common.pc; @@ -56,7 +67,9 @@ module mkFetchStage#(FetchStage_Cfg#(xlen) cfg)(FetchStage_Ifc#(xlen)); if_id_.common.pc = pc_if.common.pc; if_id_.common.isBubble = True; - if (!pc_if.common.isBubble) begin + npc <= pc_if.common.pc + 4; + + if (!pc_if.common.isBubble && !stall) begin // If there's an active request, handle it if it's returned if (memoryRequestInFlight) begin if (memoryResponses.notEmpty) begin @@ -92,10 +105,15 @@ module mkFetchStage#(FetchStage_Cfg#(xlen) cfg)(FetchStage_Ifc#(xlen)); end end + // Determine if fetching should stall on the next cycle. + stall <= externalStall; // || ichache_miss || itlb_busy; + if_id <= if_id_; endrule interface Put putPC_IF = toPut(asIfc(pc_if)); interface Get getIF_ID = toGet(if_id); interface ReadOnlyMemoryClient memoryClient = toGPClient(memoryRequest, memoryResponses); + interface Get getNPC = toGet(npc); + interface Put putStall = toPut(asIfc(externalStall)); endmodule