Add a "delay" for fixups after a push.
A push updates the head pointer from Execute, but the instructions between Decode and execute will have an out-of-date head pointer. If a branch in that window mispredicts, it will get the head pointer out of sync by resetting it to ignore the push. By delaying by one branch, we seem to eliminate over 60% of the misses, and reduce the cycle overhead from 0.5% to 0.2% in CoreMark, and still well ahead of the baseline with no fixup.
This commit is contained in:
@@ -371,7 +371,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
default: False;
|
||||
endcase);
|
||||
`ifdef RAS_HIT_TRACING
|
||||
if (link) begin
|
||||
if (linkedR(Valid(tagged Gpr x.orig_inst[19:15])) && (x.orig_inst[19:15] != x.orig_inst[11:7])) begin
|
||||
case (x.dInst.iType)
|
||||
Jr, CJALR: $display("Jr/CJALR ra: PC: %x Mispredict: %x , %x vs %x src1: %d", getAddr(x.pc), exec_result.controlFlow.mispredict, getAddr(exec_result.controlFlow.nextPc), getAddr(x.ppc), x.orig_inst[19:15]);
|
||||
endcase
|
||||
|
||||
@@ -439,6 +439,7 @@ module mkFetchStage(FetchStage);
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
Reg#(Bool) redirect_evt_reg <- mkDReg(False);
|
||||
`endif
|
||||
Reg#(Bool) rasFixupDelay <- mkRegU;
|
||||
|
||||
rule updatePcInBtb;
|
||||
nextAddrPred.put_pc(pc_reg[pc_final_port]);
|
||||
@@ -963,8 +964,9 @@ module mkFetchStage(FetchStage);
|
||||
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);
|
||||
if (!rasFixupDelay) ras.setHead(trainInfo.ras);
|
||||
end
|
||||
rasFixupDelay <= link;
|
||||
endmethod
|
||||
|
||||
interface SpeculationUpdate specUpdate = main_epoch_spec.specUpdate;
|
||||
|
||||
Reference in New Issue
Block a user