Feed head of RAS through to execute with training info to reset the head

on a misprediction.
This commit is contained in:
Jonathan Woodruff
2021-11-16 11:00:04 +00:00
parent d56045effe
commit 618dea1225
7 changed files with 62 additions and 42 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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