From 618dea12257f745ea3093056fb502942a313d3de Mon Sep 17 00:00:00 2001 From: Jonathan Woodruff Date: Tue, 16 Nov 2021 11:00:04 +0000 Subject: [PATCH] Feed head of RAS through to execute with training info to reset the head on a misprediction. --- src_Core/CPU/Core.bsv | 2 +- .../procs/RV64G_OOO/AluExePipeline.bsv | 18 +++++------ .../RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv | 30 +++++++++++-------- .../RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv | 12 ++++---- .../procs/RV64G_OOO/ReservationStationAlu.bsv | 8 ++--- src_Core/RISCY_OOO/procs/lib/DirPredictor.bsv | 7 +++++ src_Core/RISCY_OOO/procs/lib/Ras.bsv | 27 ++++++++++------- 7 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index bdb4dac..957532e 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -458,7 +458,7 @@ module mkCore#(CoreId coreId)(Core); trainBPQ[i].deq; fetchStage.train_predictors( train.pc, train.nextPc, train.iType, train.taken, - train.dpTrain, train.mispred, train.isCompressed + train.trainInfo, train.mispred, train.isCompressed ); endrule end diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index 023eaf9..73b8aa1 100755 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -77,7 +77,7 @@ typedef struct { DecodedInst dInst; PhyRegs regs; InstTag tag; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; // specualtion Maybe#(SpecTag) spec_tag; } AluDispatchToRegRead deriving(Bits, Eq, FShow); @@ -87,7 +87,7 @@ typedef struct { DecodedInst dInst; Maybe#(PhyDst) dst; InstTag tag; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; // src reg vals & pc & ppc CapPipe rVal1; CapPipe rVal2; @@ -103,7 +103,7 @@ typedef struct { IType iType; Maybe#(PhyDst) dst; InstTag tag; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; Bool isCompressed; // result CapPipe data; // alu compute result @@ -153,7 +153,7 @@ typedef struct { CapMem nextPc; IType iType; Bool taken; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; Bool mispred; Bool isCompressed; } FetchTrainBP deriving(Bits, Eq, FShow); @@ -270,7 +270,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); dInst: x.data.dInst, regs: x.regs, tag: x.tag, - dpTrain: x.data.dpTrain, + trainInfo: x.data.trainInfo, spec_tag: x.spec_tag }, spec_bits: x.spec_bits @@ -342,7 +342,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); dInst: x.dInst, dst: x.regs.dst, tag: x.tag, - dpTrain: x.dpTrain, + trainInfo: x.trainInfo, rVal1: rVal1, rVal2: rVal2, pc: pc, @@ -398,7 +398,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); iType: x.dInst.iType, dst: x.dst, tag: x.tag, - dpTrain: x.dpTrain, + trainInfo: x.trainInfo, isCompressed: x.orig_inst[1:0] != 2'b11, data: exec_result.data, csrData: is_scr_or_csr ? CSRData (exec_result.csrData) : PPC (cast(exec_result.controlFlow.nextPc)), @@ -478,7 +478,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); nextPc: cast(x.controlFlow.nextPc), iType: x.iType, taken: x.controlFlow.taken, - dpTrain: x.dpTrain, + trainInfo: x.trainInfo, mispred: True, isCompressed: x.isCompressed}, spec_bits: exeToFin.spec_bits @@ -509,7 +509,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); nextPc: cast(x.controlFlow.nextPc), iType: x.iType, taken: x.controlFlow.taken, - dpTrain: x.dpTrain, + trainInfo: x.trainInfo, mispred: False, isCompressed: x.isCompressed}, spec_bits: exeToFin.spec_bits diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv index 9851594..788fc1c 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv @@ -142,7 +142,7 @@ interface FetchStage; method Action done_flushing(); method Action train_predictors( CapMem pc, CapMem next_pc, IType iType, Bool taken, - DirPredTrainInfo dpTrain, Bool mispred, Bool isCompressed + PredTrainInfo trainInfo, Bool mispred, Bool isCompressed ); // security @@ -277,7 +277,7 @@ typedef struct { `endif CapMem ppc; Epoch main_epoch; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; Instruction inst; DecodedInst dInst; Bit #(32) orig_inst; // original 16b or 32b instruction ([1:0] will distinguish 16b or 32b) @@ -693,7 +693,7 @@ module mkFetchStage(FetchStage); let dInst = decode_result.dInst; let regs = decode_result.regs; - DirPredTrainInfo dp_train = ?; // dir pred training bookkeeping + PredTrainInfo trainInfo = ?; // dir pred training bookkeeping // update predicted next pc if (!isValid(cause)) begin @@ -702,7 +702,7 @@ module mkFetchStage(FetchStage); if(dInst.iType == Br) begin let pred_res <- dirPred.pred[i].pred(getAddr(pc)); pred_taken = pred_res.taken; - dp_train = pred_res.train; + trainInfo.dir = pred_res.train; end Maybe#(CapMem) nextPc = decodeBrPred(pc, dInst, pred_taken, (in.inst_kind == Inst_32b)); @@ -717,37 +717,41 @@ module mkFetchStage(FetchStage); Bool dst_link = linkedR(regs.dst); Bool src1_link = linkedR(regs.src1); CapMem push_addr = addPc(pc, ((in.inst_kind == Inst_32b) ? 4 : 2)); + Maybe#(CapMem) m_push_addr = Invalid; CapMem pop_addr = ras.ras[i].first; + Bool pop = False; if ((dInst.iType == J || dInst.iType == CJAL) && dst_link) begin // rs1 is invalid, i.e., not link: push - ras.ras[i].popPush(False, Valid (push_addr)); + m_push_addr = Valid (push_addr); end else if (dInst.iType == Jr || dInst.iType == CJALR) begin // jalr TODO CCALL could be push // pop or nop (if to trampoline) // Add hint to architecture? if (!dst_link && src1_link) begin // rd is link while rs1 is not: pop + pop = True; nextPc = Valid (pop_addr); - ras.ras[i].popPush(True, Invalid); end else if (!src1_link && dst_link) begin // rs1 is not link while rd is link: push - ras.ras[i].popPush(False, Valid (push_addr)); + m_push_addr = Valid (push_addr); end else if (dst_link && src1_link) begin // both rd and rs1 are links if (regs.src1 != regs.dst) begin // not same reg: first pop, then push nextPc = Valid (pop_addr); - ras.ras[i].popPush(True, Valid (push_addr)); + pop = True; + m_push_addr = Valid (push_addr); end else begin // same reg: push - ras.ras[i].popPush(False, Valid (push_addr)); + m_push_addr = Valid (push_addr); end end end + trainInfo.ras <- ras.ras[i].popPush(pop, m_push_addr); if(verbose) begin $display("Branch prediction: ", fshow(dInst.iType), " ; ", fshow(pc), " ; ", fshow(ppc), " ; ", fshow(pred_taken), " ; ", fshow(nextPc)); @@ -783,7 +787,7 @@ module mkFetchStage(FetchStage); `endif ppc: ppc, main_epoch: in.main_epoch, - dpTrain: dp_train, + trainInfo: trainInfo, inst: in.inst, dInst: dInst, orig_inst: in.orig_inst, @@ -934,7 +938,7 @@ module mkFetchStage(FetchStage); method Action train_predictors( CapMem pc, CapMem next_pc, IType iType, Bool taken, - DirPredTrainInfo dpTrain, Bool mispred, Bool isCompressed + PredTrainInfo trainInfo, Bool mispred, Bool isCompressed ); //if (iType == J || iType == CJAL || (iType == Br && next_pc < pc)) begin // // Only train the next address predictor for jumps and backward branches @@ -943,12 +947,14 @@ module mkFetchStage(FetchStage); //end if (iType == Br) begin // Train the direction predictor for all branches - dirPred.update(getAddr(pc), taken, dpTrain, mispred); + dirPred.update(getAddr(pc), taken, trainInfo.dir, mispred); + $display("Branch train PC: %x, taken: %x, mispred: %x", getAddr(pc), taken, mispred); end // train next addr pred when mispred if(mispred) begin let last_x16_pc = addPc(pc, (isCompressed ? 0 : 2)); napTrainByExe.wset(TrainNAP {pc: last_x16_pc, nextPc: next_pc}); + ras.setHead(trainInfo.ras); end endmethod diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index 0dd250c..5b09b41 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -341,7 +341,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); let orig_inst = x.orig_inst; let ppc = x.ppc; let main_epoch = x.main_epoch; - let dpTrain = x.dpTrain; + let trainInfo = x.trainInfo; let inst = x.inst; let dInst = x.dInst; let arch_regs = x.regs; @@ -481,7 +481,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); let dst = x.regs.dst; let ppc = x.ppc; let main_epoch = x.main_epoch; - let dpTrain = x.dpTrain; + let trainInfo = x.trainInfo; let inst = x.inst; let dInst = x.dInst; let arch_regs = x.regs; @@ -540,7 +540,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); // send to ALU reservation station if (to_exec) begin reservationStationAlu[0].enq(ToReservationStation { - data: AluRSData {dInst: dInst, dpTrain: dpTrain}, + data: AluRSData {dInst: dInst, trainInfo: trainInfo}, regs: phy_regs, tag: inst_tag, spec_bits: spec_bits, @@ -663,7 +663,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); let orig_inst = x.orig_inst; let ppc = x.ppc; let main_epoch = x.main_epoch; - let dpTrain = x.dpTrain; + let trainInfo = x.trainInfo; let inst = x.inst; let dInst = x.dInst; let arch_regs = x.regs; @@ -885,7 +885,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); let orig_inst = x.orig_inst; let ppc = x.ppc; let main_epoch = x.main_epoch; - let dpTrain = x.dpTrain; + let trainInfo = x.trainInfo; let inst = x.inst; let dInst = x.dInst; let arch_regs = x.regs; @@ -1001,7 +1001,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); // can process, send to ALU rs aluExeUsed[k] = True; // mark resource used reservationStationAlu[k].enq(ToReservationStation { - data: AluRSData {dInst: dInst, dpTrain: dpTrain}, + data: AluRSData {dInst: dInst, trainInfo: trainInfo}, regs: phy_regs, tag: inst_tag, spec_bits: spec_bits, diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationAlu.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationAlu.bsv index ffe2e32..d22c5d0 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationAlu.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationAlu.bsv @@ -1,6 +1,6 @@ // Copyright (c) 2017 Massachusetts Institute of Technology -// +// // 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 @@ -8,10 +8,10 @@ // 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 @@ -31,7 +31,7 @@ import DirPredictor::*; typedef struct { DecodedInst dInst; - DirPredTrainInfo dpTrain; + PredTrainInfo trainInfo; } AluRSData deriving(Bits, Eq, FShow); // ALU pipeline is aggressive, i.e. it recv bypass and early RS wakeup diff --git a/src_Core/RISCY_OOO/procs/lib/DirPredictor.bsv b/src_Core/RISCY_OOO/procs/lib/DirPredictor.bsv index fe48ab1..3435f02 100644 --- a/src_Core/RISCY_OOO/procs/lib/DirPredictor.bsv +++ b/src_Core/RISCY_OOO/procs/lib/DirPredictor.bsv @@ -46,8 +46,10 @@ import GSelectPred::*; import GSharePred::*; import TourPred::*; import TourPredSecure::*; +import Ras::*; export DirPredTrainInfo(..); +export PredTrainInfo(..); export mkDirPredictor; `ifdef DIR_PRED_BHT @@ -63,6 +65,11 @@ typedef GShareTrainInfo DirPredTrainInfo; typedef TourTrainInfo DirPredTrainInfo; `endif +typedef struct { + DirPredTrainInfo dir; + RasPredTrainInfo ras; +} PredTrainInfo deriving(Bits, Eq, FShow); + (* synthesize *) module mkDirPredictor(DirPredictor#(DirPredTrainInfo)); `ifdef DIR_PRED_BHT diff --git a/src_Core/RISCY_OOO/procs/lib/Ras.bsv b/src_Core/RISCY_OOO/procs/lib/Ras.bsv index 9848057..5acb3e7 100644 --- a/src_Core/RISCY_OOO/procs/lib/Ras.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Ras.bsv @@ -46,25 +46,27 @@ import CHERICap::*; interface RAS; method CapMem first; // first pop, then push - method Action popPush(Bool pop, Maybe#(CapMem) pushAddr); -endinterface - -interface ReturnAddrStack; - interface Vector#(SupSize, RAS) ras; - method Action flush; - method Bool flush_done; + method ActionValue#(RasIndex) popPush(Bool pop, Maybe#(CapMem) pushAddr); endinterface // Local RAS Typedefs SHOULD BE A POWER OF TWO. -typedef 8 RasEntries; +typedef 16 RasEntries; typedef Bit#(TLog#(RasEntries)) RasIndex; +typedef RasIndex RasPredTrainInfo; + +interface ReturnAddrStack; + interface Vector#(SupSize, RAS) ras; + method Action setHead(RasIndex h); + method Action flush; + method Bool flush_done; +endinterface (* synthesize *) module mkRas(ReturnAddrStack) provisos(NumAlias#(TExp#(TLog#(RasEntries)), RasEntries)); Vector#(RasEntries, Ehr#(TAdd#(SupSize, 1), CapMem)) stack <- replicateM(mkEhr(nullCap)); // head points past valid data // to gracefully overflow, head is allowed to overflow to 0 and overwrite the oldest data - Ehr#(TAdd#(SupSize, 1), RasIndex) head <- mkEhr(0); + Ehr#(TAdd#(SupSize, 2), RasIndex) head <- mkEhr(0); `ifdef SECURITY Reg#(Bool) flushDone <- mkReg(True); @@ -82,7 +84,7 @@ module mkRas(ReturnAddrStack) provisos(NumAlias#(TExp#(TLog#(RasEntries)), RasEn method CapMem first; return stack[head[i]][i]; endmethod - method Action popPush(Bool pop, Maybe#(CapMem) pushAddr); + method ActionValue#(RasIndex) popPush(Bool pop, Maybe#(CapMem) pushAddr); // first pop, then push RasIndex h = head[i]; if(pop) begin @@ -93,10 +95,15 @@ module mkRas(ReturnAddrStack) provisos(NumAlias#(TExp#(TLog#(RasEntries)), RasEn stack[h][i] <= addr; end head[i] <= h; + return h; endmethod endinterface); end + method Action setHead(RasIndex h); + head[valueof(SupSize) + 1] <= h; + endmethod + interface ras = rasIfc; `ifdef SECURITY