The top level of the branch predictor built and compiles. Does not yet function. Missing the BTB, RAS, and direction prediction tables.

This commit is contained in:
Ross Thompson 2021-02-14 10:47:01 -06:00
parent 67881ff686
commit 8486f426b7
2 changed files with 228 additions and 0 deletions

View File

@ -0,0 +1,170 @@
///////////////////////////////////////////
// bpred.sv
//
// Written: Ross Thomposn
// Email: ross1728@gmail.com
// Created: February 12, 2021
// Modified:
//
// Purpose: Branch prediction unit
// Produces a branch prediction based on branch history.
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module bpred
(input logic clk, reset,
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
// Fetch stage
// the prediction
input [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
output [`XLEN-1:0] BPPredPCF,
output SelBPPredF,
input [31:0] InstrF, // we are going to use the opcode to indicate what type instruction this is.
// if this is too slow we will have to predict the type of instruction.
// Execute state
// Update Predictor
input [`XLEN-1:0] PCE, // The address of the currently executing instruction
// 1 hot encoding
// return, jump register, jump, branch
// *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class.
// *** the specifics of how this is encode is subject to change.
input PCSrcE, // AKA Branch Taken
// Signals required to check the branch prediction accuracy.
input [`XLEN-1:0] PCTargetE, // The branch destination if the branch is taken.
input [`XLEN-1:0] PCD, // The address the branch predictor took.
input [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
// Report branch prediction status
output BPPredWrongE
);
logic BTBValidF;
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
logic [3:0] InstrClassD, InstrClassF, InstrClassE;
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
logic TargetWrongE;
logic FallThroughWrongE;
logic PredictionDirWrongE;
logic PredictionPCWrongE;
// Part 1 decode the instruction class.
// *** for now I'm skiping the compressed instructions
assign InstrClassF[3] = InstrF[5:0] == 7'h67 && InstrF[19:15] == 5'h01; // return
// This is probably too much logic.
// *** This also encourages me to switch to predicting the class.
assign InstrClassF[2] = InstrF[5:0] == 7'h67 && InstrF[19:15] == 5'h01; // jump register, but not return
assign InstrClassF[1] = InstrF[5:0] == 7'h6F; // jump
assign InstrClassF[0] = InstrF[5:0] == 7'h63; // branch
// Part 2 branch direction prediction
twoBitPredictor predictor(.LookUpPC(PCNextF),
.Prediction(BPPredF),
// update
.UpdatePC(PCE),
.UpdateEN(InstrClassE[0]),
.UpdatePrediction(UpdateBPPredE));
// 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 built it's next state.
// For a 2 bit table this is the prediction count.
assign SelBPPredF = ((InstrClassF[0] & BPPredF[1]) |
InstrClassF[3] |
(InstrClassF[2]) |
InstrClassF[1]) & BTBValidF;
// Part 3 Branch target address prediction
// *** For now the BTB will house the direct and indirect targets
BTBPredictor targetPredictor(.LookUpPC(PCNextF),
.TargetPC(BTBPredPCF),
.Valid(BTBValidF),
// update
.UpdateEN(InstrClassE[2] | InstrClassE[1] | InstrClassE[0]),
.UpdatePC(PCE),
.UpdateTarget(PCTargetE));
// Part 4 RAS
RASPredictor RASPredictor(.pop(InstrClassF[3]),
.popPC(RASPCF),
.push(InstrClassE[3]),
.pushPC(PCLinkE));
assign BPPredPCF = InstrClassF[3] ? RASPCF : BTBPredPCF;
// The prediction and its results need to be passed through the pipeline
// *** for other predictors will will be different.
flopenrc #(2) BPPredRegD(.clk(clk),
.reset(reset),
.en(~StallF),
.clear(FlushF),
.d(BPPredF),
.Q(BPPredD));
flopenrc #(2) BPPredRegE(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(BPPredD),
.Q(BPPredE));
// pipeline the class
flopenrc #(4) InstrClassRegD(.clk(clk),
.reset(reset),
.en(~StallF),
.clear(FlushF),
.d(InstrClassF),
.q(InstrClassD));
flopenr #(4) InstrClassRegE(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(flushD),
.d(InstrClassD),
.q(InstrClassE));
// Check the prediction makes execution.
assign TargetWrongE = PCTargetE != PCD;
assign FallThroughWrongE = PCLinkE != PCD;
assign PredictionDirWrongE = BPPredE ^ PCSrcE;
assign PredictionPCWrongE = PCSrcE ? TargetWrongE : FallThroughWrongE;
assign BPPredWrongE = PredictionPCWrongE | PredictionDirWrongE;
// Update predictors
satCounter2 BPDirUpdate(.BrDir(~PredictionDirWrongE),
.OldState(BPPredE),
.NewState(UpdateBPPredE));

View File

@ -0,0 +1,58 @@
///////////////////////////////////////////
// satCounter2.sv
//
// Written: Ross Thomposn
// Email: ross1728@gmail.com
// Created: February 13, 2021
// Modified:
//
// Purpose: 2 bit starting counter
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module satCounter2
(input logic BrDir,
input logic Decr,
input logic [1:0] OldState,
output logic [1:0] NewState
);
always_comb begin
case(OldState)
2'b00: begin
if(BrDir) NewState = 2'b01;
else NewState = 2'b00;
end
2'b01: begin
if(BrDir) NewState = 2'b10;
else NewState = 2'b00;
end
2'b10: begin
if(BrDir) NewState = 2'b11;
else NewState = 2'b01;
end
2'b11: begin
if(BrDir) NewState = 2'b11;
else NewState = 2'b10;
end
endcase
end
endmodule