Added generate around the spill logic so it is only used if supporting compressed instructions.

This commit is contained in:
Ross Thompson 2022-01-03 22:23:04 -06:00
parent 120a9d6a58
commit ff24718c28

View File

@ -27,61 +27,54 @@
`include "wally-config.vh" `include "wally-config.vh"
module ifu ( module ifu (
input logic clk, reset, input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushF, FlushD, FlushE, FlushM, FlushW, input logic FlushF, FlushD, FlushE, FlushM, FlushW,
// Fetch // Bus interface
input logic [`XLEN-1:0] IfuBusHRDATA, input logic [`XLEN-1:0] IfuBusHRDATA,
input logic IfuBusAck, input logic IfuBusAck,
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF, output logic [`PA_BITS-1:0] IfuBusAdr,
output logic [`PA_BITS-1:0] IfuBusAdr, output logic IfuBusRead,
output logic IfuBusRead, output logic IfuStallF,
output logic IfuStallF, (* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
// Execute // Execute
output logic [`XLEN-1:0] PCLinkE, output logic [`XLEN-1:0] PCLinkE,
input logic PCSrcE, input logic PCSrcE,
input logic [`XLEN-1:0] IEUAdrE, input logic [`XLEN-1:0] IEUAdrE,
output logic [`XLEN-1:0] PCE, output logic [`XLEN-1:0] PCE,
output logic BPPredWrongE, output logic BPPredWrongE,
// Mem // Mem
input logic RetM, TrapM, input logic RetM, TrapM,
input logic [`XLEN-1:0] PrivilegedNextPCM, input logic [`XLEN-1:0] PrivilegedNextPCM,
input logic InvalidateICacheM, input logic InvalidateICacheM,
output logic [31:0] InstrD, InstrM, output logic [31:0] InstrD, InstrM,
output logic [`XLEN-1:0] PCM, output logic [`XLEN-1:0] PCM,
output logic [4:0] InstrClassM, // branch predictor
output logic BPPredDirWrongM, output logic [4:0] InstrClassM,
output logic BTBPredPCWrongM, output logic BPPredDirWrongM,
output logic RASPredPCWrongM, output logic BTBPredPCWrongM,
output logic BPPredClassNonCFIWrongM, output logic RASPredPCWrongM,
// Writeback output logic BPPredClassNonCFIWrongM,
// output logic [`XLEN-1:0] PCLinkW, // Faults
// Faults input logic IllegalBaseInstrFaultD,
input logic IllegalBaseInstrFaultD, output logic ITLBInstrPageFaultF,
output logic ITLBInstrPageFaultF, output logic IllegalIEUInstrFaultD,
output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM,
output logic InstrMisalignedFaultM, output logic [`XLEN-1:0] InstrMisalignedAdrM,
output logic [`XLEN-1:0] InstrMisalignedAdrM, input logic ExceptionM, PendingInterruptM,
input logic ExceptionM, PendingInterruptM, // mmu management
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PTE,
input logic [1:0] PageType,
// mmu management input logic [`XLEN-1:0] SATP_REGW,
input logic [1:0] PrivilegeModeW, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [`XLEN-1:0] PTE, input logic [1:0] STATUS_MPP,
input logic [1:0] PageType, input logic ITLBWriteF, ITLBFlushF,
input logic [`XLEN-1:0] SATP_REGW, output logic ITLBMissF,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic ITLBWriteF, ITLBFlushF,
output logic ITLBMissF,
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
output logic InstrAccessFaultF
output logic InstrAccessFaultF
); );
logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF;
@ -95,73 +88,85 @@ module ifu (
logic [31:0] InstrE; logic [31:0] InstrE;
logic [`XLEN-1:0] PCD; logic [`XLEN-1:0] PCD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic reset_q; // *** look at this later. logic reset_q; // *** look at this later.
logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE; logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE;
logic [`XLEN-1:0] PCBPWrongInvalidate;
logic BPPredWrongM;
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PCPF; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width. (* mark_debug = "true" *) logic [`PA_BITS-1:0] PCPF; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width.
logic [`XLEN+1:0] PCFExt; logic [`XLEN+1:0] PCFExt;
logic [`XLEN-1:0] PCBPWrongInvalidate;
logic BPPredWrongM;
logic CacheableF; logic CacheableF;
logic [11:0] PCNextFMux; logic [11:0] PCNextFMux;
logic [`XLEN-1:0] PCFMux; logic [`XLEN-1:0] PCFMux;
logic SelNextSpill;
logic [`XLEN-1:0] PCFp2;
logic SelNextSpill, SelSpill, SpillSave;
logic Spill;
logic ICacheFetchLine; logic ICacheFetchLine;
logic BusStall; logic BusStall;
logic ICacheStallF; logic ICacheStallF;
logic IgnoreRequest; logic IgnoreRequest;
logic CPUBusy; logic CPUBusy;
logic [31:0] PostSpillInstrRawF;
generate
if(`C_SUPPORTED) begin : SpillSupport
logic [`XLEN-1:0] PCFp2;
logic Spill;
logic SelSpill, SpillSave;
logic [15:0] SpillDataBlock0;
// this exists only if there are compressed instructions.
assign PCFp2 = PCF + `XLEN'b10;
logic [15:0] SpillDataBlock0; assign PCNextFMux = SelNextSpill ? PCFp2[11:0] : PCNextF[11:0];
logic [31:0] PostSpillInstrRawF; assign PCFMux = SelSpill ? PCFp2 : PCF;
assign PCFp2 = PCF + `XLEN'b10;
assign PCNextFMux = SelNextSpill ? PCFp2[11:0] : PCNextF[11:0];
assign PCFMux = SelSpill ? PCFp2 : PCF;
assign Spill = &PCF[$clog2(`ICACHE_BLOCKLENINBITS/32)+1:1];
assign Spill = &PCF[$clog2(`ICACHE_BLOCKLENINBITS/32)+1:1]; typedef enum {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
typedef enum {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) CurrState <= #1 STATE_SPILL_READY; if (reset) CurrState <= #1 STATE_SPILL_READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
STATE_SPILL_READY: if (Spill & ~(ICacheStallF | BusStall)) NextState = STATE_SPILL_SPILL; STATE_SPILL_READY: if (Spill & ~(ICacheStallF | BusStall)) NextState = STATE_SPILL_SPILL;
else NextState = STATE_SPILL_READY; else NextState = STATE_SPILL_READY;
STATE_SPILL_SPILL: if(ICacheStallF | BusStall | StallF) NextState = STATE_SPILL_SPILL; STATE_SPILL_SPILL: if(ICacheStallF | BusStall | StallF) NextState = STATE_SPILL_SPILL;
else NextState = STATE_SPILL_READY; else NextState = STATE_SPILL_READY;
default: NextState = STATE_SPILL_READY; default: NextState = STATE_SPILL_READY;
endcase endcase
end end
assign SelSpill = CurrState == STATE_SPILL_SPILL; assign SelSpill = CurrState == STATE_SPILL_SPILL;
assign SelNextSpill = (CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall))) | assign SelNextSpill = (CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall))) |
(CurrState == STATE_SPILL_SPILL & (ICacheStallF | BusStall)); (CurrState == STATE_SPILL_SPILL & (ICacheStallF | BusStall));
assign SpillSave = CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall)); assign SpillSave = CurrState == STATE_SPILL_READY & (Spill & ~(ICacheStallF | BusStall));
flopenr #(16) SpillInstrReg(.clk(clk), flopenr #(16) SpillInstrReg(.clk(clk),
.en(SpillSave), .en(SpillSave),
.reset(reset), .reset(reset),
.d(InstrRawF[15:0]), .d(InstrRawF[15:0]),
.q(SpillDataBlock0)); .q(SpillDataBlock0));
assign PostSpillInstrRawF = Spill ? {InstrRawF[15:0], SpillDataBlock0} : InstrRawF; assign PostSpillInstrRawF = Spill ? {InstrRawF[15:0], SpillDataBlock0} : InstrRawF;
assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11;
// end of spill support
end else begin : NoSpillSupport // block: SpillSupport
assign PCNextFMux = PCNextF[11:0];
assign PCFMux = PCF;
assign SelNextSpill = 0;
assign PostSpillInstrRawF = InstrRawF;
end
endgenerate
assign PCFExt = {2'b00, PCFMux}; assign PCFExt = {2'b00, PCFMux};
@ -254,15 +259,13 @@ module ifu (
endgenerate endgenerate
// select between dcache and direct from the BUS. Always selected if no dcache. // select between dcache and direct from the BUS. Always selected if no dcache.
// handled in the busfsm.
mux2 #(32) UnCachedInstrMux(.d0(FinalInstrRawF), mux2 #(32) UnCachedInstrMux(.d0(FinalInstrRawF),
.d1(ICacheMemWriteData[31:0]), .d1(ICacheMemWriteData[31:0]),
.s(SelUncachedAdr), .s(SelUncachedAdr),
.y(InstrRawF)); .y(InstrRawF));
// always present
genvar index; genvar index;
generate generate
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
@ -292,9 +295,6 @@ module ifu (
// uses interlock fsm. // uses interlock fsm.
assign IgnoreRequest = ITLBMissF; assign IgnoreRequest = ITLBMissF;
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD); flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD);