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:
Jonathan Woodruff
2022-02-18 18:00:02 +00:00
parent 75d1afe8b4
commit e889bb95fa
2 changed files with 4 additions and 2 deletions

View File

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

View File

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