diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 537396b56..a9bd7ce99 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -107,10 +107,10 @@ module ifu ( logic CacheableF; logic [`XLEN-1:0] PCNextFSpill; logic [`XLEN-1:0] PCFSpill; - logic SelNextSpill; + logic SelNextSpillF; logic ICacheFetchLine; logic BusStall; - logic ICacheStallF; + logic ICacheStallF, IFUCacheBusStallF; logic IgnoreRequest; logic CPUBusy; (* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; @@ -118,59 +118,60 @@ module ifu ( localparam integer SPILLTHRESHOLD = `MEM_ICACHE ? `ICACHE_LINELENINBITS/32 : 1; if(`C_SUPPORTED) begin : SpillSupport - logic [`XLEN-1:0] PCFp2; - logic Spill; - logic SelSpill, SpillSave; + logic [`XLEN-1:0] PCPlus2F; + logic TakeSpillF; + logic SpillF; + logic SelSpillF, SpillSaveF; logic [15:0] SpillDataLine0; // *** PLACE ALL THIS IN A MODULE // this exists only if there are compressed instructions. - //assign PCFp2 = PCF + `XLEN'b10; ** - assign PCFp2 = PCF[1] ? {PCPlusUpperF, 2'b00} : {PCF[`XLEN-1:2], 2'b10}; // recode as mux + // reuse PC+2/4 circuitry to avoid needing a second CPA to add 2 + mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); + mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill)); + mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); - assign PCNextFSpill = SelNextSpill ? PCFp2 : PCNextF; - assign PCFSpill = SelSpill ? PCFp2 : PCF; - - assign Spill = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; + assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; typedef enum {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype; (* mark_debug = "true" *) statetype CurrState, NextState; - always_ff @(posedge clk) if (reset) CurrState <= #1 STATE_SPILL_READY; else CurrState <= #1 NextState; + assign TakeSpillF = SpillF & ~IFUCacheBusStallF; + always_comb begin - case(CurrState) - STATE_SPILL_READY: if (Spill & ~(ICacheStallF | BusStall)) NextState = STATE_SPILL_SPILL; + case (CurrState) + STATE_SPILL_READY: if (TakeSpillF) NextState = STATE_SPILL_SPILL; else NextState = STATE_SPILL_READY; - STATE_SPILL_SPILL: if(ICacheStallF | BusStall | StallF) NextState = STATE_SPILL_SPILL; - else NextState = STATE_SPILL_READY; - default: NextState = STATE_SPILL_READY; + STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL_SPILL; + else NextState = STATE_SPILL_READY; + default: NextState = STATE_SPILL_READY; endcase end - assign SelSpill = CurrState == STATE_SPILL_SPILL; - assign SelNextSpill = (CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall))) | - (CurrState == STATE_SPILL_SPILL & (ICacheStallF | BusStall)); - assign SpillSave = CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall)); + assign SelSpillF = (CurrState == STATE_SPILL_SPILL); + assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | + (CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); + assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; flopenr #(16) SpillInstrReg(.clk(clk), - .en(SpillSave), + .en(SpillSaveF), .reset(reset), .d(`MEM_ICACHE ? InstrRawF[15:0] : InstrRawF[31:16]), .q(SpillDataLine0)); - assign PostSpillInstrRawF = Spill ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; + assign PostSpillInstrRawF = SpillF ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; // end of spill support end else begin : NoSpillSupport // line: SpillSupport assign PCNextFSpill = PCNextF; assign PCFSpill = PCF; - assign SelNextSpill = 0; + assign SelNextSpillF = 0; assign PostSpillInstrRawF = InstrRawF; end @@ -315,8 +316,9 @@ module ifu ( .s(SelUncachedAdr), .y(InstrRawF)); - assign IFUStallF = ICacheStallF | BusStall | SelNextSpill; - assign CPUBusy = StallF & ~SelNextSpill; + assign IFUCacheBusStallF = ICacheStallF | BusStall; + assign IFUStallF = IFUCacheBusStallF | SelNextSpillF; + assign CPUBusy = StallF & ~SelNextSpillF; //assign IgnoreRequest = ITLBMissF | ExceptionM | PendingInterruptM; // this is a difference with the dcache.