Merge branch 'main' of https://github.com/openhwgroup/cvw into dev

This commit is contained in:
David Harris 2023-03-01 11:18:05 -08:00
commit c761fb1054
15 changed files with 386 additions and 274 deletions

View File

@ -1,3 +1,7 @@
#--showoverrides
#--help --helpall
--traceregs
--override cpu/show_c_prefix=T --override cpu/show_c_prefix=T
--override cpu/unaligned=F --override cpu/unaligned=F
--override cpu/ignore_non_leaf_DAU=1 --override cpu/ignore_non_leaf_DAU=1
@ -33,3 +37,6 @@
# ignore settings of bits DAU for non leaf page table walks # ignore settings of bits DAU for non leaf page table walks
--override cpu/ignore_non_leaf_DAU=1 --override cpu/ignore_non_leaf_DAU=1
# mimpid = 0x100
--override cpu/mimpid=0x100

View File

@ -30,7 +30,7 @@
module hazard ( module hazard (
// Detect hazards // Detect hazards
input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM, input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
input logic LSUStallM, IFUStallF, input logic LSUStallM, IFUStallF,
input logic FCvtIntStallD, FPUStallD, input logic FCvtIntStallD, FPUStallD,
@ -65,8 +65,8 @@ module hazard (
// Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents // Similarly, CSR writes and fences flush all subsequent instructions and refetch them in light of the new operating modes and cache/TLB contents
// Branch misprediction is found in the Execute stage and must flush the next two instructions. // Branch misprediction is found in the Execute stage and must flush the next two instructions.
// However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete // However, an active division operation resides in the Execute stage, and when the BP incorrectly mispredicts the divide as a taken branch, the divde must still complete
assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPPredWrongE; assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE;
assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPPredWrongE & ~(DivBusyE | FDivBusyE)); assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE));
assign FlushMCause = TrapM | RetM | CSRWriteFenceM; assign FlushMCause = TrapM | RetM | CSRWriteFenceM;
assign FlushWCause = TrapM; assign FlushWCause = TrapM;

View File

@ -33,11 +33,11 @@ module RASPredictor #(parameter int StackSize = 16 )(
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
input logic WrongBPRetD, // Prediction class is wrong input logic BPReturnWrongD, // Prediction class is wrong
input logic RetD, input logic ReturnD,
input logic RetE, JalE, // Instr class input logic ReturnE, CallE, // Instr class
input logic BPRetF, input logic BPReturnF,
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a jal input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call
output logic [`XLEN-1:0] RASPCF // Top of the stack output logic [`XLEN-1:0] RASPCF // Top of the stack
); );
@ -54,21 +54,21 @@ module RASPredictor #(parameter int StackSize = 16 )(
logic IncrRepairD, DecRepairD; logic IncrRepairD, DecRepairD;
logic DecrementPtr; logic DecrementPtr;
logic FlushedRetDE; logic FlushedReturnDE;
logic WrongPredRetD; logic WrongPredReturnD;
assign PopF = BPRetF & ~StallD & ~FlushD; assign PopF = BPReturnF & ~StallD & ~FlushD;
assign PushE = JalE & ~StallM & ~FlushM; assign PushE = CallE & ~StallM & ~FlushM;
assign WrongPredRetD = (WrongBPRetD) & ~StallE & ~FlushE; assign WrongPredReturnD = (BPReturnWrongD) & ~StallE & ~FlushE;
assign FlushedRetDE = (~StallE & FlushE & RetD) | (~StallM & FlushM & RetE); // flushed ret assign FlushedReturnDE = (~StallE & FlushE & ReturnD) | (~StallM & FlushM & ReturnE); // flushed return
assign RepairD = WrongPredRetD | FlushedRetDE ; assign RepairD = WrongPredReturnD | FlushedReturnDE ;
assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~RetD); // Guessed it was a ret, but its not assign IncrRepairD = FlushedReturnDE | (WrongPredReturnD & ~ReturnD); // Guessed it was a return, but its not
assign DecRepairD = WrongPredRetD & RetD; // Guessed non ret but is a ret. assign DecRepairD = WrongPredReturnD & ReturnD; // Guessed non return but is a return.
assign CounterEn = PopF | PushE | RepairD; assign CounterEn = PopF | PushE | RepairD;

View File

