From 857f59ab5c51e146d1cdf121443297f7ac079246 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 1 Jun 2021 10:57:43 -0500 Subject: [PATCH] Now have global history working correctly. --- testsBP/crt0/Makefile | 8 +- testsBP/simple/header.h | 1 + testsBP/simple/main.c | 3 +- wally-pipelined/config/rv64BP/wally-config.vh | 6 +- wally-pipelined/src/ifu/bpred.sv | 29 ++-- .../src/ifu/globalHistoryPredictor.sv | 62 ++----- wally-pipelined/src/ifu/gshare.sv | 159 ------------------ .../testbench/testbench-imperas.sv | 5 +- 8 files changed, 38 insertions(+), 235 deletions(-) delete mode 100644 wally-pipelined/src/ifu/gshare.sv diff --git a/testsBP/crt0/Makefile b/testsBP/crt0/Makefile index b42e86cb8..2af43a408 100644 --- a/testsBP/crt0/Makefile +++ b/testsBP/crt0/Makefile @@ -4,12 +4,12 @@ ROOT := .. LIBRARY_DIRS := LIBRARY_FILES := -MARCH :=-march=rv64ic -MABI :=-mabi=lp64 +MARCH :=-march=rv64imfdc +MABI :=-mabi=lp64d LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles -AFLAGS =$(MARCH) $(MABI) -march=rv64ic -mabi=lp64 -W -CFLAGS =$(MARCH) $(MABI) -march=rv64ic -mabi=lp64 -mcmodel=medany -O2 +AFLAGS =$(MARCH) $(MABI) -W +CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2 AS=riscv64-unknown-elf-as CC=riscv64-unknown-elf-gcc AR=riscv64-unknown-elf-ar diff --git a/testsBP/simple/header.h b/testsBP/simple/header.h index f3a62da30..aab8973fd 100644 --- a/testsBP/simple/header.h +++ b/testsBP/simple/header.h @@ -5,6 +5,7 @@ int fail(); int simple_csrbr_test(); int lbu_test(); int icache_spill_test(); +void global_hist_0_space_test(); void global_hist_1_space_test(); void global_hist_2_space_test(); void global_hist_3_space_test(); diff --git a/testsBP/simple/main.c b/testsBP/simple/main.c index 7bf6b4751..564b474e1 100644 --- a/testsBP/simple/main.c +++ b/testsBP/simple/main.c @@ -4,7 +4,8 @@ int main(){ //int res = icache_spill_test(); global_hist_3_space_test(); global_hist_2_space_test(); - global_hist_1_space_test(); + global_hist_1_space_test(); + global_hist_0_space_test(); int res = 1; if (res < 0) { fail(); diff --git a/wally-pipelined/config/rv64BP/wally-config.vh b/wally-pipelined/config/rv64BP/wally-config.vh index fd482bfde..a9dbb1bda 100644 --- a/wally-pipelined/config/rv64BP/wally-config.vh +++ b/wally-pipelined/config/rv64BP/wally-config.vh @@ -32,7 +32,7 @@ `define XLEN 64 //`define MISA (32'h00000105) -`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0) +`define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1) @@ -107,8 +107,8 @@ /* verilator lint_off ASSIGNDLY */ /* verilator lint_off PINCONNECTEMPTY */ -`define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt" -`define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt" +`define TWO_BIT_PRELOAD "../config/rv64BP/twoBitPredictor.txt" +`define BTB_PRELOAD "../config/rv64BP/BTBPredictor.txt" `define BPRED_ENABLED 1 //`define BPTYPE "BPGSHARE" // BPGLOBAL or BPTWOBIT or BPGSHARE `define BPTYPE "BPGLOBAL" // BPTWOBIT or "BPGSHARE" or BPLOCALPAg or BPGSHARE diff --git a/wally-pipelined/src/ifu/bpred.sv b/wally-pipelined/src/ifu/bpred.sv index 9beaa959a..92471c574 100644 --- a/wally-pipelined/src/ifu/bpred.sv +++ b/wally-pipelined/src/ifu/bpred.sv @@ -89,30 +89,29 @@ module bpred globalHistoryPredictor DirPredictor(.clk(clk), .reset(reset), .*, // Stalls and flushes - .LookUpPC(PCNextF), + .PCNextF(PCNextF), .BPPredF(BPPredF), // update - .BPPredD(BPPredD), .InstrClassE(InstrClassE), .BPInstrClassE(BPInstrClassE), .BPPredDirWrongE(BPPredDirWrongE), - .UpdatePC(PCE), + .PCE(PCE), .PCSrcE(PCSrcE), - .UpdatePrediction(UpdateBPPredE)); + .UpdateBPPredE(UpdateBPPredE)); end else if (`BPTYPE == "BPGSHARE") begin:Predictor gsharePredictor DirPredictor(.clk(clk), - .reset(reset), - .*, // Stalls and flushes - .LookUpPC(PCNextF), - .Prediction(BPPredF), - // update - .UpdatePC(PCE), - .UpdateEN(InstrClassE[0] & ~StallE), - .SpeculativeUpdateEn(BPInstrClassF[0] & ~StallF), - .BPPredDirWrongE(BPPredDirWrongE), - .PCSrcE(PCSrcE), - .UpdatePrediction(UpdateBPPredE)); + .reset(reset), + .*, // Stalls and flushes + .PCNextF(PCNextF), + .BPPredF(BPPredF), + // update + .InstrClassE(InstrClassE), + .BPInstrClassE(BPInstrClassE), + .BPPredDirWrongE(BPPredDirWrongE), + .PCE(PCE), + .PCSrcE(PCSrcE), + .UpdateBPPredE(UpdateBPPredE)); end else if (`BPTYPE == "BPLOCALPAg") begin:Predictor diff --git a/wally-pipelined/src/ifu/globalHistoryPredictor.sv b/wally-pipelined/src/ifu/globalHistoryPredictor.sv index b2ac19911..516de633e 100644 --- a/wally-pipelined/src/ifu/globalHistoryPredictor.sv +++ b/wally-pipelined/src/ifu/globalHistoryPredictor.sv @@ -33,19 +33,18 @@ module globalHistoryPredictor (input logic clk, input logic reset, input logic StallF, StallD, StallE, FlushF, FlushD, FlushE, - input logic [`XLEN-1:0] LookUpPC, + input logic [`XLEN-1:0] PCNextF, output logic [1:0] BPPredF, // update - input logic [1:0] BPPredD, input logic [4:0] InstrClassE, input logic [4:0] BPInstrClassE, input logic [4:0] BPInstrClassD, input logic [4:0] BPInstrClassF, input logic BPPredDirWrongE, - input logic [`XLEN-1:0] UpdatePC, + input logic [`XLEN-1:0] PCE, input logic PCSrcE, - input logic [1:0] UpdatePrediction + input logic [1:0] UpdateBPPredE ); logic [k+1:0] GHR, GHRNext; @@ -54,17 +53,10 @@ module globalHistoryPredictor logic BPClassWrongNonCFI; logic BPClassWrongCFI; logic BPClassRightNonCFI; - - -/* -----\/----- EXCLUDED -----\/----- - logic [k-1:0] GHRD, GHRE, GHRLookup; - - logic FlushedD, FlushedE; - -----/\----- EXCLUDED -----/\----- */ - logic [6:0] GHRMuxSel; logic GHRUpdateEN; + logic [k-1:0] GHRLookup; assign BPClassRightNonCFI = ~BPInstrClassE[0] & ~InstrClassE[0]; assign BPClassWrongCFI = ~BPInstrClassE[0] & InstrClassE[0]; @@ -75,15 +67,9 @@ module globalHistoryPredictor // GHR update selection, 1 hot encoded. assign GHRMuxSel[0] = ~BPInstrClassF[0] & (BPClassRightNonCFI | BPClassRightBPRight); - assign GHRMuxSel[1] = BPClassWrongCFI & ~BPInstrClassD[0]; - assign GHRMuxSel[3] = (BPClassRightBPWrong & ~BPInstrClassD[0]) | (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)); @@ -99,7 +85,6 @@ module globalHistoryPredictor 7'b001_0000: GHRNext = {2'b00, GHR[k+1:2]}; // repair 2 7'b010_0000: GHRNext = {1'b0, GHR[k+1:2], PCSrcE}; // branch update + repair 1 7'b100_0000: GHRNext = {GHR[k-2+2:0], BPPredF[1]}; // speculative update - //7'b100_0000: GHRNext = {k+1{1'bx}}; // speculative update default: GHRNext = GHR[k-1+2:0]; endcase end @@ -113,50 +98,23 @@ module globalHistoryPredictor // if actively updating the GHR at the time of prediction we want to us // GHRNext as the lookup rather than GHR. - //assign GHRLookup = GHRUpdateEN ? GHRNext : GHR; - assign PHTUpdateAdr0 = InstrClassE[0] ? GHR[k:1] : GHR[k-1:0]; assign PHTUpdateAdr1 = InstrClassE[0] ? GHR[k+1:2] : GHR[k:1]; assign PHTUpdateAdr = BPInstrClassD[0] ? PHTUpdateAdr1 : PHTUpdateAdr0; assign PHTUpdateEN = InstrClassE[0] & ~StallE; + + assign GHRLookup = |GHRMuxSel[6:1] ? GHRNext[k-1:0] : GHR[k-1:0]; // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT SRAM2P1R1W #(k, 2) PHT(.clk(clk), .reset(reset), - .RA1(GHR[k-1:0]), + //.RA1(GHR[k-1:0]), + .RA1(GHRLookup), .RD1(BPPredF), .REN1(~StallF), .WA1(PHTUpdateAdr), - .WD1(UpdatePrediction), + .WD1(UpdateBPPredE), .WEN1(PHTUpdateEN), .BitWEN1(2'b11)); -/* -----\/----- EXCLUDED -----\/----- - flopenr #(k) GlobalHistoryRegisterD(.clk(clk), - .reset(reset), - .en(~StallD & ~FlushedE), - .d(GHR), - .q(GHRD)); - - flopenr #(k) GlobalHistoryRegisterE(.clk(clk), - .reset(reset), - .en(~StallE & ~ FlushedE), - .d(GHRD), - .q(GHRE)); - - - flopenr #(1) flushedDReg(.clk(clk), - .reset(reset), - .en(~StallD), - .d(FlushD), - .q(FlushedD)); - - flopenr #(1) flushedEReg(.clk(clk), - .reset(reset), - .en(~StallE), - .d(FlushE | FlushedD), - .q(FlushedE)); - -----/\----- EXCLUDED -----/\----- */ - - endmodule diff --git a/wally-pipelined/src/ifu/gshare.sv b/wally-pipelined/src/ifu/gshare.sv deleted file mode 100644 index 3cc73be80..000000000 --- a/wally-pipelined/src/ifu/gshare.sv +++ /dev/null @@ -1,159 +0,0 @@ -/////////////////////////////////////////// -// gshare.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 -// -// 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 gsharePredictor - #(parameter int k = 10 - ) - (input logic clk, - input logic reset, - input logic StallF, StallD, StallE, FlushF, FlushD, FlushE, - input logic [`XLEN-1:0] LookUpPC, - output logic [1:0] Prediction, - // update - input logic [`XLEN-1:0] UpdatePC, - input logic UpdateEN, PCSrcE, - input logic SpeculativeUpdateEn, BPPredDirWrongE, - input logic [1:0] UpdatePrediction - - ); - - logic [k-1:0] GHRF, GHRFNext, GHRD, GHRE; - //logic [k-1:0] LookUpPCIndexD, LookUpPCIndexE; - logic [k-1:0] LookUpPCIndex, UpdatePCIndex; - logic [1:0] PredictionMemory; - logic DoForwarding, DoForwardingF; - logic [1:0] UpdatePredictionF; - logic FlushedD, FlushedE; - - // if the prediction is wrong we need to restore the ghr. - assign GHRFNext = BPPredDirWrongE ? {PCSrcE, GHRE[k-1:1]} : - {Prediction[1], GHRF[k-1:1]}; - - flopenr #(k) GlobalHistoryRegister(.clk(clk), - .reset(reset), - .en((UpdateEN & BPPredDirWrongE) | (SpeculativeUpdateEn)), - .d(GHRFNext), - .q(GHRF)); - - - // for gshare xor the PC with the GHR - assign UpdatePCIndex = GHRE ^ UpdatePC[k:1]; - assign LookUpPCIndex = GHRF ^ LookUpPC[k:1]; - // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT - // GHR referes to the address that the past k branches points to in the prediction stage - // GHRE refers to the address that the past k branches points to in the exectution stage - SRAM2P1R1W #(k, 2) PHT(.clk(clk), - .reset(reset), - .RA1(LookUpPCIndex), - .RD1(Prediction), - .REN1(~StallF), - .WA1(UpdatePCIndex), - .WD1(UpdatePrediction), - .WEN1(UpdateEN), - .BitWEN1(2'b11)); - - - flopenr #(k) GlobalHistoryRegisterD(.clk(clk), - .reset(reset), - .en(~StallD & ~FlushedE), - .d(GHRF), - .q(GHRD)); - - flopenr #(k) GlobalHistoryRegisterE(.clk(clk), - .reset(reset), - .en(~StallE & ~ FlushedE), - .d(GHRD), - .q(GHRE)); - - - flopenr #(1) flushedDReg(.clk(clk), - .reset(reset), - .en(~StallD), - .d(FlushD), - .q(FlushedD)); - - flopenr #(1) flushedEReg(.clk(clk), - .reset(reset), - .en(~StallE), - .d(FlushE | FlushedD), - .q(FlushedE)); - -/* -----\/----- EXCLUDED -----\/----- - // need to forward when updating to the same address as reading. - // first we compare to see if the update and lookup addreses are the same - assign DoForwarding = LookUpPCIndex == UpdatePCIndex; - - // register the update value and the forwarding signal into the Fetch stage - // TODO: add stall logic *** - flopr #(1) DoForwardingReg(.clk(clk), - .reset(reset), - .d(DoForwarding), - .q(DoForwardingF)); - - flopr #(2) UpdatePredictionReg(.clk(clk), - .reset(reset), - .d(UpdatePrediction), - .q(UpdatePredictionF)); - - assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory; - -----/\----- EXCLUDED -----/\----- */ - - //pipeline for GHR -/* -----\/----- EXCLUDED -----\/----- - flopenrc #(k) LookUpDReg(.clk(clk), - .reset(reset), - .en(~StallD), - .clear(FlushD), - .d(LookUpPCIndex), - .q(LookUpPCIndexD)); - - flopenrc #(k) LookUpEReg(.clk(clk), - .reset(reset), - .en(~StallE), - .clear(FlushE), - .d(LookUpPCIndexD), - .q(LookUpPCIndexE)); - -----/\----- EXCLUDED -----/\----- */ - -/* flopenrc #(k) GHRRegD(.clk(clk), - .reset(reset), - .en(~StallD), - .clear(FlushD), - .d(GHRF), - .q(GHRD)); - - flopenrc #(k) GHRRegE(.clk(clk), - .reset(reset), - .en(~StallE), - .clear(FlushE), - .d(GHRD), - .q(GHRE)); - -*/ -endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index ddee23a1e..bb8ffbd4b 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -438,8 +438,11 @@ string tests32f[] = '{ string testsBP64[] = '{ "rv64BP/simple", "10000", + "rv64BP/mmm", "1000000", + "rv64BP/linpack_bench", "1000000", + "rv64BP/sieve", "1000000", "rv64BP/qsort", "1000000", - "rv64BP/sieve", "1000000" + "rv64BP/dhrystone", "1000000" }; string tests64p[] = '{