mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 10:15:19 +00:00
More cleanup of IFU.
This commit is contained in:
parent
554df2377e
commit
910d16b642
@ -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),
|
||||
|
@ -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));
|
||||
@ -237,13 +223,8 @@ module ifu (
|
||||
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);
|
||||
|
||||
// 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}));
|
||||
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));
|
||||
|
||||
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: Can’t 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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user