@ -39,7 +39,7 @@ module bpred (
input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class input logic [31:0] InstrD, // Decompressed decode stage instruction. Used to decode instruction class
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4 input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction output logic [`XLEN-1:0] PC1NextF, // Branch Predictor predicted or corrected fetch address on miss prediction
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
// Update Predictor // Update Predictor
@ -58,28 +58,28 @@ module bpred (
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br
output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as call, return, jr (not return), j, br
// Report branch prediction status // Report branch prediction status
output logic BPPredWrongE, // Prediction is wrong output logic BPWrongE, // Prediction is wrong
output logic BPPredWrongM, // Prediction is wrong output logic BPWrongM, // Prediction is wrong
output logic DirPredictionWrongM, // Prediction direction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong
output logic BTBPredPCWrongM, // Prediction target wrong output logic BTBPredPCWrongM, // Prediction target wrong
output logic RASPredPCWrongM, // RAS prediction is wrong output logic RASPredPCWrongM, // RAS prediction is wrong
output logic PredictionInstrClassWrongM // Class prediction is wrong output logic IClassWrongM // Class prediction is wrong
); );
logic [1:0] DirPredictionF; logic [1:0] BPDirPredF;
logic [`XLEN-1:0] BTAF, RASPCF; logic [`XLEN-1:0] BTAF, RASPCF;
logic PredictionPCWrongE; logic BPPCWrongE;
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE; logic IClassWrongE;
logic DirPredictionWrongE; logic BPDirPredWrongE;
logic BPPCSrcF; logic BPPCSrcF;
logic [`XLEN-1:0] BPPredPCF; logic [`XLEN-1:0] BPPCF;
logic [`XLEN-1:0] PCNext0F; logic [`XLEN-1:0] PC0NextF;
logic [`XLEN-1:0] PCCorrectE; logic [`XLEN-1:0] PCCorrectE;
logic [3:0] WrongPredInstrClassD; logic [3:0] WrongPredInstrClassD;
@ -88,44 +88,46 @@ module bpred (
logic [`XLEN-1:0] BTAD; logic [`XLEN-1:0] BTAD;
logic BTBJalF, BTBRetF, BTBJumpF, BTBBranchF; logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPRetF, BPJalF; logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
logic BPBranchD, BPJumpD, BPRetD, BPJalD; logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
logic RetD, JalD; logic ReturnD, CallD;
logic RetE, JalE; logic ReturnE, CallE;
logic BranchM, JumpM, RetM, JalM; logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, RetW, JalW; logic BranchW, JumpW, ReturnW, CallW;
logic WrongBPRetD; logic BPReturnWrongD;
logic [`XLEN-1:0] PCW, IEUAdrW; logic [`XLEN-1:0] BTAE;
// Part 1 branch direction prediction // Part 1 branch direction prediction
// look into the 2 port Sram model. something is wrong. // look into the 2 port Sram model. something is wrong.
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE); .BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor end else if (`BPRED_TYPE == "BP_GSHARE") begin:Predictor
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
.PCSrcE); .PCSrcE);
end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor end else if (`BPRED_TYPE == "BP_GLOBAL") begin:Predictor
gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, gshare #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW,
.PCSrcE); .PCSrcE);
end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor end else if (`BPRED_TYPE == "BP_GSHARE_BASIC") begin:Predictor
gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, gsharebasic #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE); .BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor end else if (`BPRED_TYPE == "BP_GLOBAL_BASIC") begin:Predictor
gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, gsharebasic #(`BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE,
.BranchE, .BranchM, .PCSrcE); .BranchE, .BranchM, .PCSrcE);
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
@ -134,7 +136,7 @@ module bpred (
localHistoryPredictor DirPredictor(.clk, localHistoryPredictor DirPredictor(.clk,
.reset, .StallF, .StallE, .reset, .StallF, .StallE,
.LookUpPC(PCNextF), .LookUpPC(PCNextF),
.Prediction(DirPredictionF), .Prediction(BPDirPredF),
// update // update
.UpdatePC(PCE), .UpdatePC(PCE),
.UpdateEN(InstrClassE[0] & ~StallE), .UpdateEN(InstrClassE[0] & ~StallE),
@ -148,73 +150,25 @@ module bpred (
btb #(`BTB_SIZE) btb #(`BTB_SIZE)
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCW, .PCNextF, .PCF, .PCD, .PCE, .PCM,
.BTAF, .BTAD, .BTAF, .BTAD, .BTAE,
.BTBPredInstrClassF({BTBJalF, BTBRetF, BTBJumpF, BTBBranchF}), .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
.PredictionInstrClassWrongM, .IClassWrongM, .IClassWrongE,
.IEUAdrE, .IEUAdrM, .IEUAdrW, .IEUAdrE, .IEUAdrM,
.InstrClassD({JalD, RetD, JumpD, BranchD}), .InstrClassE({JalE, RetE, JumpE, BranchE}), .InstrClassM({JalM, RetM, JumpM, BranchM}), .InstrClassD({CallD, ReturnD, JumpD, BranchD}),
.InstrClassW({JalW, RetW, JumpW, BranchW})); .InstrClassE({CallE, ReturnE, JumpE, BranchE}),
.InstrClassM({CallM, ReturnM, JumpM, BranchM}),
.InstrClassW({CallW, ReturnW, JumpW, BranchW}));
if (!`INSTR_CLASS_PRED) begin : DirectClassDecode icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
// This section is mainly for testing, verification, and PPA comparison. .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
// An alternative to using the BTB to store the instruction class is to partially decode .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
// the instructions in the Fetch stage into, Jal, Ret, Jump, and Branch instructions. .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
// This logic is not described in the text book as of 23 February 2023.
logic cjal, cj, cjr, cjalr, CJumpF, CBranchF;
logic NCJumpF, NCBranchF;
if(`C_SUPPORTED) begin
logic [4:0] CompressedOpcF;
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
assign cjal = CompressedOpcF == 5'h09 & `XLEN == 32;
assign cj = CompressedOpcF == 5'h0d;
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
assign CJumpF = cjal | cj | cjr | cjalr;
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
end else begin
assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0;
end
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
assign BPRetF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // return must return to ra or r5
(`C_SUPPORTED & (cjalr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
assign BPJalF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // jal(r) must link to ra or x5
(`C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
end else begin
// This section connects the BTB's instruction class prediction.
assign {BPJalF, BPRetF, BPJumpF, BPBranchF} = {BTBJalF, BTBRetF, BTBJumpF, BTBBranchF};
end
assign BPPCSrcF = (BPBranchF & DirPredictionF[1]) | BPJumpF;
// Part 3 RAS // Part 3 RAS
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.BPRetF, .RetD, .RetE, .JalE, .BPReturnF, .ReturnD, .ReturnE, .CallE,
.WrongBPRetD, .RASPCF, .PCLinkE); .BPReturnWrongD, .RASPCF, .PCLinkE);
assign BPPredPCF = BPRetF ? RASPCF : BTAF;
assign RetD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or x5
assign JalD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {JalD, RetD}, {JalE, RetE});
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {JalE, RetE, JumpE, BranchE}, {JalM, RetM, JumpM, BranchM});
flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {JalM, RetM, JumpM, BranchM}, {JalW, RetW, JumpW, BranchW});
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
// branch predictor
flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, AnyWrongPredInstrClassE, PredictionInstrClassWrongM);
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, AnyWrongPredInstrClassD, AnyWrongPredInstrClassE);
// pipeline the predicted class
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPJalF, BPRetF, BPJumpF, BPBranchF}, {BPJalD, BPRetD, BPJumpD, BPBranchD});
// Check the prediction // Check the prediction
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
@ -222,39 +176,31 @@ module bpred (
// this will result in PCD not being equal to the fall through address PCLinkE (PCE+4). // this will result in PCD not being equal to the fall through address PCLinkE (PCE+4).
// The next instruction is always valid as no other flush would occur at the same time as the branch and not // The next instruction is always valid as no other flush would occur at the same time as the branch and not
// also flush the branch. This will change in a superscaler cpu. // also flush the branch. This will change in a superscaler cpu.
assign PredictionPCWrongE = PCCorrectE != PCD;
// branch class prediction wrong.
assign AnyWrongPredInstrClassD = |({BPJalD, BPRetD, BPJumpD, BPBranchD} ^ {JalD, RetD, JumpD, BranchD});
assign WrongBPRetD = BPRetD ^ RetD;
// branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions. // branch is wrong only if the PC does not match and both the Decode and Fetch stages have valid instructions.
assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD; assign BPWrongE = (PCCorrectE != PCD) & InstrValidE & InstrValidD;
flopenrc #(1) BPWrongMReg(clk, reset, FlushM, ~StallM, BPWrongE, BPWrongM);
logic BPPredWrongEAlt;
logic NotMatch;
assign BPPredWrongEAlt = PredictionPCWrongE & InstrValidE & InstrValidD; // this does not work for cubic benchmark
assign NotMatch = BPPredWrongE != BPPredWrongEAlt;
// Output the predicted PC or corrected PC on miss-predict. // Output the predicted PC or corrected PC on miss-predict.
assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF;
mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF);
// Selects the BP or PC+2/4. // Selects the BP or PC+2/4.
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, BPPCSrcF, PCNext0F); mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF);
// If the prediction is wrong select the correct address. // If the prediction is wrong select the correct address.
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F); mux2 #(`XLEN) pcmux1(PC0NextF, PCCorrectE, BPWrongE, PC1NextF);
// Correct branch/jump target. // Correct branch/jump target.
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE); mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE. // If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
// Effectively this is PCM+4 or the non-existant PCLinkM // Effectively this is PCM+4 or the non-existant PCLinkM
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE); if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
else assign NextValidPCE = PCE; else assign NextValidPCE = PCE;
if(`ZICOUNTERS_SUPPORTED) begin if(`ZICOUNTERS_SUPPORTED) begin
logic JumpOrTakenBranchE; logic JumpOrTakenBranchE;
logic [`XLEN-1:0] BTAE, RASPCD, RASPCE; logic [`XLEN-1:0] RASPCD, RASPCE;
logic BTBPredPCWrongE, RASPredPCWrongE; logic BTBPredPCWrongE, RASPredPCWrongE;
// performance counters // performance counters
// 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now // 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
// 3. target ras (ras target wrong / class[2]) // 3. target ras (ras target wrong / class[2])
// 4. direction (br dir wrong / class[0]) // 4. direction (br dir wrong / class[0])
@ -263,29 +209,24 @@ module bpred (
// could be wrong or the fall through address selected for branch predict not taken. // could be wrong or the fall through address selected for branch predict not taken.
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
// both without the above inaccuracies. // both without the above inaccuracies.
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~RetE) & PCSrcE; assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & RetE & PCSrcE; assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE; assign JumpOrTakenBranchE = (BranchE & PCSrcE) | JumpE;
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM); flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE);
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE}, {BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE},
{DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM}); {BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM});
end else begin end else begin
assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0; assign {BTBPredPCWrongM, RASPredPCWrongM, JumpOrTakenBranchM} = '0;
end end
// **** Fix me // **** Fix me
assign InstrClassM = {JalM, RetM, JumpM, BranchM}; assign InstrClassM = {CallM, ReturnM, JumpM, BranchM};
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
endmodule endmodule

