IFU cleanup

This commit is contained in:
David Harris 2022-01-27 16:41:57 +00:00
parent 1c22077841
commit 218ff3e25d

View File

@ -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.