diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index 397543a..58ad769 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -120,7 +120,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 @@ -159,6 +160,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); @@ -522,6 +530,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); Reg#(Maybe#(CommitTrap)) commitTrap <- mkReg(Invalid); // saves new pc here Bool pauseCommit = isValid(commitTrap) || inIfc.pauseCommit; + FIFO#(RedirectInfo) redirectQ <- mkFIFO; + // maintain system consistency when system state (CSR) changes or for security function Action makeSystemConsistent(Bool flushTlb, Bool flushSecurity, @@ -783,11 +793,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)); @@ -828,11 +838,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; @@ -948,11 +958,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); @@ -1346,6 +1357,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 diff --git a/src_Core/RISCY_OOO/procs/lib/Btb.bsv b/src_Core/RISCY_OOO/procs/lib/Btb.bsv index 3c572d3..a1d9059 100644 --- a/src_Core/RISCY_OOO/procs/lib/Btb.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Btb.bsv @@ -38,6 +38,7 @@ import Types::*; import ProcTypes::*; import ConfigReg::*; +import DReg::*; import Map::*; import Vector::*; import CHERICC_Fat::*; @@ -58,6 +59,7 @@ endinterface // Local BTB Typedefs typedef 1 PcLsbsIgnore; typedef 1024 BtbEntries; +typedef Bit#(16) CompressedTarget; typedef 2 BtbAssociativity; typedef Bit#(TLog#(SupSizeX2)) BtbBank; // Total entries/lanes of superscalar lookup/associativity @@ -94,10 +96,12 @@ module mkBtbCore(NextAddrPred#(hashSz)) Add#(1, a__, TDiv#(tagSz, hashSz)), Add#(b__, tagSz, TMul#(TDiv#(tagSz, hashSz), hashSz))); // Read and Write ordering doesn't matter since this is a predictor - Reg#(BtbBank) firstBank_reg <- mkRegU; - Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CapMem), BtbAssociativity)) - records <- replicateM(mkMapLossyBRAM); - RWire#(BtbUpdate) updateEn <- mkRWire; + Reg#(CapMem) addr_reg <- mkRegU; + Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CapMem), 1)) + fullRecords <- replicateM(mkMapLossyBRAM); + Vector#(SupSizeX2, MapSplit#(HashedTag#(hashSz), BtbIndex, VnD#(CompressedTarget), BtbAssociativity)) + compressedRecords <- replicateM(mkMapLossyBRAM); + Reg#(Maybe#(BtbUpdate)) updateEn <- mkDReg(Invalid); function BtbAddr getBtbAddr(CapMem pc) = unpack(truncateLSB(getAddr(pc))); function BtbBank getBank(CapMem pc) = getBtbAddr(pc).bank; @@ -108,44 +112,55 @@ module mkBtbCore(NextAddrPred#(hashSz)) // no flush, accept update (* fire_when_enabled, no_implicit_conditions *) - rule canonUpdate(updateEn.wget matches tagged Valid .upd); + rule canonUpdate(updateEn matches tagged Valid .upd); let pc = upd.pc; let nextPc = upd.nextPc; let taken = upd.taken; /*$display("MapUpdate in BTB - pc %x, bank: %x, taken: %x, next: %x, time: %t", pc, getBank(pc), taken, nextPc, $time);*/ - records[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:nextPc}); + CompressedTarget shortMask = -1; + CapMem mask = ~zeroExtend(shortMask); + if ((pc&mask) == (nextPc&mask)) + compressedRecords[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:truncate(nextPc)}); + else + fullRecords[getBank(pc)].update(lookupKey(pc), VnD{v:taken, d:nextPc}); endrule method Action put_pc(CapMem pc); - BtbAddr addr = getBtbAddr(pc); - firstBank_reg <= addr.bank; + addr_reg <= pc; // Start SupSizeX2 BTB lookups, but ensure to lookup in the appropriate // bank for the alignment of each potential branch. for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin - BtbAddr a = unpack(pack(addr) + fromInteger(i)); - records[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); + BtbAddr a = unpack(pack(getBtbAddr(pc)) + fromInteger(i)); + fullRecords[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); + compressedRecords[a.bank].lookupStart(MapKeyIndex{key: hash(a.tag), index: a.index}); end endmethod method Vector#(SupSizeX2, Maybe#(CapMem)) pred; Vector#(SupSizeX2, Maybe#(CapMem)) ppcs = replicate(Invalid); - for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) - if (records[i].lookupRead matches tagged Valid .record) - ppcs[i] = record.v ? Valid(record.d):Invalid; - ppcs = rotateBy(ppcs,unpack(-firstBank_reg)); // Rotate firstBank down to zeroeth element. + for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin + if (fullRecords[i].lookupRead matches tagged Valid .r) + ppcs[i] = r.v ? Valid(r.d):Invalid; + if (compressedRecords[i].lookupRead matches tagged Valid .r) + ppcs[i] = r.v ? Valid({truncateLSB(addr_reg),r.d}):Invalid; + end + ppcs = rotateBy(ppcs,unpack(-getBtbAddr(addr_reg).bank)); // Rotate firstBank down to zeroeth element. return ppcs; endmethod method Action update(CapMem pc, CapMem nextPc, Bool taken); - updateEn.wset(BtbUpdate {pc: pc, nextPc: nextPc, taken: taken}); + updateEn <= Valid(BtbUpdate {pc: pc, nextPc: nextPc, taken: taken}); endmethod `ifdef SECURITY method Action flush method Action flush; - for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) records[i].clear; + for (Integer i = 0; i < valueOf(SupSizeX2); i = i + 1) begin + fullRecords[i].clear; + compressedRecords[i].clear; + end endmethod - method flush_done = records[0].clearDone; + method flush_done = fullRecords[0].clearDone; `else method flush = noAction; method flush_done = True; diff --git a/src_Core/RISCY_OOO/procs/lib/LatencyTimer.bsv b/src_Core/RISCY_OOO/procs/lib/LatencyTimer.bsv index 56b3853..2cdfb04 100644 --- a/src_Core/RISCY_OOO/procs/lib/LatencyTimer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/LatencyTimer.bsv @@ -23,6 +23,7 @@ import Vector::*; import Types::*; +import ConfigReg::*; // a timer to track latency of multiple misses @@ -39,8 +40,8 @@ module mkLatencyTimer(LatencyTimer#(num, timeWidth)) provisos( Alias#(idxT, Bit#(TLog#(num))), Alias#(timeT, Bit#(timeWidth)) ); - Reg#(Vector#(num, timeT)) timer <- mkReg(replicate(0)); - Reg#(Vector#(num, Bool)) started <- mkReg(replicate(False)); // for checking purposes + Reg#(Vector#(num, timeT)) timer <- mkConfigReg(replicate(0)); + Reg#(Vector#(num, Bool)) started <- mkConfigReg(replicate(False)); // for checking purposes RWire#(idxT) startEn <- mkRWire; RWire#(idxT) doneEn <- mkRWire;