View File

@ -34,15 +34,16 @@ module btb #(parameter Depth = 10 ) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW,// PC at various stages input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages
output logic [`XLEN-1:0] BTAF, // BTB's guess at PC output logic [`XLEN-1:0] BTAF, // BTB's guess at PC
output logic [`XLEN-1:0] BTAD, output logic [`XLEN-1:0] BTAD,
output logic [3:0] BTBPredInstrClassF, // BTB's guess at instruction class output logic [`XLEN-1:0] BTAE,
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
// update // update
input logic PredictionInstrClassWrongM, // BTB's instruction class guess was wrong input logic IClassWrongM, // BTB's instruction class guess was wrong
input logic IClassWrongE,
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
input logic [`XLEN-1:0] IEUAdrW,
input logic [3:0] InstrClassD, // Instruction class to insert into btb input logic [3:0] InstrClassD, // Instruction class to insert into btb
input logic [3:0] InstrClassE, // Instruction class to insert into btb input logic [3:0] InstrClassE, // Instruction class to insert into btb
input logic [3:0] InstrClassM, // Instruction class to insert into btb input logic [3:0] InstrClassM, // Instruction class to insert into btb
@ -53,8 +54,12 @@ module btb #(parameter Depth = 10 ) (
logic [`XLEN-1:0] ResetPC; logic [`XLEN-1:0] ResetPC;
logic MatchD, MatchE, MatchM, MatchW, MatchX; logic MatchD, MatchE, MatchM, MatchW, MatchX;
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
logic [`XLEN+3:0] TableBTBPredictionF; logic [`XLEN+3:0] TableBTBPredF;
logic UpdateEn; logic [`XLEN-1:0] IEUAdrW;
logic [`XLEN-1:0] PCW;
logic BTBWrongE, BTAWrongE;
logic BTBWrongM, BTAWrongM;
// hashing function for indexing the PC // hashing function for indexing the PC
// We have Depth bits to index, but XLEN bits as the input. // We have Depth bits to index, but XLEN bits as the input.
@ -84,15 +89,27 @@ module btb #(parameter Depth = 10 ) (
MatchM ? {InstrClassM, IEUAdrM} : MatchM ? {InstrClassM, IEUAdrM} :
{InstrClassW, IEUAdrW} ; {InstrClassW, IEUAdrW} ;
assign {BTBPredInstrClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredictionF}; assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF};
assign UpdateEn = |InstrClassM | PredictionInstrClassWrongM;
// An optimization may be using a PC relative address. // An optimization may be using a PC relative address.
ram2p1r1wbe #(2**Depth, `XLEN+4) memory( ram2p1r1wbe #(2**Depth, `XLEN+4) memory(
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredictionF), .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF),
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(UpdateEn), .bwe2('1)); .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1));
flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD);
// BTAE is not strickly necessary. However it is used by two parts of wally.
// 1. It gates updates to the BTB when the prediction does not change. This save power.
// 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong.
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE);
assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]);
flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM);
assign BTBWrongM = BTAWrongM | IClassWrongM;
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
endmodule endmodule

