Also pause branch execution when there is a pending wrong speculation.
This commit is contained in:
@@ -426,6 +426,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
);
|
||||
globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag, spec_bits);
|
||||
endmethod
|
||||
method Bool pauseExecute = globalSpecUpdate.pendingIncorrectSpec;
|
||||
method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put;
|
||||
method doStats = doStatsReg._read;
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
|
||||
@@ -195,6 +195,8 @@ interface AluExeInput;
|
||||
method Action writeRegFile(PhyRIndx dst, CapPipe data);
|
||||
// redirect
|
||||
method Action redirect(CapMem new_pc, SpecTag spec_tag, InstTag inst_tag, SpecBits spec_bits);
|
||||
// pending invalidation could pause execute/redirections.
|
||||
method Bool pauseExecute;
|
||||
// spec update
|
||||
method Action correctSpec(SpecTag t);
|
||||
|
||||
@@ -354,7 +356,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
});
|
||||
endrule
|
||||
|
||||
rule doExeAlu;
|
||||
rule doExeAlu(!inIfc.pauseExecute);
|
||||
regToExeQ.deq;
|
||||
let regToExe = regToExeQ.first;
|
||||
let x = regToExe.data;
|
||||
@@ -417,7 +419,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
});
|
||||
endrule
|
||||
|
||||
rule doFinishAlu;
|
||||
rule doFinishAlu(!inIfc.pauseExecute);
|
||||
exeToFinQ.deq;
|
||||
let exeToFin = exeToFinQ.first;
|
||||
let x = exeToFin.data;
|
||||
|
||||
@@ -25,7 +25,7 @@ import ProcTypes::*;
|
||||
import HasSpecBits::*;
|
||||
import Vector::*;
|
||||
import Ehr::*;
|
||||
import FIFOF::*;
|
||||
import DReg::*;
|
||||
import Assert::*;
|
||||
import Types::*;
|
||||
import ConfigReg::*;
|
||||
@@ -223,8 +223,8 @@ module mkSpecFifoCF#(
|
||||
Vector#(size, Reg#(t)) row <- replicateM(mkConfigRegU);
|
||||
Ehr#(3, Vector#(size, SpecBits)) specBits <- mkEhr(?);
|
||||
|
||||
FIFOF#(SpecBits) correctSpecF <- mkUGFIFOF;
|
||||
FIFOF#(IncorrectSpeculation) incorrectSpecF <- mkUGFIFOF;
|
||||
Reg#(Maybe#(SpecBits)) correctSpec <- mkDReg(Invalid);
|
||||
Reg#(Maybe#(IncorrectSpeculation)) incorrectSpec <- mkDReg(Invalid);
|
||||
|
||||
Reg#(idxT) enqP <- mkConfigReg(0);
|
||||
Ehr#(2, idxT) deqP_ehr <- mkEhr(0);
|
||||
@@ -245,17 +245,13 @@ module mkSpecFifoCF#(
|
||||
Vector#(size, SpecBits) newSpecBits = specBits[0];
|
||||
Vector#(size, Bool) newValid = valid[0];
|
||||
// Fold in CorrectSpec update:
|
||||
if (correctSpecF.notEmpty) begin
|
||||
SpecBits mask = correctSpecF.first();
|
||||
correctSpecF.deq();
|
||||
if (correctSpec matches tagged Valid .mask) begin
|
||||
// clear spec bits for all entries
|
||||
for (Integer i=0; i<valueOf(size); i=i+1)
|
||||
newSpecBits[i] = newSpecBits[i] & mask;
|
||||
end
|
||||
// Fold in IncorrectSpec update:
|
||||
if (incorrectSpecF.notEmpty) begin
|
||||
IncorrectSpeculation incSpec = incorrectSpecF.first();
|
||||
incorrectSpecF.deq();
|
||||
if (incorrectSpec matches tagged Valid .incSpec) begin
|
||||
// clear entries
|
||||
for (Integer i=0; i<valueOf(size); i=i+1)
|
||||
if(incSpec.kill_all || newSpecBits[i][incSpec.specTag] == 1'b1)
|
||||
@@ -316,9 +312,9 @@ module mkSpecFifoCF#(
|
||||
method Bool notEmpty = valid[1][deqP];
|
||||
|
||||
interface SpeculationUpdate specUpdate;
|
||||
method correctSpeculation = correctSpecF.enq;
|
||||
method correctSpeculation(mask) = correctSpec._write(Valid(mask));
|
||||
method incorrectSpeculation(kill_all, specTag) =
|
||||
incorrectSpecF.enq(IncorrectSpeculation{kill_all: kill_all, specTag: specTag});
|
||||
incorrectSpec._write(Valid(IncorrectSpeculation{kill_all: kill_all, specTag: specTag}));
|
||||
endinterface
|
||||
endmodule
|
||||
|
||||
|
||||
Reference in New Issue
Block a user