forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/openhwgroup/cvw into dev
This commit is contained in:
commit
c761fb1054
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
106
src/ifu/bpred/icpred.sv
Normal 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
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user