View File

@ -35,18 +35,18 @@ module gshare #(parameter k = 10,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
output logic [1:0] DirPredictionF, output logic [1:0] BPDirPredF,
output logic DirPredictionWrongE, output logic BPDirPredWrongE,
// update // update
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW, input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
); );
logic MatchF, MatchD, MatchE, MatchM, MatchW; logic MatchF, MatchD, MatchE, MatchM, MatchW;
logic MatchX; logic MatchX;
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE, ForwardNewDirPredictionF; logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;
logic [1:0] NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW;
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
@ -76,33 +76,33 @@ module gshare #(parameter k = 10,
assign MatchW = BranchW & ~FlushW & (IndexF == IndexW); assign MatchW = BranchW & ~FlushW & (IndexF == IndexW);
assign MatchX = MatchD | MatchE | MatchM | MatchW; assign MatchX = MatchD | MatchE | MatchM | MatchW;
assign ForwardNewDirPredictionF = MatchD ? {2{DirPredictionD[1]}} : assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} :
MatchE ? {NewDirPredictionE} : MatchE ? {NewBPDirPredE} :
MatchM ? {NewDirPredictionM} : MatchM ? {NewBPDirPredM} :
NewDirPredictionW ; NewBPDirPredW ;
assign DirPredictionF = MatchX ? ForwardNewDirPredictionF : TableDirPredictionF; assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF;
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
.ce1(~StallF), .ce2(~StallM & ~FlushM), .ce1(~StallF), .ce2(~StallW & ~FlushW),
.ra1(IndexNextF), .ra1(IndexNextF),
.rd1(TableDirPredictionF), .rd1(TableBPDirPredF),
.wa2(IndexM), .wa2(IndexM),
.wd2(NewDirPredictionM), .wd2(NewBPDirPredM),
.we2(BranchM), .we2(BranchM),
.bwe2(1'b1)); .bwe2(1'b1));
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewDirPredictionM, NewDirPredictionW); flopenrc #(2) NewPredictionRegW(clk, reset, FlushW, ~StallW, NewBPDirPredM, NewBPDirPredW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
assign GHRNextF = BPBranchF ? {DirPredictionF[1], GHRF[k-1:1]} : GHRF; assign GHRNextF = BPBranchF ? {BPDirPredF[1], GHRF[k-1:1]} : GHRF;
assign GHRF = BranchD ? {DirPredictionD[1], GHRD[k-1:1]} : GHRD; assign GHRF = BranchD ? {BPDirPredD[1], GHRD[k-1:1]} : GHRD;
assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE; assign GHRD = BranchE ? {PCSrcE, GHRE[k-1:1]} : GHRE;
assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM; assign GHRE = BranchM ? {PCSrcM, GHRM[k-1:1]} : GHRM;

View File

@ -35,16 +35,16 @@ module gsharebasic #(parameter k = 10,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
output logic [1:0] DirPredictionF, output logic [1:0] BPDirPredF,
output logic DirPredictionWrongE, output logic BPDirPredWrongE,
// update // update
input logic [`XLEN-1:0] PCNextF, PCM, input logic [`XLEN-1:0] PCNextF, PCM,
input logic BranchE, BranchM, PCSrcE input logic BranchE, BranchM, PCSrcE
); );
logic [k-1:0] IndexNextF, IndexM; logic [k-1:0] IndexNextF, IndexM;
logic [1:0] DirPredictionD, DirPredictionE; logic [1:0] BPDirPredD, BPDirPredE;
logic [1:0] NewDirPredictionE, NewDirPredictionM; logic [1:0] NewBPDirPredE, NewBPDirPredM;
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
logic [k-1:0] GHRNext; logic [k-1:0] GHRNext;
@ -61,19 +61,19 @@ module gsharebasic #(parameter k = 10,
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
.ce1(~StallF), .ce2(~StallW & ~FlushW), .ce1(~StallF), .ce2(~StallW & ~FlushW),
.ra1(IndexNextF), .ra1(IndexNextF),
.rd1(DirPredictionF), .rd1(BPDirPredF),
.wa2(IndexM), .wa2(IndexM),
.wd2(NewDirPredictionM), .wd2(NewBPDirPredM),
.we2(BranchM), .we2(BranchM),
.bwe2(1'b1)); .bwe2(1'b1));
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR; assign GHRNext = BranchM ? {PCSrcM, GHR[k-1:1]} : GHR;
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR); flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchM, GHRNext, GHR);

