diff --git a/pipelined/src/generic/mem/ram2p1rwbefix.sv b/pipelined/src/generic/mem/ram2p1rwbefix.sv new file mode 100644 index 000000000..5ff6d397f --- /dev/null +++ b/pipelined/src/generic/mem/ram2p1rwbefix.sv @@ -0,0 +1,75 @@ +/////////////////////////////////////////// +// 1 port sram. +// +// Written: ross1728@gmail.com May 3, 2021 +// Basic sram with 1 read write port. +// When clk rises Addr and LineWriteData are sampled. +// Following the clk edge read data is output from the sampled Addr. +// Write +// +// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words + +`include "wally-config.vh" + +module ram2p1r1wbefix #(parameter DEPTH=128, WIDTH=256) ( + input logic clk, + input logic ce1, ce2, + input logic [$clog2(DEPTH)-1:0] ra1, + input logic [WIDTH-1:0] wd2, + input logic [$clog2(DEPTH)-1:0] wa2, + input logic we2, + input logic [(WIDTH-1)/8:0] bwe2, + output logic [WIDTH-1:0] rd1); + + logic [WIDTH-1:0] mem[DEPTH-1:0]; + + // *************************************************************************** + // TRUE Smem macro + // *************************************************************************** + + // *************************************************************************** + // READ first SRAM model + // *************************************************************************** + integer i; + + // Read + always @(posedge clk) + if(ce1) rd1 <= #1 mem[ra1]; + + // Write divided into part for bytes and part for extra msbs + if(WIDTH >= 8) + always @(posedge clk) + if (ce2 & we2) + for(i = 0; i < WIDTH/8; i++) + if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8]; + + if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8 + always @(posedge clk) + if (ce2 & we2 & bwe2[WIDTH/8]) + mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8]; + +endmodule diff --git a/pipelined/src/ifu/globalhistory.sv b/pipelined/src/ifu/globalhistory.sv new file mode 100644 index 000000000..24a0110e1 --- /dev/null +++ b/pipelined/src/ifu/globalhistory.sv @@ -0,0 +1,86 @@ +/////////////////////////////////////////// +// 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 Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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 globalhistory + #(parameter int k = 10 + ) + (input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, + input logic FlushD, FlushE, FlushM, +// input logic [`XLEN-1:0] LookUpPC, + output logic [1:0] DirPredictionF, + output logic DirPredictionWrongE, + // update + input logic [`XLEN-1:0] PCNextF, PCM, + input logic BranchInstrE, BranchInstrM, PCSrcE + ); + + logic [1:0] DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionE, NewDirPredictionM; + + logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; + logic [k-1:0] GHRNext; + logic PCSrcM; + + + ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), + .ce1(~StallF), .ce2(~StallM & ~FlushM), + .ra1(GHR), + .rd1(DirPredictionF), + .wa2(GHRM), + .wd2(NewDirPredictionM), + .we2(BranchInstrM & ~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); + flopenrc #(k) GHRMReg(clk, reset, FlushM, ~StallM, GHRE, GHRM); + + +endmodule diff --git a/pipelined/src/ifu/gshare.sv b/pipelined/src/ifu/gshare.sv new file mode 100644 index 000000000..d5c5fec17 --- /dev/null +++ b/pipelined/src/ifu/gshare.sv @@ -0,0 +1,88 @@ +/////////////////////////////////////////// +// 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 Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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 gshare + #(parameter int k = 10 + ) + (input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, + input logic FlushD, FlushE, FlushM, +// input logic [`XLEN-1:0] LookUpPC, + output logic [1:0] DirPredictionF, + output logic DirPredictionWrongE, + // update + input logic [`XLEN-1:0] PCNextF, PCM, + input logic BranchInstrE, BranchInstrM, PCSrcE + ); + + logic [k-1:0] IndexNextF, IndexM; + logic [1:0] DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionE, NewDirPredictionM; + + logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; + logic [k-1:0] GHRNext; + logic PCSrcM; + + assign IndexNextF = GHR & {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexM = GHRM & {PCM[k+1] ^ PCM[1], PCM[k:2]}; + + ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), + .ce1(~StallF), .ce2(~StallM & ~FlushM), + .ra1(IndexNextF), + .rd1(DirPredictionF), + .wa2(IndexM), + .wd2(NewDirPredictionM), + .we2(BranchInstrM & ~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); + flopenrc #(k) GHRMReg(clk, reset, FlushM, ~StallM, GHRE, GHRM); + + +endmodule diff --git a/pipelined/src/ifu/oldgsharepredictor.sv b/pipelined/src/ifu/oldgsharepredictor.sv new file mode 100644 index 000000000..ece3ab707 --- /dev/null +++ b/pipelined/src/ifu/oldgsharepredictor.sv @@ -0,0 +1,134 @@ +/////////////////////////////////////////// +// globalHistoryPredictor.sv +// +// Written: Shreya Sanghai +// Email: ssanghai@hmc.edu +// Created: March 16, 2021 +// Modified: +// +// Purpose: Gshare predictor with parameterized global history register +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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 oldgsharepredictor + (input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, + output logic [1:0] DirPredictionF, + // update + input logic [4:0] InstrClassE, + input logic [4:0] BPInstrClassE, + input logic [4:0] BPInstrClassD, + input logic [4:0] BPInstrClassF, + output logic DirPredictionWrongE, + + input logic PCSrcE + + ); + logic [`BPRED_SIZE+1:0] GHR, GHRNext; + logic [`BPRED_SIZE-1:0] PHTUpdateAdr, PHTUpdateAdr0, PHTUpdateAdr1; + logic PHTUpdateEN; + logic BPClassWrongNonCFI; + logic BPClassWrongCFI; + logic BPClassRightNonCFI; + logic BPClassRightBPWrong; + logic BPClassRightBPRight; + logic [1:0] DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionE; + + logic [6:0] GHRMuxSel; + logic GHRUpdateEN; + logic [`BPRED_SIZE-1:0] GHRLookup; + + assign BPClassRightNonCFI = ~BPInstrClassE[0] & ~InstrClassE[0]; + assign BPClassWrongCFI = ~BPInstrClassE[0] & InstrClassE[0]; + assign BPClassWrongNonCFI = BPInstrClassE[0] & ~InstrClassE[0]; + assign BPClassRightBPWrong = BPInstrClassE[0] & InstrClassE[0] & DirPredictionWrongE; + assign BPClassRightBPRight = BPInstrClassE[0] & InstrClassE[0] & ~DirPredictionWrongE; + + + // GHR update selection, 1 hot encoded. + assign GHRMuxSel[0] = ~BPInstrClassF[0] & (BPClassRightNonCFI | BPClassRightBPRight); + assign GHRMuxSel[1] = BPClassWrongCFI & ~BPInstrClassD[0]; + assign GHRMuxSel[2] = BPClassWrongNonCFI & ~BPInstrClassD[0]; + assign GHRMuxSel[3] = (BPClassRightBPWrong & ~BPInstrClassD[0]) | (BPClassWrongCFI & BPInstrClassD[0]); + assign GHRMuxSel[4] = BPClassWrongNonCFI & BPInstrClassD[0]; + assign GHRMuxSel[5] = InstrClassE[0] & BPClassRightBPWrong & BPInstrClassD[0]; + assign GHRMuxSel[6] = BPInstrClassF[0] & (BPClassRightNonCFI | (InstrClassE[0] & BPClassRightBPRight)); + assign GHRUpdateEN = (| GHRMuxSel[5:1] & ~StallE) | GHRMuxSel[6] & ~StallF; + + // hoping this created a AND-OR mux. + always_comb begin + case (GHRMuxSel) + 7'b000_0001: GHRNext = GHR[`BPRED_SIZE-1+2:0]; // no change + 7'b000_0010: GHRNext = {GHR[`BPRED_SIZE-2+2:0], PCSrcE}; // branch update + 7'b000_0100: GHRNext = {1'b0, GHR[`BPRED_SIZE+1:1]}; // repair 1 + 7'b000_1000: GHRNext = {GHR[`BPRED_SIZE-1+2:1], PCSrcE}; // branch update with mis prediction correction + 7'b001_0000: GHRNext = {2'b00, GHR[`BPRED_SIZE+1:2]}; // repair 2 + 7'b010_0000: GHRNext = {1'b0, GHR[`BPRED_SIZE+1:2], PCSrcE}; // branch update + repair 1 + 7'b100_0000: GHRNext = {GHR[`BPRED_SIZE-2+2:0], DirPredictionF[1]}; // speculative update + default: GHRNext = GHR[`BPRED_SIZE-1+2:0]; + endcase + end + + flopenr #(`BPRED_SIZE+2) GlobalHistoryRegister(.clk(clk), + .reset(reset), + .en((GHRUpdateEN)), + .d(GHRNext), + .q(GHR)); + + // if actively updating the GHR at the time of prediction we want to us + // GHRNext as the lookup rather than GHR. + + assign PHTUpdateAdr0 = InstrClassE[0] ? GHR[`BPRED_SIZE:1] : GHR[`BPRED_SIZE-1:0]; + assign PHTUpdateAdr1 = InstrClassE[0] ? GHR[`BPRED_SIZE+1:2] : GHR[`BPRED_SIZE:1]; + assign PHTUpdateAdr = BPInstrClassD[0] ? PHTUpdateAdr1 : PHTUpdateAdr0; + assign PHTUpdateEN = InstrClassE[0] & ~StallE; + + assign GHRLookup = |GHRMuxSel[6:1] ? GHRNext[`BPRED_SIZE-1:0] : GHR[`BPRED_SIZE-1:0]; + + // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT + ram2p1r1wb #(`BPRED_SIZE, 2) PHT(.clk(clk), + .reset(reset), + //.RA1(GHR[`BPRED_SIZE-1:0]), + .ra1(GHRLookup ^ PCNextF[`BPRED_SIZE:1]), + .rd1(DirPredictionF), + .ren1(~StallF), + .wa2(PHTUpdateAdr ^ PCE[`BPRED_SIZE:1]), + .wd2(NewDirPredictionE), + .wen2(PHTUpdateEN), + .bwe2(2'b11)); + + // DirPrediction pipeline + flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); + flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); + + // New prediction pipeline + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); + + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0]; + +endmodule // gsharePredictor diff --git a/pipelined/src/ifu/speculativeglobalhistory.sv b/pipelined/src/ifu/speculativeglobalhistory.sv new file mode 100644 index 000000000..ac4753669 --- /dev/null +++ b/pipelined/src/ifu/speculativeglobalhistory.sv @@ -0,0 +1,127 @@ +/////////////////////////////////////////// +// 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 Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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 speculativeglobalhistory + #(parameter int k = 10 + ) + (input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, +// input logic [`XLEN-1:0] LookUpPC, + output logic [1:0] DirPredictionF, + output logic DirPredictionWrongE, + // update + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, + input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, + input logic PCSrcE + ); + + logic MatchD, MatchE, MatchM, MatchW, MatchX, MatchXF; +// logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM, NewDirPredictionW, NewDirPredictionX, NewDirPredictionXF; + + logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHRW, GHRNextF, GHRCurrentF, GHRCurrentE; + logic [k-1:0] NewGHRF, NewGHRD, NewGHRE, NewGHRM, NewGHRW; + logic PCSrcM, PCSrcW; + logic [`XLEN-1:0] PCW; + + ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), + .ce1(~StallF | reset), .ce2(~StallM & ~FlushM), + .ra1(NewGHRF), + .rd1(TableDirPredictionF), + .wa2(GHRM), + .wd2(NewDirPredictionM), + .we2(BranchInstrM & ~StallM & ~FlushM), + .bwe2(1'b1)); + + // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the demi stage NextF and then + // register for use in the Fetch stage. + assign MatchD = BranchInstrD & (GHRD == GHRF); + assign MatchE = BranchInstrE & (GHRE == GHRF); + assign MatchM = BranchInstrM & (GHRM == GHRF); + assign MatchW = BranchInstrW & (GHRW == GHRF); + assign MatchX = MatchD | MatchE | MatchM | MatchW; + + assign NewDirPredictionX = MatchD ? NewDirPredictionD : + MatchE ? NewDirPredictionE : + MatchM ? NewDirPredictionM : + MatchW ? NewDirPredictionW : '0; + flopenr #(2) NewPredXReg(clk, reset, ~StallF, NewDirPredictionX, NewDirPredictionXF); + flopenrc #(1) DoForwardReg(clk, reset, FlushD, ~StallF, MatchX, MatchXF); + + assign DirPredictionF = MatchXF ? NewDirPredictionXF : TableDirPredictionF; + + // DirPrediction pipeline + flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); + flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); + + // New prediction pipeline + satCounter2 BPDirUpdateF(.BrDir(DirPredictionF[1]), .OldState(DirPredictionF), .NewState(NewDirPredictionF)); + flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD); + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); + flopenr #(2) NewPredMReg(clk, reset, ~StallM, NewDirPredictionE, NewDirPredictionM); + flopenr #(2) NewPredWReg(clk, reset, ~StallW, NewDirPredictionM, NewDirPredictionW); + + + // PCSrc pipeline + flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); + flopenrc #(1) PCSrcWReg(clk, reset, FlushW, ~StallW, PCSrcM, PCSrcW); + + // GHR pipeline + assign GHRNextF = FlushD & BranchInstrD & ~FlushE & ~FlushM & ~FlushW ? NewGHRD : + FlushE & BranchInstrE & ~FlushM & ~FlushW ? NewGHRE : + FlushM & BranchInstrM & ~FlushW ? NewGHRM : + FlushW & BranchInstrW ? NewGHRW : + NewGHRF; + + flopenr #(k) GHRFReg(clk, reset, ~StallF, GHRNextF, GHRF); + //assign GHRF = BranchInstrF ? {NewDirPredictionF[1], GHRCurrentF[k-1:1]} : GHRCurrentF; + assign NewGHRF = BranchInstrF ? {NewDirPredictionF[1], GHRF[k-1:1]} : GHRF; + flopenr #(k) GHRDReg(clk, reset, ~StallD, GHRF, GHRD); + assign NewGHRD = BranchInstrD ? {NewDirPredictionD[1], GHRD[k-1:1]} : GHRD; + flopenr #(k) GHREReg(clk, reset, ~StallE, GHRD, GHRE); + assign NewGHRE = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; + flopenr #(k) GHRMReg(clk, reset, ~StallM, GHRE, GHRM); + assign NewGHRM = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; + flopenr #(k) GHRWReg(clk, reset, ~StallW, GHRM, GHRW); + assign NewGHRW = BranchInstrW ? {PCSrcW, GHRW[k-1:1]} : GHRW; + + + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + +endmodule diff --git a/pipelined/src/ifu/speculativegshare.sv b/pipelined/src/ifu/speculativegshare.sv new file mode 100644 index 000000000..a4e692190 --- /dev/null +++ b/pipelined/src/ifu/speculativegshare.sv @@ -0,0 +1,135 @@ +/////////////////////////////////////////// +// globalHistoryPredictor.sv +// +// Written: Shreya Sanghai +// Email: ssanghai@hmc.edu +// Created: March 16, 2021 +// Modified: +// +// Purpose: Gshare History Branch predictor with parameterized global history register +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// 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 speculativegshare + #(parameter int k = 10 + ) + (input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, +// input logic [`XLEN-1:0] LookUpPC, + output logic [1:0] DirPredictionF, + output logic DirPredictionWrongE, + // update + input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, + input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, + input logic PCSrcE + ); + + logic MatchD, MatchE, MatchM, MatchW, MatchX, MatchXF; +// logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; + logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; + logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM, NewDirPredictionW, NewDirPredictionX, NewDirPredictionXF; + + logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHRW, GHRNextF, GHRCurrentF, GHRCurrentE; + logic [k-1:0] NewGHRF, NewGHRD, NewGHRE, NewGHRM, NewGHRW; + logic PCSrcM, PCSrcW; + logic [`XLEN-1:0] PCW; + logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; + + assign IndexNextF = NewGHRF & {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; + assign IndexF = GHRF & {PCF[k+1] ^ PCF[1], PCF[k:2]}; + assign IndexD = GHRD & {PCD[k+1] ^ PCD[1], PCD[k:2]}; + assign IndexE = GHRE & {PCE[k+1] ^ PCE[1], PCE[k:2]}; + assign IndexM = GHRM & {PCM[k+1] ^ PCM[1], PCM[k:2]}; + assign IndexW = GHRW & {PCW[k+1] ^ PCW[1], PCW[k:2]}; + + ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), + .ce1(~StallF | reset), .ce2(~StallM & ~FlushM), + .ra1(IndexNextF), + .rd1(TableDirPredictionF), + .wa2(IndexM), + .wd2(NewDirPredictionM), + .we2(BranchInstrM & ~StallM & ~FlushM), + .bwe2(1'b1)); + + // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the demi stage NextF and then + // register for use in the Fetch stage. + assign MatchD = BranchInstrD & (IndexD == IndexF); + assign MatchE = BranchInstrE & (IndexE == IndexF); + assign MatchM = BranchInstrM & (IndexM == IndexF); + assign MatchW = BranchInstrW & (IndexW == IndexF); + assign MatchX = MatchD | MatchE | MatchM | MatchW; + + assign NewDirPredictionX = MatchD ? NewDirPredictionD : + MatchE ? NewDirPredictionE : + MatchM ? NewDirPredictionM : + MatchW ? NewDirPredictionW : '0; + flopenr #(2) NewPredXReg(clk, reset, ~StallF, NewDirPredictionX, NewDirPredictionXF); + flopenrc #(1) DoForwardReg(clk, reset, FlushD, ~StallF, MatchX, MatchXF); + + assign DirPredictionF = MatchXF ? NewDirPredictionXF : TableDirPredictionF; + + // DirPrediction pipeline + flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); + flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); + + // New prediction pipeline + satCounter2 BPDirUpdateF(.BrDir(DirPredictionF[1]), .OldState(DirPredictionF), .NewState(NewDirPredictionF)); + flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD); + satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); + flopenr #(2) NewPredMReg(clk, reset, ~StallM, NewDirPredictionE, NewDirPredictionM); + flopenr #(2) NewPredWReg(clk, reset, ~StallW, NewDirPredictionM, NewDirPredictionW); + + + // PCSrc pipeline + flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); + flopenrc #(1) PCSrcWReg(clk, reset, FlushW, ~StallW, PCSrcM, PCSrcW); + + // GHR pipeline + assign GHRNextF = FlushD & BranchInstrD & ~FlushE & ~FlushM & ~FlushW ? NewGHRD : + FlushE & BranchInstrE & ~FlushM & ~FlushW ? NewGHRE : + FlushM & BranchInstrM & ~FlushW ? NewGHRM : + FlushW & BranchInstrW ? NewGHRW : + NewGHRF; + + flopenr #(k) GHRFReg(clk, reset, ~StallF, GHRNextF, GHRF); + //assign GHRF = BranchInstrF ? {NewDirPredictionF[1], GHRCurrentF[k-1:1]} : GHRCurrentF; + assign NewGHRF = BranchInstrF ? {NewDirPredictionF[1], GHRF[k-1:1]} : GHRF; + flopenr #(k) GHRDReg(clk, reset, ~StallD, GHRF, GHRD); + assign NewGHRD = BranchInstrD ? {NewDirPredictionD[1], GHRD[k-1:1]} : GHRD; + flopenr #(k) GHREReg(clk, reset, ~StallE, GHRD, GHRE); + assign NewGHRE = BranchInstrE ? {PCSrcE, GHRE[k-1:1]} : GHRE; + flopenr #(k) GHRMReg(clk, reset, ~StallM, GHRE, GHRM); + assign NewGHRM = BranchInstrM ? {PCSrcM, GHRM[k-1:1]} : GHRM; + flopenr #(k) GHRWReg(clk, reset, ~StallW, GHRM, GHRW); + assign NewGHRW = BranchInstrW ? {PCSrcW, GHRW[k-1:1]} : GHRW; + + + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + + flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + +endmodule