diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv index 8c30f91..5d58e86 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv @@ -146,18 +146,19 @@ typedef struct { MemTaggedData shiftedData; } WaitStResp deriving(Bits, Eq, FShow); +//SpecFifo#(2,IncorrectSpec,1,1) incorrectSpec_ff <- mkSpecFifoCF(True); // synthesized pipeline fifos -typedef SpecFifo_SB_deq_enq_C_deq_enq#(1, MemDispatchToRegRead) MemDispToRegFifo; +//typedef SpecFifo_SB_deq_enq_C_deq_enq#(1, MemDispatchToRegRead) MemDispToRegFifo; (* synthesize *) -module mkMemDispToRegFifo(MemDispToRegFifo); - let m <- mkSpecFifo_SB_deq_enq_C_deq_enq(False); +module mkMemDispToRegFifo(SpecFifo#(2,MemDispatchToRegRead,1,1)); + let m <- mkSpecFifoCF2(True); return m; endmodule -typedef SpecFifo_SB_deq_enq_C_deq_enq#(1, MemRegReadToExe) MemRegToExeFifo; +//typedef SpecFifo_SB_deq_enq_C_deq_enq#(1, MemRegReadToExe) MemRegToExeFifo; (* synthesize *) -module mkMemRegToExeFifo(MemRegToExeFifo); - let m <- mkSpecFifo_SB_deq_enq_C_deq_enq(False); +module mkMemRegToExeFifo(SpecFifo#(2,MemRegReadToExe,1,1)); + let m <- mkSpecFifoCF2(True); return m; endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/ITlb.bsv b/src_Core/RISCY_OOO/procs/lib/ITlb.bsv index 06b88a0..ecb12b7 100644 --- a/src_Core/RISCY_OOO/procs/lib/ITlb.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ITlb.bsv @@ -249,6 +249,8 @@ module mkITlb(ITlb::ITlb); no_pending_wire <= !isValid(miss); endrule + Reg#(Bool) vm_info_change <- mkReg(False); + method Action flush if(!needFlush); needFlush <= True; waitFlushP <= False; @@ -257,9 +259,10 @@ module mkITlb(ITlb::ITlb); // (2) flush truly starts when there is no pending req endmethod - method Bool flush_done = !needFlush; + method Bool flush_done = !needFlush && !vm_info_change; method Action updateVMInfo(VMInfo vm); + if (vm_info != vm) vm_info_change <= True; vm_info <= vm; endmethod diff --git a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv index 242e03e..63d37b7 100644 --- a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv @@ -323,6 +323,119 @@ module mkSpecFifoCF#( endinterface endmodule +module mkSpecFifoCF2#( + Bool lazyEnq // whether we calculate enq guard lazily +)( + SpecFifo#(size, t, validPortNum, sbPortNum) +) provisos ( + Alias#(idxT, Bit#(TLog#(size))), + Bits#(t, _tsz), + FShow#(t) +); + // correct spec is always the last + Integer sbCorrectSpecPort = valueof(sbPortNum) - 1; + + Ehr#(2, Vector#(size, Bool)) valid <- mkEhr(replicate(False)); + Vector#(size, Reg#(t)) row <- replicateM(mkConfigRegU); + Ehr#(3, Vector#(size, SpecBits)) specBits <- mkEhr(?); + + Reg#(Maybe#(SpecBits)) correctSpec <- mkDReg(Invalid); + Reg#(Maybe#(IncorrectSpeculation)) incorrectSpec <- mkDReg(Invalid); + + PulseWire wrongSpec_conflict <- mkPulseWire; + + Reg#(idxT) enqP <- mkConfigReg(0); + Ehr#(2, idxT) deqP_ehr <- mkEhr(0); + Reg#(idxT) deqP = deqP_ehr[0]; // port 0 is for deq and canon_deqP + + function idxT getNextPtr(idxT p); + return p == fromInteger(valueOf(size) - 1) ? 0 : p + 1; + endfunction + + Bool empty_for_canon = all( \== (False) , valid[0] ); + rule canon_deqP(!valid[0][deqP] && ((enqP != deqP || !empty_for_canon) && !wrongSpec_conflict)); + // element at deqP was killed, so increment deqP + deqP <= getNextPtr(deqP); + endrule + + (* fire_when_enabled, no_implicit_conditions *) + rule canon_speculation; + Vector#(size, SpecBits) newSpecBits = specBits[0]; + // Fold in CorrectSpec update: + if (correctSpec matches tagged Valid .mask) begin + // clear spec bits for all entries + for (Integer i=0; i