mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 02:05:21 +00:00
Created copy of gshare. I think there may be a simpler implementation.
This commit is contained in:
parent
10b45ed6c7
commit
c18ac35332
@ -76,7 +76,6 @@ module bpred (
|
|||||||
logic [`XLEN-1:0] PredPCF, RASPCF;
|
logic [`XLEN-1:0] PredPCF, RASPCF;
|
||||||
logic PredictionPCWrongE;
|
logic PredictionPCWrongE;
|
||||||
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
|
logic AnyWrongPredInstrClassD, AnyWrongPredInstrClassE;
|
||||||
logic [3:0] InstrClassF;
|
|
||||||
logic [3:0] InstrClassD;
|
logic [3:0] InstrClassD;
|
||||||
logic [3:0] InstrClassE;
|
logic [3:0] InstrClassE;
|
||||||
logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE;
|
logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE;
|
||||||
@ -177,7 +176,7 @@ module bpred (
|
|||||||
|
|
||||||
assign PredInstrClassF = InstrClassF;
|
assign PredInstrClassF = InstrClassF;
|
||||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
||||||
PredInstrClassF[1] |
|
PredInstrClassF[1];
|
||||||
end else begin
|
end else begin
|
||||||
assign PredInstrClassF = BTBPredInstrClassF;
|
assign PredInstrClassF = BTBPredInstrClassF;
|
||||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1] & PredValidF) |
|
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1] & PredValidF) |
|
||||||
@ -224,7 +223,7 @@ module bpred (
|
|||||||
|
|
||||||
// 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 & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE));
|
assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE | (AnyWrongPredInstrClassE & ~|InstrClassE));
|
||||||
//assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD;
|
//assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD; // this does not work for cubic benchmark
|
||||||
|
|
||||||
// Output the predicted PC or corrected PC on miss-predict.
|
// Output the predicted PC or corrected PC on miss-predict.
|
||||||
// Selects the BP or PC+2/4.
|
// Selects the BP or PC+2/4.
|
||||||
@ -263,302 +262,3 @@ module bpred (
|
|||||||
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
/* -----\/----- EXCLUDED -----\/-----
|
|
||||||
///////////////////////////////////////////
|
|
||||||
// bpred.sv
|
|
||||||
//
|
|
||||||
// Written: Ross Thomposn ross1728@gmail.com
|
|
||||||
// Created: 12 February 2021
|
|
||||||
// Modified: 19 January 2023
|
|
||||||
//
|
|
||||||
// Purpose: Branch direction prediction and jump/branch target prediction.
|
|
||||||
// Prediction made during the fetch stage and corrected in the execution stage.
|
|
||||||
//
|
|
||||||
// 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"
|
|
||||||
|
|
||||||
`define INSTR_CLASS_PRED 1
|
|
||||||
|
|
||||||
module bpred (
|
|
||||||
input logic clk, reset,
|
|
||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
|
||||||
// Fetch stage
|
|
||||||
// the prediction
|
|
||||||
input logic InstrValidD, InstrValidE,
|
|
||||||
input logic BranchD, BranchE,
|
|
||||||
input logic JumpD, JumpE,
|
|
||||||
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] 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] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
|
|
||||||
|
|
||||||
// Update Predictor
|
|
||||||
input logic [`XLEN-1:0] PCF, // Fetch stage instruction address
|
|
||||||
input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took
|
|
||||||
input logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
|
||||||
input logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
|
||||||
|
|
||||||
input logic [31:0] PostSpillInstrRawF, // Instruction
|
|
||||||
|
|
||||||
// Branch and jump outcome
|
|
||||||
input logic PCSrcE, // Executation stage branch is taken
|
|
||||||
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target 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 JumpOrTakenBranchM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
|
||||||
|
|
||||||
// Report branch prediction status
|
|
||||||
output logic BPPredWrongE, // Prediction is wrong
|
|
||||||
output logic BPPredWrongM, // Prediction is wrong
|
|
||||||
output logic DirPredictionWrongM, // Prediction direction is wrong
|
|
||||||
output logic BTBPredPCWrongM, // Prediction target wrong
|
|
||||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
|
||||||
output logic PredictionInstrClassWrongM // Class prediction is wrong
|
|
||||||
);
|
|
||||||
|
|
||||||
logic PredValidF;
|
|
||||||
logic [1:0] DirPredictionF;
|
|
||||||
|
|
||||||
logic [3:0] BTBPredInstrClassF, PredInstrClassF, PredInstrClassD, PredInstrClassE;
|
|
||||||
logic [`XLEN-1:0] PredPCF, RASPCF;
|
|
||||||
logic TargetWrongE;
|
|
||||||
logic FallThroughWrongE;
|
|
||||||
logic PredictionPCWrongE;
|
|
||||||
logic PredictionInstrClassWrongE;
|
|
||||||
logic [3:0] InstrClassF, InstrClassD, InstrClassE, InstrClassW;
|
|
||||||
logic DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE;
|
|
||||||
|
|
||||||
logic SelBPPredF;
|
|
||||||
logic [`XLEN-1:0] BPPredPCF;
|
|
||||||
logic [`XLEN-1:0] PCNext0F;
|
|
||||||
logic [`XLEN-1:0] PCCorrectE;
|
|
||||||
logic [3:0] WrongPredInstrClassD;
|
|
||||||
|
|
||||||
|
|
||||||
logic BTBTargetWrongE;
|
|
||||||
logic RASTargetWrongE;
|
|
||||||
logic JumpOrTakenBranchE;
|
|
||||||
|
|
||||||
logic [`XLEN-1:0] PredPCD, PredPCE, RASPCD, RASPCE;
|
|
||||||
|
|
||||||
// Part 1 branch direction prediction
|
|
||||||
// look into the 2 port Sram model. something is wrong.
|
|
||||||
if (`BPRED_TYPE == "BPTWOBIT") begin:Predictor
|
|
||||||
twoBitPredictor #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
|
||||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
|
||||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BPGLOBAL") begin:Predictor
|
|
||||||
globalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
|
||||||
.PCNextF, .PCM, .DirPredictionF, .DirPredictionWrongE,
|
|
||||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
|
||||||
|
|
||||||
/-* -----\/----- EXCLUDED -----\/-----
|
|
||||||
end else if (`BPRED_TYPE == "BPSPECULATIVEGLOBAL") begin:Predictor
|
|
||||||
speculativeglobalhistory #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
|
||||||
.DirPredictionF, .DirPredictionWrongE,
|
|
||||||
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]),
|
|
||||||
.BranchInstrW(InstrClassW[0]), .WrongPredInstrClassD, .PCSrcE);
|
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BPGSHARE") begin:Predictor
|
|
||||||
gshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
|
||||||
.PCNextF, .PCE, .DirPredictionF, .DirPredictionWrongE,
|
|
||||||
.BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PCSrcE);
|
|
||||||
-----/\----- EXCLUDED -----/\----- *-/
|
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor
|
|
||||||
speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
|
||||||
.PCNextF, .PCF, .PCD, .PCE, .DirPredictionF, .DirPredictionWrongE,
|
|
||||||
.PredInstrClassF, .InstrClassD, .InstrClassE, .InstrClassM, .WrongPredInstrClassD, .PCSrcE);
|
|
||||||
|
|
||||||
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
|
|
||||||
// *** Fix me
|
|
||||||
/-* -----\/----- EXCLUDED -----\/-----
|
|
||||||
localHistoryPredictor DirPredictor(.clk,
|
|
||||||
.reset, .StallF, .StallE,
|
|
||||||
.LookUpPC(PCNextF),
|
|
||||||
.Prediction(DirPredictionF),
|
|
||||||
// update
|
|
||||||
.UpdatePC(PCE),
|
|
||||||
.UpdateEN(InstrClassE[0] & ~StallE),
|
|
||||||
.PCSrcE,
|
|
||||||
.UpdatePrediction(InstrClassE[0]));
|
|
||||||
-----/\----- EXCLUDED -----/\----- *-/
|
|
||||||
end
|
|
||||||
|
|
||||||
// this predictor will have two pieces of data,
|
|
||||||
// 1) A direction (1 = Taken, 0 = Not Taken)
|
|
||||||
// 2) Any information which is necessary for the predictor to build its next state.
|
|
||||||
// For a 2 bit table this is the prediction count.
|
|
||||||
|
|
||||||
// Part 2 Branch target address prediction
|
|
||||||
// *** For now the BTB will house the direct and indirect targets
|
|
||||||
|
|
||||||
btb TargetPredictor(.clk, .reset, .StallF, .StallD, .StallM, .FlushD, .FlushM,
|
|
||||||
.PCNextF, .PCF, .PCD, .PCE,
|
|
||||||
.PredPCF,
|
|
||||||
.BTBPredInstrClassF,
|
|
||||||
.PredValidF,
|
|
||||||
.AnyWrongPredInstrClassE(PredictionInstrClassWrongE),
|
|
||||||
.IEUAdrE,
|
|
||||||
.InstrClassD,
|
|
||||||
.InstrClassE);
|
|
||||||
|
|
||||||
// the branch predictor needs a compact decoding of the instruction class.
|
|
||||||
if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode
|
|
||||||
logic [4:0] CompressedOpcF;
|
|
||||||
logic [3:0] InstrClassF;
|
|
||||||
logic cjal, cj, cjr, cjalr;
|
|
||||||
|
|
||||||
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 InstrClassF[0] = PostSpillInstrRawF[6:0] == 7'h63 |
|
|
||||||
(`C_SUPPORTED & CompressedOpcF[4:1] == 4'h7);
|
|
||||||
|
|
||||||
assign InstrClassF[1] = (PostSpillInstrRawF[6:0] == 7'h67 & (PostSpillInstrRawF[19:15] & 5'h1B) != 5'h01 & (PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01) | // jump register, but not return
|
|
||||||
(PostSpillInstrRawF[6:0] == 7'h6F & (PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01) | // jump, RD != x1 or x5
|
|
||||||
(`C_SUPPORTED & (cj | (cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) != 5'h01)) ));
|
|
||||||
|
|
||||||
assign InstrClassF[2] = PostSpillInstrRawF[6:0] == 7'h67 & (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 InstrClassF[3] = ((PostSpillInstrRawF[6:0] & 7'h77) == 7'h67 & (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)));
|
|
||||||
assign PredInstrClassF = InstrClassF;
|
|
||||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1]) |
|
|
||||||
PredInstrClassF[2] |
|
|
||||||
PredInstrClassF[1] |
|
|
||||||
PredInstrClassF[3];
|
|
||||||
end else begin
|
|
||||||
assign PredInstrClassF = BTBPredInstrClassF;
|
|
||||||
assign SelBPPredF = (PredInstrClassF[0] & DirPredictionF[1] & PredValidF) |
|
|
||||||
PredInstrClassF[2] |
|
|
||||||
(PredInstrClassF[1] & PredValidF) |
|
|
||||||
(PredInstrClassF[3] & PredValidF);
|
|
||||||
end
|
|
||||||
|
|
||||||
// Part 3 RAS
|
|
||||||
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
|
||||||
.PredInstrClassF, .InstrClassD, .InstrClassE,
|
|
||||||
.WrongPredInstrClassD, .RASPCF, .PCLinkE);
|
|
||||||
|
|
||||||
assign BPPredPCF = PredInstrClassF[2] ? RASPCF : PredPCF;
|
|
||||||
|
|
||||||
assign InstrClassD[3] = (InstrD[6:0] & 7'h77) == 7'h67 & (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
|
|
||||||
assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5
|
|
||||||
assign InstrClassD[1] = (InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01) | // jump register, but not return
|
|
||||||
(InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01); // jump, RD != x1 or x5
|
|
||||||
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
|
|
||||||
|
|
||||||
flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
|
|
||||||
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
|
|
||||||
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
|
|
||||||
flopenrc #(1) JumpOrTakenBranchMReg(clk, reset, FlushM, ~StallM, JumpOrTakenBranchE, JumpOrTakenBranchM);
|
|
||||||
|
|
||||||
// branch predictor
|
|
||||||
flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
|
||||||
{DirPredictionWrongE, BTBPredPCWrongE, RASPredPCWrongE, PredictionInstrClassWrongE},
|
|
||||||
{DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM});
|
|
||||||
|
|
||||||
// pipeline the class
|
|
||||||
flopenrc #(4) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD);
|
|
||||||
flopenrc #(4) PredInstrClassRegE(clk, reset, FlushE, ~StallE, PredInstrClassD, PredInstrClassE);
|
|
||||||
|
|
||||||
// Check the prediction
|
|
||||||
// first check if the target or fallthrough address matches what was predicted.
|
|
||||||
assign TargetWrongE = IEUAdrE != PCD;
|
|
||||||
assign FallThroughWrongE = PCLinkE != PCD;
|
|
||||||
// If the target is taken check the target rather than fallthrough. The instruction needs to be a branch if PCSrcE is selected
|
|
||||||
// Remember the bpred can incorrectly predict a non cfi instruction as a branch taken. If the real instruction is non cfi
|
|
||||||
// it must have selected the fall through.
|
|
||||||
assign PredictionPCWrongE = PCCorrectE != PCD;
|
|
||||||
|
|
||||||
// assign PredictionPCWrongE = (PCSrcE & (|InstrClassE) ? TargetWrongE : FallThroughWrongE);
|
|
||||||
|
|
||||||
// The branch direction also need to checked.
|
|
||||||
// However if the direction is wrong then the pc will be wrong. This is only relavent to checking the
|
|
||||||
// accuracy of the direciton prediction.
|
|
||||||
//assign DirPredictionWrongE = (BPPredE[1] ^ PCSrcE) & InstrClassE[0];
|
|
||||||
|
|
||||||
// Finally we need to check if the class is wrong. When the class is wrong the BTB needs to be updated.
|
|
||||||
// Also we want to track this in a performance counter.
|
|
||||||
assign PredictionInstrClassWrongE = InstrClassE != PredInstrClassE;
|
|
||||||
|
|
||||||
// We want to output to the instruction fetch if the PC fetched was wrong. If by chance the predictor was wrong about
|
|
||||||
// the direction or class, but correct about the target we don't have the flush the pipeline. However we still
|
|
||||||
// need this information to verify the accuracy of the predictors.
|
|
||||||
assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE) | BPPredClassNonCFIWrongE;
|
|
||||||
// assign BPPredWrongE = PredictionPCWrongE & InstrValidE & InstrValidD;
|
|
||||||
|
|
||||||
// If we have a jump, jump register or jal or jalr and the PC is wrong we need to increment the performance counter.
|
|
||||||
//assign BTBPredPCWrongE = (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PredictionPCWrongE;
|
|
||||||
//assign BTBPredPCWrongE = TargetWrongE & (InstrClassE[3] | InstrClassE[1] | InstrClassE[0]) & PCSrcE;
|
|
||||||
assign BTBPredPCWrongE = BTBTargetWrongE;
|
|
||||||
|
|
||||||
// similar with RAS. Over counts ras if the class prediction was wrong.
|
|
||||||
//assign RASPredPCWrongE = TargetWrongE & InstrClassE[2] & PCSrcE;
|
|
||||||
assign RASPredPCWrongE = RASTargetWrongE;
|
|
||||||
// Finally if the real instruction class is non CFI but the predictor said it was we need to count.
|
|
||||||
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
|
|
||||||
|
|
||||||
// branch class prediction wrong.
|
|
||||||
assign WrongPredInstrClassD = PredInstrClassD ^ InstrClassD;
|
|
||||||
|
|
||||||
// Selects the BP or PC+2/4.
|
|
||||||
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
|
|
||||||
// If the prediction is wrong select the correct address.
|
|
||||||
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F);
|
|
||||||
// Correct branch/jump target.
|
|
||||||
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// if(`BPCLASS) begin
|
|
||||||
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
|
|
||||||
// end else begin
|
|
||||||
// assign NextValidPCE = PCE;
|
|
||||||
// end
|
|
||||||
|
|
||||||
// performance counters
|
|
||||||
// 1. class (class wrong / minstret) (PredictionInstrClassWrongM / csr) // Correct now
|
|
||||||
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
|
|
||||||
// 3. target ras (ras target wrong / class[2])
|
|
||||||
// 4. direction (br dir wrong / class[0])
|
|
||||||
|
|
||||||
assign BTBTargetWrongE = (PredPCE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] | InstrClassE[3]) & PCSrcE;
|
|
||||||
assign RASTargetWrongE = (RASPCE != IEUAdrE) & InstrClassE[2] & PCSrcE;
|
|
||||||
|
|
||||||
assign JumpOrTakenBranchE = (InstrClassE[0] & PCSrcE) | InstrClassE[1] | InstrClassE[3];
|
|
||||||
|
|
||||||
flopenrc #(`XLEN) BTBTargetDReg(clk, reset, FlushD, ~StallD, PredPCF, PredPCD);
|
|
||||||
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, PredPCD, PredPCE);
|
|
||||||
|
|
||||||
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
|
||||||
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
-----/\----- EXCLUDED -----/\----- */
|
|
||||||
|
80
src/ifu/bpred/gshare_copy.sv
Normal file
80
src/ifu/bpred/gshare_copy.sv
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// globalHistoryPredictor.sv
|
||||||
|
//
|
||||||
|
// Written: Shreya Sanghai
|
||||||
|
// Email: ssanghai@hmc.edu
|
||||||
|
// Created: March 16, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Global History Branch predictor with parameterized global history register
|
||||||
|
//
|
||||||
|
// 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 gshare_copy #(parameter k = 10) (
|
||||||
|
input logic clk,
|
||||||
|
input logic reset,
|
||||||
|
input logic StallF, StallD, StallE, StallM,
|
||||||
|
input logic FlushD, FlushE, FlushM,
|
||||||
|
output logic [1:0] DirPredictionF,
|
||||||
|
output logic DirPredictionWrongE,
|
||||||
|
// update
|
||||||
|
input logic [`XLEN-1:0] PCNextF, PCE,
|
||||||
|
input logic BranchInstrE, BranchInstrM, PCSrcE
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [k-1:0] IndexNextF, IndexE;
|
||||||
|
logic [1:0] DirPredictionD, DirPredictionE;
|
||||||
|
logic [1:0] NewDirPredictionE, NewDirPredictionM;
|
||||||
|
|
||||||
|
logic [k-1:0] GHRF, GHRD, GHRE, GHR;
|
||||||
|
logic [k-1:0] GHRNext;
|
||||||
|
logic PCSrcM;
|
||||||
|
|
||||||
|
assign IndexNextF = GHR & {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
|
||||||
|
assign IndexE = GHRE & {PCE[k+1] ^ PCE[1], PCE[k:2]};
|
||||||
|
|
||||||
|
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),
|
||||||
|
.ce1(~StallF), .ce2(~StallM & ~FlushM),
|
||||||
|
.ra1(IndexNextF),
|
||||||
|
.rd1(DirPredictionF),
|
||||||
|
.wa2(IndexE),
|
||||||
|
.wd2(NewDirPredictionE),
|
||||||
|
.we2(BranchInstrE & ~StallM & ~FlushM),
|
||||||
|
.bwe2(1'b1));
|
||||||
|
|
||||||
|
flopenrc #(2) PredictionRegD(clk, reset, FlushD, ~StallD, DirPredictionF, DirPredictionD);
|
||||||
|
flopenrc #(2) PredictionRegE(clk, reset, FlushE, ~StallE, DirPredictionD, DirPredictionE);
|
||||||
|
|
||||||
|
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
|
||||||
|
flopenrc #(2) NewPredictionRegM(clk, reset, FlushM, ~StallM, NewDirPredictionE, NewDirPredictionM);
|
||||||
|
|
||||||
|
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
|
||||||
|
|
||||||
|
assign GHRNext = BranchInstrM ? {PCSrcM, GHR[k-1:1]} : GHR;
|
||||||
|
flopenr #(k) GHRReg(clk, reset, ~StallM & ~FlushM & BranchInstrM, GHRNext, GHR);
|
||||||
|
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM);
|
||||||
|
|
||||||
|
flopenrc #(k) GHRFReg(clk, reset, FlushD, ~StallF, GHR, GHRF);
|
||||||
|
flopenrc #(k) GHRDReg(clk, reset, FlushD, ~StallD, GHRF, GHRD);
|
||||||
|
flopenrc #(k) GHREReg(clk, reset, FlushE, ~StallE, GHRD, GHRE);
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
@ -50,9 +50,9 @@ string tvpaths[] = '{
|
|||||||
|
|
||||||
string embench[] = '{
|
string embench[] = '{
|
||||||
`EMBENCH,
|
`EMBENCH,
|
||||||
|
"bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches
|
||||||
"bd_speedopt_speed/src/aha-mont64/aha-mont64",
|
"bd_speedopt_speed/src/aha-mont64/aha-mont64",
|
||||||
"bd_speedopt_speed/src/crc32/crc32",
|
"bd_speedopt_speed/src/crc32/crc32",
|
||||||
"bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches
|
|
||||||
"bd_speedopt_speed/src/edn/edn",
|
"bd_speedopt_speed/src/edn/edn",
|
||||||
"bd_speedopt_speed/src/huffbench/huffbench",
|
"bd_speedopt_speed/src/huffbench/huffbench",
|
||||||
"bd_speedopt_speed/src/matmult-int/matmult-int",
|
"bd_speedopt_speed/src/matmult-int/matmult-int",
|
||||||
|
Loading…
Reference in New Issue
Block a user