diff --git a/src_Core/CPU/Core.bsv b/src_Core/CPU/Core.bsv index 7172cf9..5c29e37 100644 --- a/src_Core/CPU/Core.bsv +++ b/src_Core/CPU/Core.bsv @@ -223,6 +223,7 @@ interface CoreFixPoint; interface MemExePipeline memExeIfc; method Action killAll; // kill everything: used by commit stage interface Reg#(Bool) doStatsIfc; + method Bool pendingIncorrectSpec; endinterface `ifdef CONTRACTS_VERIFY @@ -412,7 +413,7 @@ module mkCore#(CoreId coreId)(Core); method setRegReadyAggr = writeAggr(aluWrAggrPort(i)); interface sendBypass = sendBypassIfc; method writeRegFile = writeCons(aluWrConsPort(i)); - method Action redirect(CapMem new_pc, SpecTag spec_tag, InstTag inst_tag); + method Action redirect(CapMem new_pc, SpecTag spec_tag, InstTag inst_tag, SpecBits spec_bits); if (verbose) begin $display("[ALU redirect - %d] ", i, fshow(new_pc), "; ", fshow(spec_tag), "; ", fshow(inst_tag)); @@ -423,7 +424,7 @@ module mkCore#(CoreId coreId)(Core); , inst_tag.dii_next_pid `endif ); - globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag); + globalSpecUpdate.incorrectSpec(False, spec_tag, inst_tag, spec_bits); endmethod method correctSpec = globalSpecUpdate.correctSpec[finishAluCorrectSpecPort(i)].put; method doStats = doStatsReg._read; @@ -510,9 +511,10 @@ module mkCore#(CoreId coreId)(Core); interface fpuMulDivExeIfc = fpuMulDivExe; interface memExeIfc = memExe; method Action killAll; - globalSpecUpdate.incorrectSpec(True, ?, ?); + globalSpecUpdate.incorrectSpec(True, ?, ?, 0); endmethod interface doStatsIfc = doStatsReg; + method pendingIncorrectSpec = globalSpecUpdate.pendingIncorrectSpec; endmodule CoreFixPoint coreFix <- moduleFix(mkCoreFixPoint); @@ -647,6 +649,7 @@ module mkCore#(CoreId coreId)(Core); method stbEmpty = stb.isEmpty; method stqEmpty = lsq.stqEmpty; method lsqSetAtCommit = lsq.setAtCommit; + method pauseCommit = coreFix.pendingIncorrectSpec; method tlbNoPendingReq = iTlb.noPendingReq && dTlb.noPendingReq; method setFlushTlbs; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index b39fc2c..acb59be 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -194,7 +194,7 @@ interface AluExeInput; // write reg file & set conservative sb method Action writeRegFile(PhyRIndx dst, CapPipe data); // redirect - method Action redirect(CapMem new_pc, SpecTag spec_tag, InstTag inst_tag); + method Action redirect(CapMem new_pc, SpecTag spec_tag, InstTag inst_tag, SpecBits spec_bits); // spec update method Action correctSpec(SpecTag t); @@ -469,7 +469,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); if (x.controlFlow.mispredict) (* nosplit *) begin // wrong branch predictin, we must have spec tag doAssert(isValid(x.spec_tag), "mispredicted branch must have spec tag"); - inIfc.redirect(cast(x.controlFlow.nextPc), validValue(x.spec_tag), x.tag); + inIfc.redirect(cast(x.controlFlow.nextPc), validValue(x.spec_tag), x.tag, exeToFin.spec_bits); // must be a branch, train branch predictor doAssert(x.iType == Jr || x.iType == CJALR || x.iType == CCall || x.iType == Br, "only jr, br, cjalr, and ccall can mispredict"); inIfc.fetch_train_predictors(FetchTrainBP { @@ -481,6 +481,8 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); mispred: True, isCompressed: x.isCompressed }); + $display("alu mispredict pc¤: %x, nextPc: %x, %d", + x.controlFlow.pc, x.controlFlow.nextPc, cur_cycle); `ifdef PERF_COUNT // performance counter if(inIfc.doStats) begin diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index 168b20b..397543a 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -108,6 +108,8 @@ interface CommitInput; interface Vector#(SupSize, Put#(LdStQTag)) lsqSetAtCommit; // TLB has stopped processing now method Bool tlbNoPendingReq; + // Pause committing, probably for buffered wrongSpec + method Bool pauseCommit; // set flags method Action setFlushTlbs; method Action setUpdateVMInfo; @@ -518,6 +520,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // we commit trap in two cycles: first cycle deq ROB and flush; second // cycle handles trap, redirect and handles system consistency Reg#(Maybe#(CommitTrap)) commitTrap <- mkReg(Invalid); // saves new pc here + Bool pauseCommit = isValid(commitTrap) || inIfc.pauseCommit; // maintain system consistency when system state (CSR) changes or for security function Action makeSystemConsistent(Bool flushTlb, @@ -650,7 +653,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); `ifdef INCLUDE_GDB_CONTROL (rg_run_state == RUN_STATE_RUNNING) &&& `endif - !isValid(commitTrap) &&& + !pauseCommit &&& rob.deqPort[0].deq_data.trap matches tagged Valid .trap ); rob.deqPort[0].deq; @@ -815,7 +818,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); `ifdef INCLUDE_GDB_CONTROL (rg_run_state == RUN_STATE_RUNNING) &&& `endif - !isValid(commitTrap) &&& + !pauseCommit &&& !isValid(rob.deqPort[0].deq_data.trap) &&& rob.deqPort[0].deq_data.ldKilled matches tagged Valid .killBy ); @@ -856,7 +859,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); `ifdef INCLUDE_GDB_CONTROL (rg_run_state == RUN_STATE_RUNNING) && `endif - !isValid(commitTrap) && + !pauseCommit && !isValid(rob.deqPort[0].deq_data.trap) && !isValid(rob.deqPort[0].deq_data.ldKilled) && rob.deqPort[0].deq_data.rob_inst_state == Executed && @@ -1031,7 +1034,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // Lr/Sc/Amo/MMIO cannot proceed to executed until we notify LSQ that it // has reached the commit stage rule notifyLSQCommit( - !isValid(commitTrap) && + !pauseCommit && !isValid(rob.deqPort[0].deq_data.trap) && !isValid(rob.deqPort[0].deq_data.ldKilled) && rob.deqPort[0].deq_data.rob_inst_state != Executed && @@ -1052,7 +1055,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); `ifdef INCLUDE_GDB_CONTROL (rg_run_state == RUN_STATE_RUNNING) && `endif - !isValid(commitTrap) && + !pauseCommit && !isValid(rob.deqPort[0].deq_data.trap) && !isValid(rob.deqPort[0].deq_data.ldKilled) && rob.deqPort[0].deq_data.rob_inst_state == Executed && diff --git a/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv b/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv index dbdf7c1..8234e3b 100644 --- a/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv +++ b/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv @@ -26,7 +26,7 @@ import HasSpecBits::*; import GetPut::*; import Vector::*; import ReorderBuffer::*; -import FIFO::*; +import SpecFifo::*; typedef struct { Bool kill_all; @@ -36,13 +36,14 @@ typedef struct { interface GlobalSpecUpdate#(numeric type correctSpecPortNum, numeric type conflictWrongSpecPortNum); interface Vector#(correctSpecPortNum, Put#(SpecTag)) correctSpec; - method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag); + method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag, SpecBits spec_bits); // Some rules (e.g. doFinishFpuMulDiv) in Core.bsv may not conflict with wrong spec // and is ordered before rules that calls incorrectSpec // this creates cycles in scheduling // To break the cycle, such rules can call the following interface // to manually create a conflict with rules that do incorrectSpec interface Vector#(conflictWrongSpecPortNum, Put#(void)) conflictWrongSpec; + method Bool pendingIncorrectSpec; endinterface module mkGlobalSpecUpdate#( @@ -54,12 +55,12 @@ module mkGlobalSpecUpdate#( // record correct spec tags Vector#(correctSpecPortNum, RWire#(SpecTag)) correctSpecTag <- replicateM(mkRWire); // make wrong spec conflict with correct spec - Vector#(correctSpecPortNum, RWire#(void)) spec_conflict <- replicateM(mkRWire); + Vector#(correctSpecPortNum, PulseWire) spec_conflict <- replicateM(mkPulseWire); // let the caller of conflictWrongSpec to be conflict with wrong spec - Vector#(conflictWrongSpecPortNum, RWire#(void)) wrongSpec_conflict <- replicateM(mkRWire); + Vector#(conflictWrongSpecPortNum, PulseWire) wrongSpec_conflict <- replicateM(mkPulseWire); // must be a single-element fifo to ensure all pushing rules cannot fire while we are waiting // to kill. - FIFO#(IncorrectSpec) incorrectSpec_ff <- mkFIFO1; + SpecFifo#(2,IncorrectSpec,1,1) incorrectSpec_ff <- mkSpecFifoCF(True); (* fire_when_enabled, no_implicit_conditions *) rule canon_correct_spec; @@ -69,31 +70,32 @@ module mkGlobalSpecUpdate#( mask[tag] = 0; end end + incorrectSpec_ff.specUpdate.correctSpeculation(mask); ifc.correctSpeculation(mask); rob.correctSpeculation(mask); endrule rule do_incorrect_spec; - IncorrectSpec x <- toGet(incorrectSpec_ff).get; + IncorrectSpec x = incorrectSpec_ff.first.data; + incorrectSpec_ff.deq; + incorrectSpec_ff.specUpdate.incorrectSpeculation(x.kill_all, x.spec_tag); ifc.incorrectSpeculation(x.kill_all, x.spec_tag); rob.incorrectSpeculation(x.kill_all, x.spec_tag, x.inst_tag); // conflict with correct spec for(Integer i = 0; i < valueof(correctSpecPortNum); i = i+1) begin - spec_conflict[i].wset(?); + spec_conflict[i].send; end // conflict with the caller of conflictWrongSpec for(Integer i = 0; i < valueof(conflictWrongSpecPortNum); i = i+1) begin - wrongSpec_conflict[i].wset(?); + wrongSpec_conflict[i].send; end endrule Vector#(correctSpecPortNum, Put#(SpecTag)) correctVec = ?; for(Integer i = 0; i < valueof(correctSpecPortNum); i = i+1) begin correctVec[i] = (interface Put; - method Action put(SpecTag t); + method Action put(SpecTag t) if (!spec_conflict[i]); correctSpecTag[i].wset(t); - // conflict with wrong spec - spec_conflict[i].wset(?); endmethod endinterface); end @@ -101,16 +103,21 @@ module mkGlobalSpecUpdate#( Vector#(conflictWrongSpecPortNum, Put#(void)) conflictWrongVec = ?; for(Integer i = 0; i < valueof(conflictWrongSpecPortNum); i = i+1) begin conflictWrongVec[i] = (interface Put; - method Action put(void x); - wrongSpec_conflict[i].wset(?); + method Action put(void x) if (!wrongSpec_conflict[i]); + noAction; endmethod endinterface); end interface correctSpec = correctVec; - method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag) - = incorrectSpec_ff.enq(IncorrectSpec{kill_all: kill_all, spec_tag: spec_tag, inst_tag: inst_tag}); + method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag, SpecBits spec_bits) + = incorrectSpec_ff.enq(ToSpecFifo{ + data: IncorrectSpec{kill_all: kill_all, spec_tag: spec_tag, inst_tag: inst_tag}, + spec_bits: spec_bits + }); interface conflictWrongSpec = conflictWrongVec; + + method Bool pendingIncorrectSpec = incorrectSpec_ff.notEmpty; endmodule diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 1ca4aa7..194f570 100644 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -674,7 +674,7 @@ module mkSupReorderBuffer#( Add#(1, a__, aluExeNum), Add#(1, b__, fpuMulDivExeNum) ); - Bool verbose = False; + Bool verbose = True; // doCommit rule: deq < wrongSpec (overwrite deq in doCommit) < doRenaming rule: enq Integer valid_deq_port = 0; @@ -756,6 +756,7 @@ module mkSupReorderBuffer#( // move deqP & reset valid deqP[i] <= getNextPtr(deqP[i]); valid[i][deqP[i]][valid_deq_port] <= False; + $display("deq[%d][%d]", i, deqP[i]); end end // update firstDeqWay: find the first deq port that is not enabled @@ -935,6 +936,9 @@ module mkSupReorderBuffer#( end endfunction for(Integer i = 0; i < valueof(SingleScalarSize); i = i+1) begin + if (in_kill_range(fromInteger(i)) != (row[w][i].dependsOn_wrongSpec(specTag) && valid[w][i][valid_wrongSpec_port])) + $display("enqP: %d, enqPNext: %d, w: %d, i: %d, wrongSpec: %d, valid: %d, cur_cycle: %d", + enqP[w], enqPNext[w], w, i, row[w][i].dependsOn_wrongSpec(specTag), valid[w][i][valid_wrongSpec_port], cur_cycle); doAssert( in_kill_range(fromInteger(i)) == (row[w][i].dependsOn_wrongSpec(specTag) && valid[w][i][valid_wrongSpec_port]), diff --git a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv index 818a340..8eb8c0e 100644 --- a/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SpecFifo.bsv @@ -43,6 +43,7 @@ interface SpecFifo#( method Action enq(ToSpecFifo#(t) x); method Action deq; method ToSpecFifo#(t) first; + method Bool notEmpty; interface SpeculationUpdate specUpdate; endinterface @@ -166,6 +167,8 @@ module mkSpecFifo#( }; endmethod + method Bool notEmpty = valid[deqP][sched.validDeqPort]; + interface SpeculationUpdate specUpdate; method Action correctSpeculation(SpecBits mask); // clear spec bits for all entries @@ -310,6 +313,8 @@ module mkSpecFifoCF#( }; endmethod + method Bool notEmpty = valid[1][deqP]; + interface SpeculationUpdate specUpdate; method correctSpeculation = correctSpecF.enq; method incorrectSpeculation(kill_all, specTag) = diff --git a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv index 24fa28c..6513a8c 100644 --- a/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv +++ b/src_Core/RISCY_OOO/procs/lib/SplitLSQ.bsv @@ -949,17 +949,7 @@ module mkSplitLSQ(SplitLSQ); // make wrongSpec conflict with all others (but not correctSpec method and // findIssue) - RWire#(void) wrongSpec_hit_conflict <- mkRWire; - RWire#(void) wrongSpec_enqIss_conflict <- mkRWire; - RWire#(void) wrongSpec_enq_conflict <- mkRWire; - RWire#(void) wrongSpec_cacheEvict_conflict <- mkRWire; - RWire#(void) wrongSpec_update_conflict <- mkRWire; - RWire#(void) wrongSpec_issue_conflict <- mkRWire; - RWire#(void) wrongSpec_respLd_conflict <- mkRWire; - RWire#(void) wrongSpec_deqLd_conflict <- mkRWire; - RWire#(void) wrongSpec_deqSt_conflict <- mkRWire; - RWire#(void) wrongSpec_verify_conflict <- mkRWire; - RWire#(void) wrongSpec_wakeBySB_conflict <- mkRWire; + PulseWire wrongSpec_conflict <- mkPulseWire; // make wrongSpec more urgent than firstSt (resolve bsc error) Wire#(Bool) wrongSpec_urgent_firstSt <- mkDWire(True); Map#(Bit#(10),Bit#(6),Int#(3),2) ldKillMap <- mkMapLossy(minBound); @@ -1145,7 +1135,7 @@ module mkSplitLSQ(SplitLSQ); end endrule - rule enqIssueQ(issueLdInfo.wget matches tagged Valid .info); + rule enqIssueQ(issueLdInfo.wget matches tagged Valid .info &&& !wrongSpec_conflict); if(verbose) begin $display("[LSQ - enqIss] ", fshow(info)); end @@ -1187,8 +1177,6 @@ module mkSplitLSQ(SplitLSQ); spec_bits: ld_specBits_enqIss[info.tag] }); ld_inIssueQ_enqIss[info.tag] <= True; - // make conflict with incorrect spec - wrongSpec_enqIss_conflict.wset(?); endrule // Verify SQ entry one by one @@ -1211,7 +1199,8 @@ module mkSplitLSQ(SplitLSQ); // NOTE that when SQ is full and all verified, verifyP will point to a // valid and verified entry rule verifySt(st_valid_verify[st_verifyP_verify] && - !st_verified_verify[st_verifyP_verify]); + !st_verified_verify[st_verifyP_verify] && + !wrongSpec_conflict); StQTag verP = st_verifyP_verify; // check if the entry can be verified. We should not fire this rule if @@ -1261,9 +1250,6 @@ module mkSplitLSQ(SplitLSQ); joinActions(map(setVerified, idxVec)); if(verbose) $display("[LSQ - verifySt] st_verifyP %d", verP); - - // make conflict with incorrect spec - wrongSpec_verify_conflict.wset(?); endrule `ifdef BSIM @@ -1437,10 +1423,7 @@ module mkSplitLSQ(SplitLSQ); endcase); endmethod - method ActionValue#(LSQHitInfo) getHit(LdStQTag t); - // Conflict with wrong spec. This makes cache pipelineResp rule - // conflict with wrong spec, and can help avoid scheduling cycle. - wrongSpec_hit_conflict.wset(?); + method ActionValue#(LSQHitInfo) getHit(LdStQTag t) if (!wrongSpec_conflict); return (case(t) matches tagged Ld .tag: (LSQHitInfo { waitWPResp: ld_waitWPResp_hit[tag], @@ -1465,7 +1448,7 @@ module mkSplitLSQ(SplitLSQ); MemInst mem_inst, Maybe#(PhyDst) dst, SpecBits spec_bits, - Bit#(16) pc_hash) if(ld_can_enq_wire); + Bit#(16) pc_hash) if(ld_can_enq_wire && !wrongSpec_conflict); if(verbose) begin $display("[LSQ - enqLd] enqP %d; ", ld_enqP, "; ", fshow(inst_tag), @@ -1518,14 +1501,12 @@ module mkSplitLSQ(SplitLSQ); ld_olderSt_enq[ld_enqP] <= Invalid; ld_olderStVerified_enq[ld_enqP] <= False; end - // make conflict with incorrect spec - wrongSpec_enq_conflict.wset(?); endmethod method Action enqSt(InstTag inst_tag, MemInst mem_inst, Maybe#(PhyDst) dst, - SpecBits spec_bits) if(st_can_enq_wire); + SpecBits spec_bits) if(st_can_enq_wire && !wrongSpec_conflict); if(verbose) begin $display("[LSQ - enqSt] enqP %d; ", st_enqP, "; ", fshow(inst_tag), @@ -1554,8 +1535,6 @@ module mkSplitLSQ(SplitLSQ); st_verified_enq[st_enqP] <= False; st_specBits_enq[st_enqP] <= spec_bits; st_atCommit_enq[st_enqP] <= False; - // make conflict with incorrect spec - wrongSpec_enq_conflict.wset(?); endmethod method Action updateData(StQTag t, MemTaggedData d); @@ -1570,7 +1549,7 @@ module mkSplitLSQ(SplitLSQ); method ActionValue#(LSQUpdateAddrResult) updateAddr( LdStQTag lsqTag, Maybe#(Trap) fault, Bool allowCap, Addr pa, Bool mmio, ByteOrTagEn shift_be - ); + ) if (!wrongSpec_conflict); // index vec for vector functions Vector#(LdQSize, LdQTag) idxVec = genWith(fromInteger); @@ -1736,9 +1715,6 @@ module mkSplitLSQ(SplitLSQ); end end - // make conflict with incorrect spec - wrongSpec_update_conflict.wset(?); - // return waiting for wp resp bit: for deciding whether the updating Ld // can be issued return LSQUpdateAddrResult { @@ -1753,7 +1729,7 @@ module mkSplitLSQ(SplitLSQ); method ActionValue#(LSQIssueLdResult) issueLd(LdQTag tag, Addr pa, ByteOrTagEn shift_be, - SBSearchRes sbRes); + SBSearchRes sbRes) if (!wrongSpec_conflict); if(verbose) begin $display("[LSQ - issueLd] ", fshow(tag), "; ", fshow(pa), "; ", fshow(shift_be), "; ", fshow(sbRes)); @@ -2022,9 +1998,6 @@ module mkSplitLSQ(SplitLSQ); end `endif - // make conflict with incorrect spec - wrongSpec_issue_conflict.wset(?); - return issRes; endmethod @@ -2041,7 +2014,7 @@ module mkSplitLSQ(SplitLSQ); return issueLdQ.first.data; endmethod - method ActionValue#(LSQRespLdResult) respLd(LdQTag t, MemTaggedData alignedData); + method ActionValue#(LSQRespLdResult) respLd(LdQTag t, MemTaggedData alignedData) if (!wrongSpec_conflict); let res = LSQRespLdResult { wrongPath: False, dst: Invalid, @@ -2090,8 +2063,6 @@ module mkSplitLSQ(SplitLSQ); $display("[LSQ - respLd] ", fshow(t), "; ", fshow(alignedData), "; ", fshow(res)); end - // make conflict with incorrect spec - wrongSpec_respLd_conflict.wset(?); // return return res; endmethod @@ -2116,7 +2087,7 @@ module mkSplitLSQ(SplitLSQ); }; endmethod - method Action deqLd if(deqLdGuard); + method Action deqLd if(deqLdGuard && !wrongSpec_conflict); LdQTag deqP = ld_deqP_deqLd; if(verbose) $display("[LSQ - deqLd] deqP %d", deqP); @@ -2163,9 +2134,6 @@ module mkSplitLSQ(SplitLSQ); endfunction Vector#(LdQSize, LdQTag) idxVec = genWith(fromInteger); joinActions(map(setReady, idxVec)); - - // make conflict with incorrect spec - wrongSpec_deqLd_conflict.wset(?); endmethod method StQDeqEntry firstSt if(deqStGuard && wrongSpec_urgent_firstSt); @@ -2186,7 +2154,7 @@ module mkSplitLSQ(SplitLSQ); }; endmethod - method Action deqSt if(deqStGuard); + method Action deqSt if(deqStGuard && !wrongSpec_conflict); StQTag deqP = st_deqP; if(verbose) $display("[LSQ - deqSt] deqP %d", deqP); @@ -2234,13 +2202,10 @@ module mkSplitLSQ(SplitLSQ); endfunction Vector#(LdQSize, LdQTag) idxVec = genWith(fromInteger); joinActions(map(resetSt, idxVec)); - - // make conflict with incorrect spec - wrongSpec_deqSt_conflict.wset(?); endmethod `ifdef TSO_MM - method Action cacheEvict(LineAddr lineAddr); + method Action cacheEvict(LineAddr lineAddr) if (!wrongSpec_conflict); if(verbose) $display("[LSQ - cacheEvict] ", fshow(lineAddr)); // kill a load if it satisfies the following conditions: // (1) valid @@ -2270,14 +2235,11 @@ module mkSplitLSQ(SplitLSQ); doAssert(!ld_isMMIO_evict[killTag], "cannot kill MMIO"); doAssert(ld_memFunc[killTag] == Ld, "can only kill Ld"); end - - // make conflict with incorrect spec - wrongSpec_cacheEvict_conflict.wset(?); endmethod `else - method Action wakeupLdStalledBySB(SBIndex sbIdx); + method Action wakeupLdStalledBySB(SBIndex sbIdx) if (!wrongSpec_conflict); if(verbose) begin $display("[LSQ - wakeupBySB] ", fshow(sbIdx)); end @@ -2292,8 +2254,6 @@ module mkSplitLSQ(SplitLSQ); endfunction Vector#(LdQSize, LdQTag) idxVec = genWith(fromInteger); joinActions(map(setReady, idxVec)); - // make conflict with incorrect spec - wrongSpec_wakeBySB_conflict.wset(?); endmethod `endif @@ -2438,17 +2398,7 @@ module mkSplitLSQ(SplitLSQ); end // make conflict with others - wrongSpec_hit_conflict.wset(?); - wrongSpec_enqIss_conflict.wset(?); - wrongSpec_enq_conflict.wset(?); - wrongSpec_update_conflict.wset(?); - wrongSpec_issue_conflict.wset(?); - wrongSpec_respLd_conflict.wset(?); - wrongSpec_deqLd_conflict.wset(?); - wrongSpec_deqSt_conflict.wset(?); - wrongSpec_verify_conflict.wset(?); - wrongSpec_cacheEvict_conflict.wset(?); - wrongSpec_wakeBySB_conflict.wset(?); + wrongSpec_conflict.send(); // more urgent than firstSt wrongSpec_urgent_firstSt <= True; endmethod