Feed head of RAS through to execute with training info to reset the head
on a misprediction.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user