106
src/ifu/bpred/icpred.sv Normal file
View File

@ -0,0 +1,106 @@
///////////////////////////////////////////
// icpred.sv
//
// Written: Ross Thomposn ross1728@gmail.com
// Created: February 26, 2023
// Modified: February 26, 2023
//
// Purpose: Partial decode of instructions into control flow instructions (cfi)P
// Call, Return, Jump, and Branch
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module icpred #(parameter INSTR_CLASS_PRED = 1)(
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
input logic [31:0] PostSpillInstrRawF, InstrD, // Instruction
input logic BranchD, BranchE,
input logic JumpD, JumpE,
output logic BranchM, BranchW,
output logic JumpM, JumpW,
output logic CallD, CallE, CallM, CallW,
output logic ReturnD, ReturnE, ReturnM, ReturnW,
input logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF,
output logic BPCallF, BPReturnF, BPJumpF, BPBranchF,
output logic IClassWrongM, BPReturnWrongD, IClassWrongE
);
logic IClassWrongD;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
if (!INSTR_CLASS_PRED) begin : DirectClassDecode
// This section is mainly for testing, verification, and PPA comparison.
// An alternative to using the BTB to store the instruction class is to partially decode
// the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions.
// This logic is not described in the text book as of 23 February 2023.
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
logic NCJumpF, NCBranchF;
if(`C_SUPPORTED) begin
logic [4:0] CompressedOpcF;
assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]};
assign ccall = CompressedOpcF == 5'h09 & `XLEN == 32;
assign cj = CompressedOpcF == 5'h0d;
assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
assign ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0;
assign CJumpF = ccall | cj | cjr | ccallr;
assign CBranchF = CompressedOpcF[4:1] == 4'h7;
end else begin
assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0;
end
assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F;
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
end else begin
// This section connects the BTB's instruction class prediction.
assign {BPCallF, BPReturnF, BPJumpF, BPBranchF} = {BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF};
end
assign ReturnD = JumpD & (InstrD[19:15] & 5'h1B) == 5'h01; // returnurn must returnurn to ra or x5
assign CallD = JumpD & (InstrD[11:7] & 5'h1B) == 5'h01; // call(r) must link to ra or x5
flopenrc #(2) InstrClassRegE(clk, reset, FlushE, ~StallE, {CallD, ReturnD}, {CallE, ReturnE});
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, {CallE, ReturnE, JumpE, BranchE}, {CallM, ReturnM, JumpM, BranchM});
flopenrc #(4) InstrClassRegW(clk, reset, FlushM, ~StallW, {CallM, ReturnM, JumpM, BranchM}, {CallW, ReturnW, JumpW, BranchW});
// branch predictor
flopenrc #(1) BPClassWrongRegM(clk, reset, FlushM, ~StallM, IClassWrongE, IClassWrongM);
flopenrc #(1) WrongInstrClassRegE(clk, reset, FlushE, ~StallE, IClassWrongD, IClassWrongE);
// pipeline the predicted class
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, {BPCallF, BPReturnF, BPJumpF, BPBranchF}, {BPCallD, BPReturnD, BPJumpD, BPBranchD});
// branch class prediction wrong.
assign IClassWrongD = |({BPCallD, BPReturnD, BPJumpD, BPBranchD} ^ {CallD, ReturnD, JumpD, BranchD});
assign BPReturnWrongD = BPReturnD ^ ReturnD;
endmodule

View File

@ -34,8 +34,8 @@ module twoBitPredictor #(parameter k = 10) (
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] PCNextF, PCM, input logic [`XLEN-1:0] PCNextF, PCM,
output logic [1:0] DirPredictionF, output logic [1:0] BPDirPredF,
output logic DirPredictionWrongE, output logic BPDirPredWrongE,
input logic BranchE, BranchM, input logic BranchE, BranchM,
input logic PCSrcE input logic PCSrcE
); );
@ -43,8 +43,8 @@ module twoBitPredictor #(parameter k = 10) (
logic [k-1:0] IndexNextF, IndexM; logic [k-1:0] IndexNextF, IndexM;
logic [1:0] PredictionMemory; logic [1:0] PredictionMemory;
logic DoForwarding, DoForwardingF; logic DoForwarding, DoForwardingF;
logic [1:0] DirPredictionD, DirPredictionE; logic [1:0] BPDirPredD, BPDirPredE;
logic [1:0] NewDirPredictionE, NewDirPredictionM; logic [1:0] NewBPDirPredE, NewBPDirPredM;
// hashing function for indexing the PC // hashing function for indexing the PC
// We have k bits to index, but XLEN bits as the input. // We have k bits to index, but XLEN bits as the input.
@ -57,19 +57,19 @@ module twoBitPredictor #(parameter k = 10) (
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
.ce1(~StallF), .ce2(~StallW & ~FlushW), .ce1(~StallF), .ce2(~StallW & ~FlushW),
.ra1(IndexNextF), .ra1(IndexNextF),
.rd1(DirPredictionF), .rd1(BPDirPredF),
.wa2(IndexM), .wa2(IndexM),
.wd2(NewDirPredictionM), .wd2(NewBPDirPredM),
.we2(BranchM), .we2(BranchM),
.bwe2(1'b1)); .bwe2(1'b1));
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD); flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, BPDirPredF, BPDirPredD);
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE); flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, BPDirPredD, BPDirPredE);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchE; assign BPDirPredWrongE = PCSrcE != BPDirPredE[1] & BranchE;
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(BPDirPredE), .NewState(NewBPDirPredE));
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM); flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewBPDirPredE, NewBPDirPredM);
endmodule endmodule

View File

@ -54,22 +54,22 @@ module ifu (
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
output logic [`XLEN-1:0] PCE, // Execution stage instruction address output logic [`XLEN-1:0] PCE, // Execution stage instruction address
output logic BPPredWrongE, // Prediction is wrong output logic BPWrongE, // Prediction is wrong
output logic BPPredWrongM, // Prediction is wrong output logic BPWrongM, // Prediction is wrong
// Mem // Mem
output logic CommittedF, // I$ or bus memory operation started, delay interrupts output logic CommittedF, // I$ or bus memory operation started, delay interrupts
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
output logic [`XLEN-1:0] PCNext2F, // Selected PC between branch prediction and next valid PC if CSRWriteFence output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
output logic [31:0] InstrD, // The decoded instruction in Decode stage output logic [31:0] InstrD, // The decoded instruction in Decode stage
output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [31:0] InstrM, // The decoded instruction in Memory stage
output logic [`XLEN-1:0] PCM, // Memory stage instruction address output logic [`XLEN-1:0] PCM, // Memory stage instruction address
// branch predictor // branch predictor
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
output logic JumpOrTakenBranchM, output logic JumpOrTakenBranchM,
output logic DirPredictionWrongM, // Prediction direction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong
output logic BTBPredPCWrongM, // Prediction target wrong output logic BTBPredPCWrongM, // Prediction target wrong
output logic RASPredPCWrongM, // RAS prediction is wrong output logic RASPredPCWrongM, // RAS prediction is wrong
output logic PredictionInstrClassWrongM, // Class prediction is wrong output logic IClassWrongM, // Class prediction is wrong
// Faults // Faults
input logic IllegalBaseInstrD, // Illegal non-compressed instruction input logic IllegalBaseInstrD, // Illegal non-compressed instruction
input logic IllegalFPUInstrD, // Illegal FP instruction input logic IllegalFPUInstrD, // Illegal FP instruction
@ -132,7 +132,7 @@ module ifu (
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
logic GatedStallD; // StallD gated by selected next spill logic GatedStallD; // StallD gated by selected next spill
// branch predictor signal // branch predictor signal
logic [`XLEN-1:0] PCNext1F; // Branch predictor next PCF logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF
logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic BusCommittedF; // Bus memory operation in flight, delay interrupts
logic CacheCommittedF; // I$ memory operation started, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts
logic SelIROM; // PMA indicates instruction address is in the IROM logic SelIROM; // PMA indicates instruction address is in the IROM
@ -297,8 +297,8 @@ module ifu (
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED) if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED)
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PCNext2F)); mux2 #(`XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
else assign PCNext2F = PCNext1F; else assign PC2NextF = PC1NextF;
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
@ -330,14 +330,14 @@ module ifu (
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE, .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
.InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE, .InstrD, .PCNextF, .PCPlus2or4F, .PC1NextF, .PCE, .PCM, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCF, .NextValidPCE,
.PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPPredWrongM, .PCD, .PCLinkE, .InstrClassM, .BPWrongE, .PostSpillInstrRawF, .JumpOrTakenBranchM, .BPWrongM,
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM); .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM);
end else begin : bpred end else begin : bpred
mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF));
assign BPPredWrongE = PCSrcE; assign BPWrongE = PCSrcE;
assign {InstrClassM, DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0; assign {InstrClassM, BPDirPredWrongM, BTBPredPCWrongM, RASPredPCWrongM, IClassWrongM} = '0;
assign NextValidPCE = PCE; assign NextValidPCE = PCE;
end end

View File

@ -37,7 +37,7 @@ module csr #(parameter
input logic FlushM, FlushW, input logic FlushM, FlushW,
input logic StallE, StallM, StallW, input logic StallE, StallM, StallW,
input logic [31:0] InstrM, // current instruction input logic [31:0] InstrM, // current instruction
input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return logic input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic
input logic [`XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU input logic [`XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU
input logic CSRReadM, CSRWriteM, // read or write CSR input logic CSRReadM, CSRWriteM, // read or write CSR
input logic TrapM, // trap is occurring input logic TrapM, // trap is occurring
@ -57,11 +57,11 @@ module csr #(parameter
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
// inputs for performance counters // inputs for performance counters
input logic LoadStallD, input logic LoadStallD,
input logic DirPredictionWrongM, input logic BPDirPredWrongM,
input logic BTBPredPCWrongM, input logic BTBPredPCWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic PredictionInstrClassWrongM, input logic IClassWrongM,
input logic BPPredWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic JumpOrTakenBranchM, // actual instruction class input logic JumpOrTakenBranchM, // actual instruction class
input logic DCacheMiss, input logic DCacheMiss,
@ -155,7 +155,7 @@ module csr #(parameter
// A return sets the PC to MEPC or SEPC // A return sets the PC to MEPC or SEPC
assign RetM = mretM | sretM; assign RetM = mretM | sretM;
mux2 #(`XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC); mux2 #(`XLEN) epcmux(SEPC_REGW, MEPC_REGW, mretM, EPC);
mux3 #(`XLEN) pcmux3(PCNext2F, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF); mux3 #(`XLEN) pcmux3(PC2NextF, EPC, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF);
/////////////////////////////////////////// ///////////////////////////////////////////
// CSRWriteValM // CSRWriteValM
@ -259,7 +259,7 @@ module csr #(parameter
if (`ZICOUNTERS_SUPPORTED) begin:counters if (`ZICOUNTERS_SUPPORTED) begin:counters
csrc counters(.clk, .reset, .StallE, .StallM, .FlushM, csrc counters(.clk, .reset, .StallE, .StallM, .FlushM,
.InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM, .InstrValidNotFlushedM, .LoadStallD, .CSRMWriteM,
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .JumpOrTakenBranchM, .BPPredWrongM, .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM, .JumpOrTakenBranchM, .BPWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
.CSRAdrM, .PrivilegeModeW, .CSRWriteValM, .CSRAdrM, .PrivilegeModeW, .CSRWriteValM,
.MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW,

View File

@ -44,11 +44,11 @@ module csrc #(parameter
input logic StallE, StallM, input logic StallE, StallM,
input logic FlushM, input logic FlushM,
input logic InstrValidNotFlushedM, LoadStallD, CSRMWriteM, input logic InstrValidNotFlushedM, LoadStallD, CSRMWriteM,
input logic DirPredictionWrongM, input logic BPDirPredWrongM,
input logic BTBPredPCWrongM, input logic BTBPredPCWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic PredictionInstrClassWrongM, input logic IClassWrongM,
input logic BPPredWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic JumpOrTakenBranchM, // actual instruction class input logic JumpOrTakenBranchM, // actual instruction class
input logic DCacheMiss, input logic DCacheMiss,
@ -86,18 +86,18 @@ module csrc #(parameter
assign CounterEvent[`COUNTERS-1:3] = 0; assign CounterEvent[`COUNTERS-1:3] = 0;
end else begin: cevent // User-defined counters end else begin: cevent // User-defined counters
assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[4] = DirPredictionWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction assign CounterEvent[4] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; // branch predictor wrong target assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; // branch predictor wrong target
assign CounterEvent[7] = JumpOrTakenBranchM & InstrValidNotFlushedM; // jump or taken branch instructions assign CounterEvent[7] = JumpOrTakenBranchM & InstrValidNotFlushedM; // jump or taken branch instructions
assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
assign CounterEvent[9] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions assign CounterEvent[9] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
assign CounterEvent[10] = PredictionInstrClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; // data cache access assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; // data cache access
assign CounterEvent[12] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[12] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[13] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access assign CounterEvent[13] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access
assign CounterEvent[14] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[14] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[15] = BPPredWrongM & InstrValidNotFlushedM; // branch predictor wrong assign CounterEvent[15] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
assign CounterEvent[`COUNTERS-1:16] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions assign CounterEvent[`COUNTERS-1:16] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
end end

View File

@ -38,7 +38,7 @@ module privileged (
input logic [`XLEN-1:0] SrcAM, // GPR register to write input logic [`XLEN-1:0] SrcAM, // GPR register to write
input logic [31:0] InstrM, // Instruction input logic [31:0] InstrM, // Instruction
input logic [`XLEN-1:0] IEUAdrM, // address from IEU input logic [`XLEN-1:0] IEUAdrM, // address from IEU
input logic [`XLEN-1:0] PCM, PCNext2F, // program counter, next PC going to trap/return PC logic input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
// control signals // control signals
input logic InstrValidM, // Current instruction is valid (not flushed) input logic InstrValidM, // Current instruction is valid (not flushed)
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
@ -46,11 +46,11 @@ module privileged (
// processor events for performance counter logging // processor events for performance counter logging
input logic FRegWriteM, // instruction will write floating-point registers input logic FRegWriteM, // instruction will write floating-point registers
input logic LoadStallD, // load instruction is stalling input logic LoadStallD, // load instruction is stalling
input logic DirPredictionWrongM, // branch predictor guessed wrong directoin input logic BPDirPredWrongM, // branch predictor guessed wrong directoin
input logic BTBPredPCWrongM, // branch predictor guessed wrong target input logic BTBPredPCWrongM, // branch predictor guessed wrong target
input logic RASPredPCWrongM, // return adddress stack guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target
input logic PredictionInstrClassWrongM, // branch predictor guessed wrong instruction class input logic IClassWrongM, // branch predictor guessed wrong instruction class
input logic BPPredWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, // actual instruction class input logic [3:0] InstrClassM, // actual instruction class
input logic JumpOrTakenBranchM, // actual instruction class input logic JumpOrTakenBranchM, // actual instruction class
input logic DCacheMiss, // data cache miss input logic DCacheMiss, // data cache miss
@ -121,12 +121,12 @@ module privileged (
// Control and Status Registers // Control and Status Registers
csr csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, csr csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM, .IEUAdrM, .PCNext2F, .InstrM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF,
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
.DirPredictionWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredWrongM, .BPDirPredWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPWrongM,
.PredictionInstrClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM, .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .JumpOrTakenBranchM,
.NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW, .NextPrivilegeModeM, .PrivilegeModeW, .CauseM, .SelHPTW,
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TVM,
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_FS,

View File

@ -66,7 +66,7 @@ module wallypipelinedcore (
logic [`XLEN-1:0] PCFSpill, PCE, PCLinkE; logic [`XLEN-1:0] PCFSpill, PCE, PCLinkE;
logic [`XLEN-1:0] PCM; logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW; logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F; logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidD, InstrValidE, InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
@ -140,11 +140,11 @@ module wallypipelinedcore (
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
logic BPPredWrongE, BPPredWrongM; logic BPWrongE, BPWrongM;
logic DirPredictionWrongM; logic BPDirPredWrongM;
logic BTBPredPCWrongM; logic BTBPredPCWrongM;
logic RASPredPCWrongM; logic RASPredPCWrongM;
logic PredictionInstrClassWrongM; logic IClassWrongM;
logic [3:0] InstrClassM; logic [3:0] InstrClassM;
logic InstrAccessFaultF, HPTWInstrAccessFaultM; logic InstrAccessFaultF, HPTWInstrAccessFaultM;
logic [2:0] LSUHSIZE; logic [2:0] LSUHSIZE;
@ -169,15 +169,15 @@ module wallypipelinedcore (
.InstrValidM, .InstrValidE, .InstrValidD, .InstrValidM, .InstrValidE, .InstrValidD,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
// Fetch // Fetch
.HRDATA, .PCFSpill, .IFUHADDR, .PCNext2F, .HRDATA, .PCFSpill, .IFUHADDR, .PC2NextF,
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE, .IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUHREADY, .IFUHWRITE,
.ICacheAccess, .ICacheMiss, .ICacheAccess, .ICacheMiss,
// Execute // Execute
.PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPPredWrongE, .BPPredWrongM, .PCLinkE, .PCSrcE, .IEUAdrE, .IEUAdrM, .PCE, .BPWrongE, .BPWrongM,
// Mem // Mem
.CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM, .CommittedF, .UnalignedPCNextF, .InvalidateICacheM, .CSRWriteFenceM,
.InstrD, .InstrM, .PCM, .InstrClassM, .DirPredictionWrongM, .JumpOrTakenBranchM, .InstrD, .InstrM, .PCM, .InstrClassM, .BPDirPredWrongM, .JumpOrTakenBranchM,
.BTBPredPCWrongM, .RASPredPCWrongM, .PredictionInstrClassWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .IClassWrongM,
// Faults out // Faults out
.IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, .IllegalBaseInstrD, .IllegalFPUInstrD, .InstrPageFaultF, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM,
// mmu management // mmu management
@ -268,7 +268,7 @@ module wallypipelinedcore (
// global stall and flush control // global stall and flush control
hazard hzu( hazard hzu(
.BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM, .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
.LSUStallM, .IFUStallF, .LSUStallM, .IFUStallF,
.FCvtIntStallD, .FPUStallD, .FCvtIntStallD, .FPUStallD,
@ -284,13 +284,13 @@ module wallypipelinedcore (
privileged priv( privileged priv(
.clk, .reset, .clk, .reset,
.FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW,
.CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PCNext2F, .CSRReadM, .CSRWriteM, .SrcAM, .PCM, .PC2NextF,
.InstrM, .CSRReadValW, .UnalignedPCNextF, .InstrM, .CSRReadValW, .UnalignedPCNextF,
.RetM, .TrapM, .sfencevmaM, .RetM, .TrapM, .sfencevmaM,
.InstrValidM, .CommittedM, .CommittedF, .InstrValidM, .CommittedM, .CommittedF,
.FRegWriteM, .LoadStallD, .FRegWriteM, .LoadStallD,
.DirPredictionWrongM, .BTBPredPCWrongM, .BPPredWrongM, .BPDirPredWrongM, .BTBPredPCWrongM, .BPWrongM,
.RASPredPCWrongM, .PredictionInstrClassWrongM, .RASPredPCWrongM, .IClassWrongM,
.InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrClassM, .JumpOrTakenBranchM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
.InstrMisalignedFaultM, .IllegalIEUFPUInstrD, .InstrMisalignedFaultM, .IllegalIEUFPUInstrD,
@ -304,7 +304,7 @@ module wallypipelinedcore (
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM); .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM);
end else begin end else begin
assign CSRReadValW = 0; assign CSRReadValW = 0;
assign UnalignedPCNextF = PCNext2F; assign UnalignedPCNextF = PC2NextF;
assign RetM = 0; assign RetM = 0;
assign TrapM = 0; assign TrapM = 0;
assign WFIStallM = 0; assign WFIStallM = 0;

View File

@ -137,7 +137,12 @@ module testbench;
.CMP_CSR (1) .CMP_CSR (1)
) idv_trace2api(rvvi); ) idv_trace2api(rvvi);
int PRIV_RWX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE | RVVI_MEMORY_PRIVILEGE_EXEC;
int PRIV_RW = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE;
int PRIV_X = RVVI_MEMORY_PRIVILEGE_EXEC;
initial begin initial begin
MAX_ERRS = 3; MAX_ERRS = 3;
// Initialize REF (do this before initializing the DUT) // Initialize REF (do this before initializing the DUT)
@ -159,6 +164,41 @@ module testbench;
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
// cannot predict this register due to latency between
// pending and taken
void'(rvviRefCsrSetVolatile(0, 32'h344));
rvviRefCsrCompareEnable(0, 32'h344, RVVI_FALSE);
// Memory lo, hi, priv (RVVI_MEMORY_PRIVILEGE_{READ,WRITE,EXEC})
void'(rvviRefMemorySetPrivilege(56'h0, 56'h7fffffffff, 0));
if (`BOOTROM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`BOOTROM_BASE, (`BOOTROM_BASE + `BOOTROM_RANGE), PRIV_X));
if (`UNCORE_RAM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`UNCORE_RAM_BASE, (`UNCORE_RAM_BASE + `UNCORE_RAM_RANGE), PRIV_RWX));
if (`EXT_MEM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`EXT_MEM_BASE, (`EXT_MEM_BASE + `EXT_MEM_RANGE), PRIV_RWX));
if (`CLINT_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE)));
end
if (`GPIO_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE)));
end
if (`UART_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE)));
void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW));
end
if (`PLIC_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE)));
end
if (`SDC_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`SDC_BASE, (`SDC_BASE + `SDC_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE)));
end
if(`XLEN==32) begin if(`XLEN==32) begin
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH
@ -166,14 +206,15 @@ module testbench;
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
end end
// Enable the trace2log module // These should be done in the attached client
if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin // // Enable the trace2log module
msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE)); // if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin
end // msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE));
// end
if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin //
msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE)); // if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin
end // msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE));
// end
end end
final begin final begin