More cleanup of IFU.

This commit is contained in:
Ross Thompson 2022-02-01 14:32:27 -06:00
parent 554df2377e
commit 910d16b642
2 changed files with 66 additions and 115 deletions

View File

@ -35,10 +35,11 @@
module bpred
(input logic clk, reset,
input logic StallF, StallD, StallE,
input logic FlushF, FlushD, FlushE,
input logic StallF, StallD, StallE, StallM,
input logic FlushF, FlushD, FlushE, FlushM,
// Fetch stage
// the prediction
input logic [31:0] InstrD,
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
output logic [`XLEN-1:0] BPPredPCF,
output logic SelBPPredF,
@ -53,13 +54,14 @@ module bpred
input logic [`XLEN-1:0] IEUAdrE, // The branch destination if the branch is taken.
input logic [`XLEN-1:0] PCD, // The address the branch predictor took.
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic [4:0] InstrClassE,
output logic [4:0] InstrClassM,
// Report branch prediction status
output logic BPPredWrongE,
output logic BPPredDirWrongE,
output logic BTBPredPCWrongE,
output logic RASPredPCWrongE,
output logic BPPredClassNonCFIWrongE
output logic BPPredWrongM,
output logic BPPredDirWrongM,
output logic BTBPredPCWrongM,
output logic RASPredPCWrongM,
output logic BPPredClassNonCFIWrongM
);
logic BTBValidF;
@ -71,14 +73,14 @@ module bpred
logic FallThroughWrongE;
logic PredictionPCWrongE;
logic PredictionInstrClassWrongE;
logic [4:0] InstrClassD, InstrClassE;
logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE;
// Part 1 branch direction prediction
if (`BPTYPE == "BPTWOBIT") begin:Predictor
twoBitPredictor DirPredictor(.clk(clk),
.reset(reset),
.StallF(StallF),
twoBitPredictor DirPredictor(.clk, .reset, .StallF,
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
@ -87,58 +89,27 @@ module bpred
.UpdatePrediction(UpdateBPPredE));
end else if (`BPTYPE == "BPGLOBAL") begin:Predictor
globalHistoryPredictor DirPredictor(.clk, .reset, .StallF, .StallE,
.PCNextF, .BPPredF,
.InstrClassE, .BPInstrClassF, .BPInstrClassD, .BPInstrClassE, .BPPredDirWrongE,
.PCE, .PCSrcE, .UpdateBPPredE);
globalHistoryPredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.PCNextF(PCNextF),
.BPPredF(BPPredF),
// update
.InstrClassE(InstrClassE),
.BPInstrClassE(BPInstrClassE),
.BPPredDirWrongE(BPPredDirWrongE),
.PCE(PCE),
.PCSrcE(PCSrcE),
.UpdateBPPredE(UpdateBPPredE));
end else if (`BPTYPE == "BPGSHARE") begin:Predictor
gsharePredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.PCNextF(PCNextF),
.BPPredF(BPPredF),
// update
.InstrClassE(InstrClassE),
.BPInstrClassE(BPInstrClassE),
.BPPredDirWrongE(BPPredDirWrongE),
.PCE(PCE),
.PCSrcE(PCSrcE),
.UpdateBPPredE(UpdateBPPredE));
gsharePredictor DirPredictor(.clk, .reset, .StallF, .StallE,
.PCNextF, .BPPredF,
.InstrClassE, .BPInstrClassF, .BPInstrClassD, .BPInstrClassE, .BPPredDirWrongE,
.PCE, .PCSrcE, .UpdateBPPredE);
end
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
localHistoryPredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
localHistoryPredictor DirPredictor(.clk,
.reset, .StallF, .StallE, .FlushF,
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE),
.UpdatePrediction(UpdateBPPredE));
end
else if (`BPTYPE == "BPLOCALPAg") begin:Predictor
localHistoryPredictor DirPredictor(.clk(clk),
.reset(reset),
.*, // Stalls and flushes
.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE),
.PCSrcE(PCSrcE),
.PCSrcE,
.UpdatePrediction(UpdateBPPredE));
end
@ -201,15 +172,35 @@ module bpred
.d(BPPredD),
.q(BPPredE));
// the branch predictor needs a compact decoding of the instruction class.
// *** consider adding in the alternate return address x5 for returns.
assign InstrClassD[4] = (InstrD[6:0] & 7'h77) == 7'h67 & (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or r5
assign InstrClassD[3] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5
assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01; // jump register, but not return
assign InstrClassD[1] = InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01; // jump, RD != x1 or x5
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
flopenrc #(5) InstrClassRegE(.clk, .reset, .en(~StallE), .clear(FlushE), .d(InstrClassD), .q(InstrClassE));
flopenrc #(5) InstrClassRegM(.clk, .reset, .en(~StallM), .clear(FlushM), .d(InstrClassE), .q(InstrClassM));
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM), .d(BPPredWrongE), .q(BPPredWrongM));
// branch predictor
flopenrc #(4) BPPredWrongRegM(.clk, .reset, .en(~StallM), .clear(FlushM),
.d({BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE}),
.q({BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM}));
// pipeline the class
flopenrc #(5) InstrClassRegD(.clk(clk),
flopenrc #(5) BPInstrClassRegD(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(BPInstrClassF),
.q(BPInstrClassD));
flopenrc #(5) InstrClassRegE(.clk(clk),
flopenrc #(5) BPInstrClassRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),

View File

@ -100,8 +100,6 @@ module ifu (
localparam [31:0] nop = 32'h00000013; // instruction for NOP
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.
logic [`XLEN+1:0] PCFExt;
@ -159,8 +157,7 @@ module ifu (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
end else begin
assign {ITLBMissF, InstrAccessFaultF} = '0;
assign InstrPageFaultF = '0;
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF} = '0;
assign PCPF = PCF;
assign CacheableF = '1;
end
@ -182,22 +179,11 @@ module ifu (
end else begin : bus
localparam integer WORDSPERLINE = `MEM_ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1;
localparam integer LOGWPL = `MEM_ICACHE ? $clog2(WORDSPERLINE) : 1;
localparam integer LINELEN = `MEM_ICACHE ? `ICACHE_LINELENINBITS : `XLEN;
localparam integer WordCountThreshold = `MEM_ICACHE ? WORDSPERLINE - 1 : 0;
localparam integer LINEBYTELEN = LINELEN/8;
localparam integer OFFSETLEN = $clog2(LINEBYTELEN);
logic [LOGWPL-1:0] WordCount;
logic SelUncachedAdr;
logic [LINELEN-1:0] ICacheMemWriteData;
logic [`PA_BITS-1:0] LocalIFUBusAdr;
logic [`PA_BITS-1:0] ICacheBusAdr;
logic ICacheBusAck;
genvar index;
busdp #(WORDSPERLINE, LINELEN)
busdp(.clk, .reset,
@ -226,7 +212,7 @@ module ifu (
.CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess),
.FinalWriteData('0),
.RW(IFURWF),
.Atomic(2'b00), .FlushCache(1'b0),
.Atomic('0), .FlushCache('0),
.NextAdr(PCNextFSpill[11:0]),
.PAdr(PCPF),
.CacheCommitted(), .InvalidateCacheM(InvalidateICacheM));
@ -235,15 +221,10 @@ module ifu (
assign {ICacheFetchLine, ICacheBusAdr, ICacheStallF, FinalInstrRawF} = '0;
assign ICacheAccess = CacheableF; assign ICacheMiss = CacheableF;
end
end
end
// branch predictor signal
logic SelBPPredF;
logic [`XLEN-1:0] BPPredPCF, PCNext0F, PCNext1F, PCNext2F;
logic [4:0] InstrClassD, InstrClassE;
logic [`XLEN-1:0] PCNext1F, PCNext2F;
assign IFUCacheBusStallF = ICacheStallF | BusStall;
assign IFUStallF = IFUCacheBusStallF | SelNextSpillF;
@ -253,14 +234,9 @@ module ifu (
assign PrivilegedChangePCM = RetM | TrapM;
// *** move unnecessary muxes into BPRED_ENABLED
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), .d1(BPPredPCF), .s(SelBPPredF), .y(PCNext0F));
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
// The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE.
mux2 #(`XLEN) pccorrectemux(.d0(PCLinkE), .d1(IEUAdrE), .s(PCSrcE), .y(PCCorrectE));
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), .y(PCNext2F));
// Mux only required on instruction class miss prediction.
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(PCBPWrongInvalidate));
mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), .y(UnalignedPCNextF));
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
@ -268,38 +244,28 @@ module ifu (
// branch and jump predictor
if (`BPRED_ENABLED) begin : bpred
// *** move the rest of this hardware into branch predictor including instruction class registers
logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE;
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM), .d(BPPredWrongE), .q(BPPredWrongM));
logic SelBPPredF;
logic [`XLEN-1:0] BPPredPCF, PCNext0F;
logic BPPredWrongM;
bpred bpred(.clk, .reset,
.StallF, .StallD, .StallE,
.FlushF, .FlushD, .FlushE,
.PCNextF, .BPPredPCF, .SelBPPredF, .PCE, .PCSrcE, .IEUAdrE,
.PCD, .PCLinkE, .InstrClassE, .BPPredWrongE, .BPPredDirWrongE,
.BTBPredPCWrongE, .RASPredPCWrongE, .BPPredClassNonCFIWrongE);
.StallF, .StallD, .StallE, .StallM,
.FlushF, .FlushD, .FlushE, .FlushM,
.InstrD, .PCNextF, .BPPredPCF, .SelBPPredF, .PCE, .PCSrcE, .IEUAdrE,
.PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .BPPredWrongM,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM);
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), .d1(BPPredPCF), .s(SelBPPredF), .y(PCNext0F));
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
// Mux only required on instruction class miss prediction.
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF),
.s(BPPredWrongM), .y(PCBPWrongInvalidate));
// the branch predictor needs a compact decoding of the instruction class.
// *** consider adding in the alternate return address x5 for returns.
assign InstrClassD[4] = (InstrD[6:0] & 7'h77) == 7'h67 & (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or r5
assign InstrClassD[3] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5
assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01; // jump register, but not return
assign InstrClassD[1] = InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01; // jump, RD != x1 or x5
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
// branch predictor
flopenrc #(5) InstrClassRegE(.clk, .reset, .en(~StallE), .clear(FlushE), .d(InstrClassD), .q(InstrClassE));
flopenrc #(5) InstrClassRegM(.clk, .reset, .en(~StallM), .clear(FlushM), .d(InstrClassE), .q(InstrClassM));
flopenrc #(4) BPPredWrongRegM(.clk, .reset, .en(~StallM), .clear(FlushM),
.d({BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE}),
.q({BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM}));
end else begin : bpred
assign BPPredPCF = '0;
assign BPPredWrongE = PCSrcE;
assign BPPredWrongM = '0;
assign {SelBPPredF, BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0;
assign {BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0;
assign PCNext1F = PCPlus2or4F;
assign PCBPWrongInvalidate = PCE;
end
// pcadder
@ -313,16 +279,12 @@ module ifu (
else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10};
else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
// Decode stage pipeline register and logic
flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
// expand 16-bit compressed instructions to 32 bits
decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD);
assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
// *** combine these with others in better way, including M, F
// Misaligned PC logic
// Instruction address misalignement only from br/jal(r) instructions.
@ -336,7 +298,6 @@ module ifu (
// Traps: Cant happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec.
assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE;
flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
// *** Ross Thompson. Check InstrMisalignedAdrM as I believe it is the same as PCF. Should be able to remove.
flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM);
// Instruction and PC/PCLink pipeline registers
@ -347,4 +308,3 @@ module ifu (
flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);
flopenr #(`XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE);
endmodule