Buffer redirection from Commit to reduce conflicts in the pipeline.
This is a general improvement, and should be upstreamed to master if there are no issues discovered.
This commit is contained in:
@@ -118,7 +118,8 @@ interface CommitInput;
|
||||
method Action setReconcileD; // recocile D$
|
||||
// redirect
|
||||
method Action killAll;
|
||||
method Action redirectPc(CapMem trap_pc
|
||||
method Action redirectPc(
|
||||
CapMem trap_pc
|
||||
`ifdef RVFI_DII
|
||||
, Dii_Parcel_Id dii_pid
|
||||
`endif
|
||||
@@ -157,6 +158,13 @@ typedef struct {
|
||||
SpecBits specBits;
|
||||
} RenameErrInfo deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
CapMem trap_pc;
|
||||
`ifdef RVFI_DII
|
||||
Dii_Parcel_Id dii_pid;
|
||||
`endif
|
||||
} RedirectInfo deriving(Bits, Eq, FShow);
|
||||
|
||||
interface CommitStage;
|
||||
// performance
|
||||
method Data getPerf(ComStagePerfType t);
|
||||
@@ -519,6 +527,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// cycle handles trap, redirect and handles system consistency
|
||||
Reg#(Maybe#(CommitTrap)) commitTrap <- mkReg(Invalid); // saves new pc here
|
||||
|
||||
FIFO#(RedirectInfo) redirectQ <- mkFIFO;
|
||||
|
||||
// maintain system consistency when system state (CSR) changes or for security
|
||||
function Action makeSystemConsistent(Bool flushTlb,
|
||||
Bool flushSecurity,
|
||||
@@ -780,11 +790,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// trap handling & redirect
|
||||
let trap_updates <- csrf.trap(trap.trap, cast(trap.pc), trap.addr, trap.orig_inst);
|
||||
CapPipe new_pc = cast(trap_updates.new_pcc);
|
||||
inIfc.redirectPc(cast(new_pc)
|
||||
redirectQ.enq(RedirectInfo{trap_pc: cast(new_pc)
|
||||
`ifdef RVFI_DII
|
||||
, trap.x.dii_pid + (is_16b_inst(trap.orig_inst) ? 1 : 2)
|
||||
, dii_pid: trap.x.dii_pid + (is_16b_inst(trap.orig_inst) ? 1 : 2)
|
||||
`endif
|
||||
);
|
||||
});
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(tagged Invalid);
|
||||
rvfis[0] = genRVFI(trap.x, traceCnt, getTSB(), getAddr(new_pc));
|
||||
@@ -825,11 +835,11 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
// kill everything, redirect, and increment epoch
|
||||
inIfc.killAll;
|
||||
inIfc.redirectPc(x.pc
|
||||
`ifdef RVFI_DII
|
||||
, x.dii_pid
|
||||
`endif
|
||||
);
|
||||
redirectQ.enq(RedirectInfo{trap_pc: x.pc
|
||||
`ifdef RVFI_DII
|
||||
, dii_pid: x.dii_pid
|
||||
`endif
|
||||
});
|
||||
inIfc.incrementEpoch;
|
||||
|
||||
// the killed Ld should have claimed phy reg, we should not commit it;
|
||||
@@ -945,11 +955,12 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
m_ret_updates = tagged Valid ret_updates;
|
||||
`endif
|
||||
end
|
||||
inIfc.redirectPc(next_pc
|
||||
`ifdef RVFI_DII
|
||||
, x.dii_pid + (is_16b_inst(x.orig_inst) ? 1 : 2)
|
||||
`endif
|
||||
);
|
||||
redirectQ.enq(RedirectInfo{trap_pc: next_pc
|
||||
`ifdef RVFI_DII
|
||||
, x.dii_pid + (is_16b_inst(x.orig_inst) ? 1 : 2)
|
||||
`endif
|
||||
});
|
||||
|
||||
|
||||
`ifdef RVFI
|
||||
Rvfi_Traces rvfis = replicate(tagged Invalid);
|
||||
@@ -1343,6 +1354,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
`endif
|
||||
endrule
|
||||
|
||||
rule pass_redirect;
|
||||
RedirectInfo ri <- toGet(redirectQ).get;
|
||||
inIfc.redirectPc(ri.trap_pc
|
||||
`ifdef RVFI_DII
|
||||
, ri.rii_pid
|
||||
`endif
|
||||
);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user