A version that seems to actually run.
The buffer in GlobalSpecUpdate has to be a SpecFifo.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]),
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user