Request queues in L1 cache
This commit is contained in:
committed by
Jonathan Woodruff
parent
03b8face1e
commit
535d85ff35
@@ -58,6 +58,8 @@ typedef struct {
|
|||||||
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) ram;
|
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) ram;
|
||||||
// replace info, actually not needed, just output for debug purposes
|
// replace info, actually not needed, just output for debug purposes
|
||||||
repT repInfo;
|
repT repInfo;
|
||||||
|
// the next-in-line queuer for this cache index
|
||||||
|
setAuxT setAuxData;
|
||||||
} PipeOut#(
|
} PipeOut#(
|
||||||
type wayT,
|
type wayT,
|
||||||
type tagT,
|
type tagT,
|
||||||
@@ -67,6 +69,7 @@ typedef struct {
|
|||||||
type otherT,
|
type otherT,
|
||||||
type repT,
|
type repT,
|
||||||
type lineT,
|
type lineT,
|
||||||
|
type setAuxT,
|
||||||
type pipeCmdT
|
type pipeCmdT
|
||||||
) deriving(Bits, Eq, FShow);
|
) deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
@@ -80,16 +83,18 @@ interface CCPipe#(
|
|||||||
type otherT,
|
type otherT,
|
||||||
type repT,
|
type repT,
|
||||||
type lineT,
|
type lineT,
|
||||||
|
type setAuxT,
|
||||||
type pipeCmdT
|
type pipeCmdT
|
||||||
);
|
);
|
||||||
method Action enq(pipeCmdT cmd, Maybe#(lineT) respLine, RespState#(msiT) toState);
|
method Action enq(pipeCmdT cmd, Maybe#(lineT) respLine, RespState#(msiT) toState);
|
||||||
method Bool notFull;
|
method Bool notFull;
|
||||||
method PipeOut#(Bit#(TLog#(wayNum)), tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT) first;
|
method PipeOut#(Bit#(TLog#(wayNum)), tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT) first;
|
||||||
method PipeOut#(Bit#(TLog#(wayNum)), tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT) unguard_first;
|
method PipeOut#(Bit#(TLog#(wayNum)), tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT) unguard_first;
|
||||||
method Bool notEmpty;
|
method Bool notEmpty;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(pipeCmdT) newCmd,
|
Maybe#(pipeCmdT) newCmd,
|
||||||
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) wrRam,
|
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) wrRam,
|
||||||
|
setAuxT setAuxData,
|
||||||
Bool updateRep // update replacement info
|
Bool updateRep // update replacement info
|
||||||
);
|
);
|
||||||
// empty signal when we need to flush self-invalidate cache
|
// empty signal when we need to flush self-invalidate cache
|
||||||
@@ -110,6 +115,7 @@ typedef struct {
|
|||||||
// CRs/PRs info
|
// CRs/PRs info
|
||||||
Maybe#(lineT) respLine;
|
Maybe#(lineT) respLine;
|
||||||
RespState#(msiT) toState;
|
RespState#(msiT) toState;
|
||||||
|
Maybe#(setAuxT) setAuxData;
|
||||||
} Enq2Match#(
|
} Enq2Match#(
|
||||||
numeric type wayNum,
|
numeric type wayNum,
|
||||||
type tagT,
|
type tagT,
|
||||||
@@ -119,6 +125,7 @@ typedef struct {
|
|||||||
type otherT,
|
type otherT,
|
||||||
type repT,
|
type repT,
|
||||||
type lineT,
|
type lineT,
|
||||||
|
type setAuxT,
|
||||||
type pipeCmdT
|
type pipeCmdT
|
||||||
) deriving(Bits, Eq, FShow);
|
) deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
@@ -134,6 +141,7 @@ typedef struct {
|
|||||||
repT repInfo;
|
repT repInfo;
|
||||||
// bypassed or resp line
|
// bypassed or resp line
|
||||||
Maybe#(lineT) line;
|
Maybe#(lineT) line;
|
||||||
|
setAuxT setAuxData;
|
||||||
} Match2Out#(
|
} Match2Out#(
|
||||||
type wayT,
|
type wayT,
|
||||||
type tagT,
|
type tagT,
|
||||||
@@ -143,6 +151,7 @@ typedef struct {
|
|||||||
type otherT,
|
type otherT,
|
||||||
type repT,
|
type repT,
|
||||||
type lineT,
|
type lineT,
|
||||||
|
type setAuxT,
|
||||||
type pipeCmdT
|
type pipeCmdT
|
||||||
) deriving(Bits, Eq, FShow);
|
) deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
@@ -151,6 +160,7 @@ typedef struct {
|
|||||||
wayT way;
|
wayT way;
|
||||||
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) ram; // data to write into RAM
|
RamData#(tagT, msiT, dirT, ownerT, otherT, lineT) ram; // data to write into RAM
|
||||||
repT repInfo; // replacement info write into RAM
|
repT repInfo; // replacement info write into RAM
|
||||||
|
setAuxT setAuxData;
|
||||||
} BypassInfo#(
|
} BypassInfo#(
|
||||||
type wayT,
|
type wayT,
|
||||||
type indexT,
|
type indexT,
|
||||||
@@ -160,7 +170,8 @@ typedef struct {
|
|||||||
type ownerT,
|
type ownerT,
|
||||||
type otherT,
|
type otherT,
|
||||||
type repT,
|
type repT,
|
||||||
type lineT
|
type lineT,
|
||||||
|
type setAuxT
|
||||||
) deriving(Bits, Eq, FShow);
|
) deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -208,19 +219,20 @@ module mkCCPipe#(
|
|||||||
function ActionValue#(repT) updateRepInfo(repT oldRep, wayT hitWay),
|
function ActionValue#(repT) updateRepInfo(repT oldRep, wayT hitWay),
|
||||||
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam,
|
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam,
|
||||||
RWBramCore#(indexT, repT) repRam,
|
RWBramCore#(indexT, repT) repRam,
|
||||||
RWBramCore#(dataIndexT, lineT) dataRam
|
RWBramCore#(dataIndexT, lineT) dataRam,
|
||||||
|
RWBramCore#(indexT, setAuxT) setAuxDataRam
|
||||||
)(
|
)(
|
||||||
CCPipe#(wayNum, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)
|
CCPipe#(wayNum, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)
|
||||||
) provisos (
|
) provisos (
|
||||||
Alias#(wayT, Bit#(TLog#(wayNum))),
|
Alias#(wayT, Bit#(TLog#(wayNum))),
|
||||||
Alias#(indexT, Bit#(_indexSz)),
|
Alias#(indexT, Bit#(_indexSz)),
|
||||||
Alias#(infoT, CacheInfo#(tagT, msiT, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, msiT, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, msiT, dirT, ownerT, otherT, lineT)),
|
Alias#(ramDataT, RamData#(tagT, msiT, dirT, ownerT, otherT, lineT)),
|
||||||
Alias#(respStateT, RespState#(msiT)),
|
Alias#(respStateT, RespState#(msiT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(enq2MatchT, Enq2Match#(wayNum, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(enq2MatchT, Enq2Match#(wayNum, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(match2OutT, Match2Out#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(match2OutT, Match2Out#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(bypassInfoT, BypassInfo#(wayT, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT)),
|
Alias#(bypassInfoT, BypassInfo#(wayT, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT)),
|
||||||
Bits#(tagT, _tagSz),
|
Bits#(tagT, _tagSz),
|
||||||
Bits#(msiT, _msiSz),
|
Bits#(msiT, _msiSz),
|
||||||
Bits#(dirT, _dirSz),
|
Bits#(dirT, _dirSz),
|
||||||
@@ -229,6 +241,7 @@ module mkCCPipe#(
|
|||||||
Bits#(repT, _repSz),
|
Bits#(repT, _repSz),
|
||||||
Bits#(lineT, _lineSz),
|
Bits#(lineT, _lineSz),
|
||||||
Bits#(pipeCmdT, _pipeCmdSz),
|
Bits#(pipeCmdT, _pipeCmdSz),
|
||||||
|
Bits#(setAuxT, _setOtherSz),
|
||||||
// index to data ram: {way, normal index}
|
// index to data ram: {way, normal index}
|
||||||
Alias#(dataIndexT, Bit#(TAdd#(TLog#(wayNum), _indexSz)))
|
Alias#(dataIndexT, Bit#(TAdd#(TLog#(wayNum), _indexSz)))
|
||||||
);
|
);
|
||||||
@@ -274,6 +287,8 @@ module mkCCPipe#(
|
|||||||
end
|
end
|
||||||
repRam.deqRdResp;
|
repRam.deqRdResp;
|
||||||
repT repInfo = fromMaybe(repRam.rdResp, e2m.repInfo);
|
repT repInfo = fromMaybe(repRam.rdResp, e2m.repInfo);
|
||||||
|
setAuxDataRam.deqRdResp;
|
||||||
|
setAuxT setAuxData = fromMaybe(setAuxDataRam.rdResp, e2m.setAuxData);
|
||||||
// do tag match to get way to occupy
|
// do tag match to get way to occupy
|
||||||
Vector#(wayNum, tagT) tagVec;
|
Vector#(wayNum, tagT) tagVec;
|
||||||
Vector#(wayNum, msiT) csVec;
|
Vector#(wayNum, msiT) csVec;
|
||||||
@@ -297,7 +312,8 @@ module mkCCPipe#(
|
|||||||
pRqMiss: pRqMiss,
|
pRqMiss: pRqMiss,
|
||||||
info: infoVec[way],
|
info: infoVec[way],
|
||||||
repInfo: repInfo,
|
repInfo: repInfo,
|
||||||
line: e2m.respLine
|
line: e2m.respLine,
|
||||||
|
setAuxData: setAuxData
|
||||||
};
|
};
|
||||||
if(e2m.toState matches tagged UpCs .s) begin
|
if(e2m.toState matches tagged UpCs .s) begin
|
||||||
UpdateByUpCs#(msiT) upd <- updateByUpCs(
|
UpdateByUpCs#(msiT) upd <- updateByUpCs(
|
||||||
@@ -332,7 +348,8 @@ module mkCCPipe#(
|
|||||||
info: m2o.info,
|
info: m2o.info,
|
||||||
line: fromMaybe(dataRam.rdResp, m2o.line)
|
line: fromMaybe(dataRam.rdResp, m2o.line)
|
||||||
},
|
},
|
||||||
repInfo: m2o.repInfo
|
repInfo: m2o.repInfo,
|
||||||
|
setAuxData: m2o.setAuxData
|
||||||
};
|
};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -348,17 +365,20 @@ module mkCCPipe#(
|
|||||||
infoRam[i].rdReq(index);
|
infoRam[i].rdReq(index);
|
||||||
end
|
end
|
||||||
repRam.rdReq(index);
|
repRam.rdReq(index);
|
||||||
|
setAuxDataRam.rdReq(index);
|
||||||
// write reg & get bypass
|
// write reg & get bypass
|
||||||
enq2MatchT e2m = Enq2Match {
|
enq2MatchT e2m = Enq2Match {
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
infoVec: replicate(Invalid),
|
infoVec: replicate(Invalid),
|
||||||
repInfo: Invalid,
|
repInfo: Invalid,
|
||||||
respLine: respLine,
|
respLine: respLine,
|
||||||
toState: toState
|
toState: toState,
|
||||||
|
setAuxData: Invalid
|
||||||
};
|
};
|
||||||
if(bypass.wget matches tagged Valid .b &&& b.index == index) begin
|
if(bypass.wget matches tagged Valid .b &&& b.index == index) begin
|
||||||
e2m.infoVec[b.way] = Valid (b.ram.info);
|
e2m.infoVec[b.way] = Valid (b.ram.info);
|
||||||
e2m.repInfo = Valid (b.repInfo);
|
e2m.repInfo = Valid (b.repInfo);
|
||||||
|
e2m.setAuxData = Valid(b.setAuxData);
|
||||||
end
|
end
|
||||||
enq2Mat_enq <= Valid (e2m);
|
enq2Mat_enq <= Valid (e2m);
|
||||||
endmethod
|
endmethod
|
||||||
@@ -375,7 +395,7 @@ module mkCCPipe#(
|
|||||||
|
|
||||||
method Bool notEmpty = deq_guard;
|
method Bool notEmpty = deq_guard;
|
||||||
|
|
||||||
method Action deqWrite(Maybe#(pipeCmdT) newCmd, ramDataT wrRam, Bool updateRep) if(deq_guard);
|
method Action deqWrite(Maybe#(pipeCmdT) newCmd, ramDataT wrRam, setAuxT setAuxData, Bool updateRep) if(deq_guard);
|
||||||
match2OutT m2o = fromMaybe(?, mat2Out_out);
|
match2OutT m2o = fromMaybe(?, mat2Out_out);
|
||||||
wayT way = m2o.way;
|
wayT way = m2o.way;
|
||||||
indexT index = getIndex(m2o.cmd);
|
indexT index = getIndex(m2o.cmd);
|
||||||
@@ -388,12 +408,14 @@ module mkCCPipe#(
|
|||||||
infoRam[way].wrReq(index, wrRam.info);
|
infoRam[way].wrReq(index, wrRam.info);
|
||||||
repRam.wrReq(index, repInfo);
|
repRam.wrReq(index, repInfo);
|
||||||
dataRam.wrReq(getDataRamIndex(way, index), wrRam.line);
|
dataRam.wrReq(getDataRamIndex(way, index), wrRam.line);
|
||||||
|
setAuxDataRam.wrReq(index, setAuxData);
|
||||||
// set bypass to Enq and Match stages
|
// set bypass to Enq and Match stages
|
||||||
bypass.wset(BypassInfo {
|
bypass.wset(BypassInfo {
|
||||||
index: index,
|
index: index,
|
||||||
way: way,
|
way: way,
|
||||||
ram: wrRam,
|
ram: wrRam,
|
||||||
repInfo: repInfo
|
repInfo: repInfo,
|
||||||
|
setAuxData: setAuxData
|
||||||
});
|
});
|
||||||
// change pipeline reg
|
// change pipeline reg
|
||||||
if(newCmd matches tagged Valid .cmd) begin
|
if(newCmd matches tagged Valid .cmd) begin
|
||||||
@@ -404,7 +426,8 @@ module mkCCPipe#(
|
|||||||
pRqMiss: False, // reset (not valid for swapped in pRq)
|
pRqMiss: False, // reset (not valid for swapped in pRq)
|
||||||
info: wrRam.info, // get bypass
|
info: wrRam.info, // get bypass
|
||||||
repInfo: repInfo, // get bypass
|
repInfo: repInfo, // get bypass
|
||||||
line: Valid (wrRam.line) // get bypass
|
line: Valid (wrRam.line), // get bypass
|
||||||
|
setAuxData: setAuxData
|
||||||
});
|
});
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
@@ -443,19 +466,20 @@ module mkCCPipeSingleCycle#(
|
|||||||
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam,
|
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam,
|
||||||
RWBramCore#(indexT, repT) repRam,
|
RWBramCore#(indexT, repT) repRam,
|
||||||
// Must be BRAMs with integrated forwarding; e.g. mkRWBramCoreForwarded
|
// Must be BRAMs with integrated forwarding; e.g. mkRWBramCoreForwarded
|
||||||
Vector#(wayNum, RWBramCore#(dataIndexT, lineT)) dataRam
|
Vector#(wayNum, RWBramCore#(dataIndexT, lineT)) dataRam,
|
||||||
|
RWBramCore#(indexT, setAuxT) setAuxDataRam
|
||||||
)(
|
)(
|
||||||
CCPipe#(wayNum, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)
|
CCPipe#(wayNum, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)
|
||||||
) provisos (
|
) provisos (
|
||||||
Alias#(wayT, Bit#(TLog#(wayNum))),
|
Alias#(wayT, Bit#(TLog#(wayNum))),
|
||||||
Alias#(indexT, Bit#(_indexSz)),
|
Alias#(indexT, Bit#(_indexSz)),
|
||||||
Alias#(infoT, CacheInfo#(tagT, msiT, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, msiT, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, msiT, dirT, ownerT, otherT, lineT)),
|
Alias#(ramDataT, RamData#(tagT, msiT, dirT, ownerT, otherT, lineT)),
|
||||||
Alias#(respStateT, RespState#(msiT)),
|
Alias#(respStateT, RespState#(msiT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(enq2MatchT, Enq2Match#(wayNum, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(enq2MatchT, Enq2Match#(wayNum, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(match2OutT, Match2Out#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, pipeCmdT)),
|
Alias#(match2OutT, Match2Out#(wayT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT, pipeCmdT)),
|
||||||
Alias#(bypassInfoT, BypassInfo#(wayT, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT)),
|
Alias#(bypassInfoT, BypassInfo#(wayT, indexT, tagT, msiT, dirT, ownerT, otherT, repT, lineT, setAuxT)),
|
||||||
Bits#(tagT, _tagSz),
|
Bits#(tagT, _tagSz),
|
||||||
Bits#(msiT, _msiSz),
|
Bits#(msiT, _msiSz),
|
||||||
Bits#(dirT, _dirSz),
|
Bits#(dirT, _dirSz),
|
||||||
@@ -464,6 +488,7 @@ module mkCCPipeSingleCycle#(
|
|||||||
Bits#(repT, _repSz),
|
Bits#(repT, _repSz),
|
||||||
Bits#(lineT, _lineSz),
|
Bits#(lineT, _lineSz),
|
||||||
Bits#(pipeCmdT, _pipeCmdSz),
|
Bits#(pipeCmdT, _pipeCmdSz),
|
||||||
|
Bits#(setAuxT, _setOtherSz),
|
||||||
Alias#(dataIndexT, Bit#(_indexSz))
|
Alias#(dataIndexT, Bit#(_indexSz))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -494,6 +519,9 @@ module mkCCPipeSingleCycle#(
|
|||||||
end
|
end
|
||||||
repRam.deqRdResp;
|
repRam.deqRdResp;
|
||||||
repT repInfo = fromMaybe(repRam.rdResp, e2m.repInfo);
|
repT repInfo = fromMaybe(repRam.rdResp, e2m.repInfo);
|
||||||
|
setAuxDataRam.deqRdResp;
|
||||||
|
setAuxT setAuxData = fromMaybe(setAuxDataRam.rdResp, e2m.setAuxData);
|
||||||
|
//$display("%t : doTagMatch repRamdeqRdResp ", $time);
|
||||||
// do tag match to get way to occupy
|
// do tag match to get way to occupy
|
||||||
Vector#(wayNum, tagT) tagVec;
|
Vector#(wayNum, tagT) tagVec;
|
||||||
Vector#(wayNum, msiT) csVec;
|
Vector#(wayNum, msiT) csVec;
|
||||||
@@ -513,7 +541,8 @@ module mkCCPipeSingleCycle#(
|
|||||||
pRqMiss: pRqMiss,
|
pRqMiss: pRqMiss,
|
||||||
info: infoVec[way],
|
info: infoVec[way],
|
||||||
repInfo: repInfo,
|
repInfo: repInfo,
|
||||||
line: isValid(e2m.respLine) ? e2m.respLine:Valid(dataVec[way])
|
line: isValid(e2m.respLine) ? e2m.respLine:Valid(dataVec[way]),
|
||||||
|
setAuxData: setAuxData
|
||||||
};
|
};
|
||||||
if(e2m.toState matches tagged UpCs .s) begin
|
if(e2m.toState matches tagged UpCs .s) begin
|
||||||
UpdateByUpCs#(msiT) upd <- updateByUpCs(
|
UpdateByUpCs#(msiT) upd <- updateByUpCs(
|
||||||
@@ -546,7 +575,8 @@ module mkCCPipeSingleCycle#(
|
|||||||
info: m2o.info,
|
info: m2o.info,
|
||||||
line: m2o.line.Valid
|
line: m2o.line.Valid
|
||||||
},
|
},
|
||||||
repInfo: m2o.repInfo
|
repInfo: m2o.repInfo,
|
||||||
|
setAuxData: m2o.setAuxData
|
||||||
};
|
};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -563,13 +593,16 @@ module mkCCPipeSingleCycle#(
|
|||||||
dataRam[i].rdReq(index);
|
dataRam[i].rdReq(index);
|
||||||
end
|
end
|
||||||
repRam.rdReq(index);
|
repRam.rdReq(index);
|
||||||
|
setAuxDataRam.rdReq(index);
|
||||||
|
//$display("%t : enq repRam.rdReq ", $time);
|
||||||
// write reg
|
// write reg
|
||||||
enq2MatchT e2m = Enq2Match {
|
enq2MatchT e2m = Enq2Match {
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
infoVec: replicate(Invalid),
|
infoVec: replicate(Invalid),
|
||||||
repInfo: Invalid,
|
repInfo: Invalid,
|
||||||
respLine: respLine,
|
respLine: respLine,
|
||||||
toState: toState
|
toState: toState,
|
||||||
|
setAuxData: Invalid
|
||||||
};
|
};
|
||||||
enq2Mat_enq <= Valid (e2m);
|
enq2Mat_enq <= Valid (e2m);
|
||||||
endmethod
|
endmethod
|
||||||
@@ -586,7 +619,7 @@ module mkCCPipeSingleCycle#(
|
|||||||
|
|
||||||
method Bool notEmpty = deq_guard;
|
method Bool notEmpty = deq_guard;
|
||||||
|
|
||||||
method Action deqWrite(Maybe#(pipeCmdT) newCmd, ramDataT wrRam, Bool updateRep) if(deq_guard);
|
method Action deqWrite(Maybe#(pipeCmdT) newCmd, ramDataT wrRam, setAuxT setAuxData, Bool updateRep) if(deq_guard);
|
||||||
match2OutT m2o = fromMaybe(?, mat2Out_out);
|
match2OutT m2o = fromMaybe(?, mat2Out_out);
|
||||||
wayT way = m2o.way;
|
wayT way = m2o.way;
|
||||||
indexT index = getIndex(m2o.cmd);
|
indexT index = getIndex(m2o.cmd);
|
||||||
@@ -599,6 +632,7 @@ module mkCCPipeSingleCycle#(
|
|||||||
infoRam[way].wrReq(index, wrRam.info);
|
infoRam[way].wrReq(index, wrRam.info);
|
||||||
repRam.wrReq(index, repInfo);
|
repRam.wrReq(index, repInfo);
|
||||||
dataRam[way].wrReq(index, wrRam.line);
|
dataRam[way].wrReq(index, wrRam.line);
|
||||||
|
setAuxDataRam.wrReq(index, setAuxData);
|
||||||
// change pipeline reg
|
// change pipeline reg
|
||||||
if(newCmd matches tagged Valid .cmd) begin
|
if(newCmd matches tagged Valid .cmd) begin
|
||||||
// update pipeline reg
|
// update pipeline reg
|
||||||
@@ -608,7 +642,8 @@ module mkCCPipeSingleCycle#(
|
|||||||
pRqMiss: False, // reset (not valid for swapped in pRq)
|
pRqMiss: False, // reset (not valid for swapped in pRq)
|
||||||
info: wrRam.info,
|
info: wrRam.info,
|
||||||
repInfo: repInfo,
|
repInfo: repInfo,
|
||||||
line: Valid(wrRam.line)
|
line: Valid(wrRam.line),
|
||||||
|
setAuxData: setAuxData
|
||||||
});
|
});
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
|||||||
@@ -124,8 +124,10 @@ module mkIBank#(
|
|||||||
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
||||||
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
||||||
Alias#(cacheOwnerT, Maybe#(cRqIdxT)), // owner cannot be pRq
|
Alias#(cacheOwnerT, Maybe#(cRqIdxT)), // owner cannot be pRq
|
||||||
|
Alias#(cacheOtherT, void), // owner cannot be pRq
|
||||||
|
Alias#(cacheSetAuxT, Maybe#(cRqIdxT)),
|
||||||
Alias#(cacheInfoT, CacheInfo#(tagT, Msi, void, cacheOwnerT, void)),
|
Alias#(cacheInfoT, CacheInfo#(tagT, Msi, void, cacheOwnerT, void)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, void, cacheOwnerT, void, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, void, cacheOwnerT, cacheOtherT, Line)),
|
||||||
Alias#(procRqT, ProcRqToI),
|
Alias#(procRqT, ProcRqToI),
|
||||||
Alias#(cRqToPT, CRqMsg#(wayT, void)),
|
Alias#(cRqToPT, CRqMsg#(wayT, void)),
|
||||||
Alias#(cRsToPT, CRsMsg#(void)),
|
Alias#(cRsToPT, CRsMsg#(void)),
|
||||||
@@ -134,7 +136,7 @@ module mkIBank#(
|
|||||||
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
||||||
Alias#(cRqSlotT, ICRqSlot#(wayT, tagT)), // cRq MSHR slot
|
Alias#(cRqSlotT, ICRqSlot#(wayT, tagT)), // cRq MSHR slot
|
||||||
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, l1CmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, cacheOtherT, RandRepInfo, Line, cacheSetAuxT, l1CmdT)),
|
||||||
Mul#(2, supSz, supSzX2),
|
Mul#(2, supSz, supSzX2),
|
||||||
Alias#(resultT, Vector#(supSzX2, Maybe#(Instruction16))),
|
Alias#(resultT, Vector#(supSzX2, Maybe#(Instruction16))),
|
||||||
// requirements
|
// requirements
|
||||||
@@ -531,7 +533,7 @@ module mkIBank#(
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, True); // hit, so update rep info
|
}, Invalid, True); // hit, so update rep info
|
||||||
if (!cRqIsPrefetch[n]) begin
|
if (!cRqIsPrefetch[n]) begin
|
||||||
prefetcher.reportAccess(req.addr, HIT);
|
prefetcher.reportAccess(req.addr, HIT);
|
||||||
llcPrefetcher.reportAccess(req.addr, HIT);
|
llcPrefetcher.reportAccess(req.addr, HIT);
|
||||||
@@ -594,7 +596,7 @@ module mkIBank#(
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, False);
|
}, Invalid, False);
|
||||||
if (!cRqIsPrefetch[n]) begin
|
if (!cRqIsPrefetch[n]) begin
|
||||||
prefetcher.reportAccess(procRq.addr, MISS);
|
prefetcher.reportAccess(procRq.addr, MISS);
|
||||||
llcPrefetcher.reportAccess(procRq.addr, MISS);
|
llcPrefetcher.reportAccess(procRq.addr, MISS);
|
||||||
@@ -616,7 +618,7 @@ module mkIBank#(
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ? // data is no longer used
|
line: ? // data is no longer used
|
||||||
}, False);
|
}, Invalid, False);
|
||||||
doAssert(ram.info.cs == S, "I$ replacement only replace S line");
|
doAssert(ram.info.cs == S, "I$ replacement only replace S line");
|
||||||
// update MSHR to save replaced tag
|
// update MSHR to save replaced tag
|
||||||
// although we send req to parent later (when resp to parent is sent)
|
// although we send req to parent later (when resp to parent is sent)
|
||||||
@@ -639,7 +641,7 @@ module mkIBank#(
|
|||||||
function Action cRqSetDepNoCacheChange;
|
function Action cRqSetDepNoCacheChange;
|
||||||
action
|
action
|
||||||
cRqMshr.pipelineResp.setStateSlot(n, Depend, defaultValue);
|
cRqMshr.pipelineResp.setStateSlot(n, Depend, defaultValue);
|
||||||
pipeline.deqWrite(Invalid, pipeOut.ram, False);
|
pipeline.deqWrite(Invalid, pipeOut.ram, Invalid, False);
|
||||||
endaction
|
endaction
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -740,7 +742,7 @@ module mkIBank#(
|
|||||||
$display("%t I %m pipelineResp: pRq: drop", $time);
|
$display("%t I %m pipelineResp: pRq: drop", $time);
|
||||||
// pRq can be directly dropped, no successor (since just go through pipeline)
|
// pRq can be directly dropped, no successor (since just go through pipeline)
|
||||||
pRqMshr.pipelineResp.releaseEntry(n);
|
pRqMshr.pipelineResp.releaseEntry(n);
|
||||||
pipeline.deqWrite(Invalid, pipeOut.ram, False);
|
pipeline.deqWrite(Invalid, pipeOut.ram, Invalid, False);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@@ -763,7 +765,7 @@ module mkIBank#(
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ? // line is not useful
|
line: ? // line is not useful
|
||||||
}, False);
|
}, Invalid, False);
|
||||||
// pRq is done
|
// pRq is done
|
||||||
pRqMshr.pipelineResp.setDone(n);
|
pRqMshr.pipelineResp.setDone(n);
|
||||||
// send resp to parent
|
// send resp to parent
|
||||||
@@ -824,7 +826,7 @@ module mkIBank#(
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ?
|
line: ?
|
||||||
}, False);
|
}, Invalid, False);
|
||||||
|
|
||||||
// check if we have finished all flush
|
// check if we have finished all flush
|
||||||
if (flush.index == maxBound &&
|
if (flush.index == maxBound &&
|
||||||
|
|||||||
@@ -120,11 +120,12 @@ typedef struct {
|
|||||||
cRqIdxT n; // AMO req MSHR idx
|
cRqIdxT n; // AMO req MSHR idx
|
||||||
cRqT req; // AMO req
|
cRqT req; // AMO req
|
||||||
Maybe#(cRqIdxT) succ; // same-addr-successor of AMO req
|
Maybe#(cRqIdxT) succ; // same-addr-successor of AMO req
|
||||||
|
Maybe#(cRqIdxT) nextInQueue;
|
||||||
} AmoHitInfo#(type cRqIdxT, type cRqT) deriving(Bits, Eq, FShow);
|
} AmoHitInfo#(type cRqIdxT, type cRqT) deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
module mkL1Bank#(
|
module mkL1Bank#(
|
||||||
Bit#(lgBankNum) bankId,
|
Bit#(lgBankNum) bankId,
|
||||||
module#(L1CRqMshr#(cRqNum, wayT, tagT, procRqT)) mkL1CRqMshrLocal,
|
module#(L1CRqMshr#(cRqNum, indexT, wayT, tagT, procRqT)) mkL1CRqMshrLocal,
|
||||||
module#(L1PRqMshr#(pRqNum)) mkL1PRqMshrLocal,
|
module#(L1PRqMshr#(pRqNum)) mkL1PRqMshrLocal,
|
||||||
module#(L1Pipe#(lgBankNum, wayNum, indexT, tagT, cRqIdxT, pRqIdxT)) mkL1Pipeline,
|
module#(L1Pipe#(lgBankNum, wayNum, indexT, tagT, cRqIdxT, pRqIdxT)) mkL1Pipeline,
|
||||||
L1ProcResp#(procRqIdT) procResp
|
L1ProcResp#(procRqIdT) procResp
|
||||||
@@ -137,6 +138,7 @@ module mkL1Bank#(
|
|||||||
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
||||||
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
||||||
Alias#(cacheOwnerT, Maybe#(cRqIdxT)), // actually owner cannot be pRq
|
Alias#(cacheOwnerT, Maybe#(cRqIdxT)), // actually owner cannot be pRq
|
||||||
|
Alias#(cacheSetAuxT, Maybe#(cRqIdxT)),
|
||||||
Alias#(cacheInfoT, CacheInfo#(tagT, Msi, void, cacheOwnerT, void)),
|
Alias#(cacheInfoT, CacheInfo#(tagT, Msi, void, cacheOwnerT, void)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, void, cacheOwnerT, void, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, void, cacheOwnerT, void, Line)),
|
||||||
Alias#(procRqT, ProcRq#(procRqIdT)),
|
Alias#(procRqT, ProcRq#(procRqIdT)),
|
||||||
@@ -147,7 +149,7 @@ module mkL1Bank#(
|
|||||||
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
||||||
Alias#(cRqSlotT, L1CRqSlot#(wayT, tagT)), // cRq MSHR slot
|
Alias#(cRqSlotT, L1CRqSlot#(wayT, tagT)), // cRq MSHR slot
|
||||||
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, l1CmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, cacheSetAuxT, l1CmdT)),
|
||||||
// requirements
|
// requirements
|
||||||
Bits#(procRqIdT, _procRqIdT),
|
Bits#(procRqIdT, _procRqIdT),
|
||||||
FShow#(procRqIdT),
|
FShow#(procRqIdT),
|
||||||
@@ -160,7 +162,7 @@ module mkL1Bank#(
|
|||||||
|
|
||||||
Bool verbose = False;
|
Bool verbose = False;
|
||||||
|
|
||||||
L1CRqMshr#(cRqNum, wayT, tagT, procRqT) cRqMshr <- mkL1CRqMshrLocal;
|
L1CRqMshr#(cRqNum, indexT, wayT, tagT, procRqT) cRqMshr <- mkL1CRqMshrLocal;
|
||||||
|
|
||||||
L1PRqMshr#(pRqNum) pRqMshr <- mkL1PRqMshrLocal;
|
L1PRqMshr#(pRqNum) pRqMshr <- mkL1PRqMshrLocal;
|
||||||
|
|
||||||
@@ -559,6 +561,8 @@ endfunction
|
|||||||
L1CRqState pipeOutCState = cRqMshr.pipelineResp.getState(pipeOutCRqIdx);
|
L1CRqState pipeOutCState = cRqMshr.pipelineResp.getState(pipeOutCRqIdx);
|
||||||
cRqSlotT pipeOutCSlot = cRqMshr.pipelineResp.getSlot(pipeOutCRqIdx);
|
cRqSlotT pipeOutCSlot = cRqMshr.pipelineResp.getSlot(pipeOutCRqIdx);
|
||||||
Maybe#(cRqIdxT) pipeOutSucc = cRqMshr.pipelineResp.getSucc(pipeOutCRqIdx);
|
Maybe#(cRqIdxT) pipeOutSucc = cRqMshr.pipelineResp.getSucc(pipeOutCRqIdx);
|
||||||
|
Maybe#(cRqIdxT) pipeOutNextInQueue = pipeOut.setAuxData;
|
||||||
|
Maybe#(cRqIdxT) pipeOutSecondInQueue = isValid(pipeOutNextInQueue) ? cRqMshr.pipelineResp.getSucc2(fromMaybe(?, pipeOutNextInQueue)) : Invalid;
|
||||||
|
|
||||||
// function to process cRq hit (MSHR slot may have garbage)
|
// function to process cRq hit (MSHR slot may have garbage)
|
||||||
function Action cRqHit(cRqIdxT n, procRqT req);
|
function Action cRqHit(cRqIdxT n, procRqT req);
|
||||||
@@ -639,7 +643,16 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: newLine // write new data into cache
|
line: newLine // write new data into cache
|
||||||
}, True); // hit, so update rep info
|
}, isValid(succ) ? pipeOutNextInQueue : pipeOutSecondInQueue, True); // hit, so update rep info
|
||||||
|
if (!isValid(succ) &&& pipeOutNextInQueue matches tagged Valid .nextInQueue) begin
|
||||||
|
$display("%t L1D dequeuing queued req: mshr: %d, queueSucc: ",
|
||||||
|
$time,
|
||||||
|
nextInQueue,
|
||||||
|
fshow(pipeOutSecondInQueue)
|
||||||
|
);
|
||||||
|
cRqRetryIndexQ.enq(nextInQueue);
|
||||||
|
cRqMshr.manageQueue.resetEntry(nextInQueue);
|
||||||
|
end
|
||||||
if (!cRqIsPrefetch[n]) begin
|
if (!cRqIsPrefetch[n]) begin
|
||||||
prefetcher.reportAccess(req.addr, req.pcHash, HIT);
|
prefetcher.reportAccess(req.addr, req.pcHash, HIT);
|
||||||
llcPrefetcher.reportAccess(req.addr, req.pcHash, HIT);
|
llcPrefetcher.reportAccess(req.addr, req.pcHash, HIT);
|
||||||
@@ -656,7 +669,8 @@ endfunction
|
|||||||
processAmo <= Valid (AmoHitInfo {
|
processAmo <= Valid (AmoHitInfo {
|
||||||
n: n,
|
n: n,
|
||||||
req: req,
|
req: req,
|
||||||
succ: succ
|
succ: succ,
|
||||||
|
nextInQueue: pipeOutNextInQueue
|
||||||
});
|
});
|
||||||
if (verbose)
|
if (verbose)
|
||||||
$display("%t L1 %m pipelineResp: Hit func: AMO process in next cycle", $time);
|
$display("%t L1 %m pipelineResp: Hit func: AMO process in next cycle", $time);
|
||||||
@@ -676,7 +690,7 @@ endfunction
|
|||||||
MemTaggedData current = getTaggedDataAt(curLine, dataSel);
|
MemTaggedData current = getTaggedDataAt(curLine, dataSel);
|
||||||
Vector#(2, Bit#(64)) dwordData = current.data;
|
Vector#(2, Bit#(64)) dwordData = current.data;
|
||||||
Vector#(4, Bit#(32)) wordData = unpack(pack(current.data));
|
Vector#(4, Bit#(32)) wordData = unpack(pack(current.data));
|
||||||
Bit#(1) dwordIdx = req.addr[3];
|
Bit#(1) dwordIdx = req.addr[3];
|
||||||
Bit#(2) wordIdx = req.addr[3:2];
|
Bit#(2) wordIdx = req.addr[3:2];
|
||||||
// resp processor
|
// resp processor
|
||||||
MemTaggedData resp = case (req.amoInst.width)
|
MemTaggedData resp = case (req.amoInst.width)
|
||||||
@@ -704,7 +718,7 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: newLine // write new data into cache
|
line: newLine // write new data into cache
|
||||||
}, True); // hit, so update rep info
|
}, amoHit.nextInQueue, True); // hit, so update rep info
|
||||||
doAssert(req.toState == M, "AMO must req for M");
|
doAssert(req.toState == M, "AMO must req for M");
|
||||||
if (verbose)
|
if (verbose)
|
||||||
$display("%t L1 %m processAmo: update ram: ", $time,
|
$display("%t L1 %m processAmo: update ram: ", $time,
|
||||||
@@ -726,7 +740,8 @@ endfunction
|
|||||||
$display("%t L1 %m pipelineResp: cRq: ", $time, fshow(n), " ; ", fshow(procRq));
|
$display("%t L1 %m pipelineResp: cRq: ", $time, fshow(n), " ; ", fshow(procRq));
|
||||||
|
|
||||||
// find end of dependency chain
|
// find end of dependency chain
|
||||||
Maybe#(cRqIdxT) cRqEOC = cRqMshr.pipelineResp.searchEndOfChain(procRq.addr);
|
Maybe#(cRqIdxT) cRqDependEOC = cRqMshr.pipelineResp.searchDependEndOfChain(procRq.addr);
|
||||||
|
Maybe#(cRqIdxT) cRqQueuedEOC = cRqMshr.pipelineResp.searchQueuedEndOfChain(procRq.addr);
|
||||||
|
|
||||||
function Action cRqScEarlyFail(Bool resetOwner);
|
function Action cRqScEarlyFail(Bool resetOwner);
|
||||||
action
|
action
|
||||||
@@ -746,7 +761,7 @@ endfunction
|
|||||||
other: ram.info.other
|
other: ram.info.other
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, False);
|
}, pipeOutNextInQueue, False);
|
||||||
// retry successor
|
// retry successor
|
||||||
Maybe#(cRqIdxT) succ = pipeOutSucc;
|
Maybe#(cRqIdxT) succ = pipeOutSucc;
|
||||||
if(succ matches tagged Valid .s) begin
|
if(succ matches tagged Valid .s) begin
|
||||||
@@ -793,7 +808,7 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, False);
|
}, pipeOutNextInQueue, False);
|
||||||
if (!cRqIsPrefetch[n]) begin
|
if (!cRqIsPrefetch[n]) begin
|
||||||
prefetcher.reportAccess(procRq.addr, procRq.pcHash, MISS);
|
prefetcher.reportAccess(procRq.addr, procRq.pcHash, MISS);
|
||||||
llcPrefetcher.reportAccess(procRq.addr, procRq.pcHash, MISS);
|
llcPrefetcher.reportAccess(procRq.addr, procRq.pcHash, MISS);
|
||||||
@@ -814,7 +829,7 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ? // data is no longer used
|
line: ? // data is no longer used
|
||||||
}, False);
|
}, pipeOutNextInQueue, False);
|
||||||
// update MSHR: may save replaced line data
|
// update MSHR: may save replaced line data
|
||||||
cRqMshr.pipelineResp.setStateSlot(n, WaitNewTag, L1CRqSlot {
|
cRqMshr.pipelineResp.setStateSlot(n, WaitNewTag, L1CRqSlot {
|
||||||
way: pipeOut.way, // use way from pipeline
|
way: pipeOut.way, // use way from pipeline
|
||||||
@@ -841,7 +856,22 @@ endfunction
|
|||||||
function Action cRqSetDepNoCacheChange;
|
function Action cRqSetDepNoCacheChange;
|
||||||
action
|
action
|
||||||
cRqMshr.pipelineResp.setStateSlot(n, Depend, defaultValue);
|
cRqMshr.pipelineResp.setStateSlot(n, Depend, defaultValue);
|
||||||
pipeline.deqWrite(Invalid, pipeOut.ram, False);
|
pipeline.deqWrite(Invalid, pipeOut.ram, pipeOutNextInQueue, False);
|
||||||
|
endaction
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function Action cRqQueue;
|
||||||
|
action
|
||||||
|
cRqMshr.pipelineResp.setStateSlot(n, Queued, defaultValue);
|
||||||
|
pipeline.deqWrite(Invalid, pipeOut.ram, Valid(fromMaybe(n, pipeOutNextInQueue)), False);
|
||||||
|
endaction
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function Action cRqDrop;
|
||||||
|
action
|
||||||
|
cRqMshr.pipelineResp.releaseEntry(n);
|
||||||
|
crqMshrDeqs <= crqMshrDeqs + 1;
|
||||||
|
pipeline.deqWrite(Invalid, pipeOut.ram, pipeOutNextInQueue, False);
|
||||||
endaction
|
endaction
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -857,18 +887,36 @@ endfunction
|
|||||||
Bool cs_valid = ram.info.cs > I;
|
Bool cs_valid = ram.info.cs > I;
|
||||||
if(ram.info.owner matches tagged Valid .cOwner) begin
|
if(ram.info.owner matches tagged Valid .cOwner) begin
|
||||||
if(cOwner != n) begin
|
if(cOwner != n) begin
|
||||||
// owner is another cRq, so must just go through tag match
|
|
||||||
// tag match must be hit (because replacement algo won't give a way with owner)
|
|
||||||
doAssert(pipeOutCState == Init, "must first time go through tag match");
|
doAssert(pipeOutCState == Init, "must first time go through tag match");
|
||||||
doAssert(cs_valid && tag_match, "cRq should hit in tag match");
|
// If the tags match then we want to add to a dependency chain
|
||||||
// should be added to a cRq in dependency chain & deq from pipeline
|
if (tag_match) begin
|
||||||
doAssert(isValid(cRqEOC), ("cRq hit on another cRq, cRqEOC must be true"));
|
// should be added to a cRq in dependency chain & deq from pipeline
|
||||||
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqEOC), Valid (n));
|
doAssert(isValid(cRqDependEOC), ("cRq hit on another cRq, cRqDependEOC must be true"));
|
||||||
cRqSetDepNoCacheChange;
|
// If this is a prefetch, we can drop the prefetch here (prefetch was probably late)
|
||||||
if (verbose)
|
if (cRqIsPrefetch[n]) begin
|
||||||
$display("%t L1 %m pipelineResp: cRq: own by other cRq ", $time,
|
cRqDrop;
|
||||||
fshow(cOwner), ", depend on cRq ", fshow(cRqEOC)
|
end else begin
|
||||||
);
|
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqDependEOC), Valid (n));
|
||||||
|
cRqSetDepNoCacheChange;
|
||||||
|
end
|
||||||
|
if (verbose)
|
||||||
|
$display("%t L1 %m pipelineResp: cRq: own by other cRq ", $time,
|
||||||
|
fshow(cOwner), ", depend on cRq ", fshow(cRqDependEOC)
|
||||||
|
);
|
||||||
|
end
|
||||||
|
// If the tags don't match then we want to queue the cRq
|
||||||
|
else begin
|
||||||
|
// if there was an option to add a dependency, L1Pipe should have found it
|
||||||
|
doAssert(!isValid(cRqDependEOC), ("end of chain is valid but the chosen way did not match tags"));
|
||||||
|
if (cRqIsPrefetch[n]) begin
|
||||||
|
cRqDrop;
|
||||||
|
end else begin
|
||||||
|
if (cRqQueuedEOC matches tagged Valid .eoc) begin
|
||||||
|
cRqMshr.pipelineResp.setSucc(eoc, Valid (n));
|
||||||
|
end
|
||||||
|
cRqQueue;
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// owner is myself, so must be swapped in
|
// owner is myself, so must be swapped in
|
||||||
@@ -907,47 +955,38 @@ endfunction
|
|||||||
// 2. cRq addr-depends on an Sc which fails early, just got waken up
|
// 2. cRq addr-depends on an Sc which fails early, just got waken up
|
||||||
L1CRqState cState = pipeOutCState;
|
L1CRqState cState = pipeOutCState;
|
||||||
|
|
||||||
// check for cRqEOC to append to dependency chain
|
// There should be no dependency
|
||||||
// Only append to dep-chain if is in Init state
|
doAssert(!isValid(cRqDependEOC), "end of chain is valid but the chosen way is not owned");
|
||||||
if(cRqEOC matches tagged Valid .k &&& cState == Init) begin
|
|
||||||
if (verbose)
|
// Check hit or miss, replacment may be needed
|
||||||
$display("%t L1 %m pipelineResp: cRq: no owner, depend on cRq, ", $time,
|
if(tag_match && enough_cs_to_hit) begin
|
||||||
fshow(cState), " ; ", fshow(cRqEOC)
|
// Hit
|
||||||
|
doAssert(cs_valid, "hit, so cs must > I");
|
||||||
|
if (verbose)
|
||||||
|
$display("%t L1 %m pipelineResp: cRq: no owner, hit", $time);
|
||||||
|
cRqHit(n, procRq, False);
|
||||||
|
end
|
||||||
|
else if(scFail) begin
|
||||||
|
// Sc already fails, so we don't need to req parent. Since
|
||||||
|
// there is no owner of the line, we can reset owner to
|
||||||
|
// Invalid.
|
||||||
|
if (verbose)
|
||||||
|
$display("%t L1 %m pipelineResp: cRq: no owner, Sc early fails, ",
|
||||||
|
$time, fshow(linkAddr)
|
||||||
);
|
);
|
||||||
cRqMshr.pipelineResp.setSucc(k, Valid (n));
|
cRqScEarlyFail(True);
|
||||||
cRqSetDepNoCacheChange;
|
end
|
||||||
|
else if(cs_valid && !tag_match) begin
|
||||||
|
// Req parent, need replacement
|
||||||
|
if (verbose)
|
||||||
|
$display("%t L1 %m pipelineResp: cRq: no owner, replace", $time);
|
||||||
|
cRqReplacement;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// Check hit or miss, replacment may be needed
|
if (verbose)
|
||||||
if(tag_match && enough_cs_to_hit) begin
|
$display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time);
|
||||||
// Hit
|
// Req parent, no replacement needed
|
||||||
doAssert(cs_valid, "hit, so cs must > I");
|
cRqMissNoReplacement;
|
||||||
if (verbose)
|
|
||||||
$display("%t L1 %m pipelineResp: cRq: no owner, hit", $time);
|
|
||||||
cRqHit(n, procRq);
|
|
||||||
end
|
|
||||||
else if(scFail) begin
|
|
||||||
// Sc already fails, so we don't need to req parent. Since
|
|
||||||
// there is no owner of the line, we can reset owner to
|
|
||||||
// Invalid.
|
|
||||||
if (verbose)
|
|
||||||
$display("%t L1 %m pipelineResp: cRq: no owner, Sc early fails, ",
|
|
||||||
$time, fshow(linkAddr)
|
|
||||||
);
|
|
||||||
cRqScEarlyFail(True);
|
|
||||||
end
|
|
||||||
else if(cs_valid && !tag_match) begin
|
|
||||||
// Req parent, need replacement
|
|
||||||
if (verbose)
|
|
||||||
$display("%t L1 %m pipelineResp: cRq: no owner, replace", $time);
|
|
||||||
cRqReplacement;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if (verbose)
|
|
||||||
$display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time);
|
|
||||||
// Req parent, no replacement needed
|
|
||||||
cRqMissNoReplacement;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endrule
|
endrule
|
||||||
@@ -989,7 +1028,7 @@ endfunction
|
|||||||
// pRq can be directly dropped
|
// pRq can be directly dropped
|
||||||
// must go through tag match, no successor
|
// must go through tag match, no successor
|
||||||
pRqMshr.pipelineResp.releaseEntry(n);
|
pRqMshr.pipelineResp.releaseEntry(n);
|
||||||
pipeline.deqWrite(Invalid, pipeOut.ram, False);
|
pipeline.deqWrite(Invalid, pipeOut.ram, pipeOutNextInQueue, False);
|
||||||
// sanity check (ram.info.tag != getTag(pRq.addr) is useless)
|
// sanity check (ram.info.tag != getTag(pRq.addr) is useless)
|
||||||
if(!pipeOut.pRqMiss) begin
|
if(!pipeOut.pRqMiss) begin
|
||||||
doAssert(ram.info.cs == S && pRq.toState == S && ram.info.tag == getTag(pRq.addr),
|
doAssert(ram.info.cs == S && pRq.toState == S && ram.info.tag == getTag(pRq.addr),
|
||||||
@@ -1023,7 +1062,7 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, False);
|
}, pipeOutNextInQueue, False);
|
||||||
rsToPIndexQ.enq(PRq (n));
|
rsToPIndexQ.enq(PRq (n));
|
||||||
// update cRq bookkeeping
|
// update cRq bookkeeping
|
||||||
cRqMshr.pipelineResp.setStateSlot(cOwner, WaitSt, L1CRqSlot {
|
cRqMshr.pipelineResp.setStateSlot(cOwner, WaitSt, L1CRqSlot {
|
||||||
@@ -1054,7 +1093,16 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ram.line
|
line: ram.line
|
||||||
}, False);
|
}, pipeOutSecondInQueue, False);
|
||||||
|
if (pipeOutNextInQueue matches tagged Valid .nextInQueue) begin
|
||||||
|
$display("%t L1D dequeuing queued req: mshr: %d, queueSucc: ",
|
||||||
|
$time,
|
||||||
|
nextInQueue,
|
||||||
|
fshow(pipeOutSecondInQueue)
|
||||||
|
);
|
||||||
|
cRqRetryIndexQ.enq(nextInQueue);
|
||||||
|
cRqMshr.manageQueue.resetEntry(nextInQueue);
|
||||||
|
end
|
||||||
rsToPIndexQ.enq(PRq (n));
|
rsToPIndexQ.enq(PRq (n));
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1076,6 +1124,7 @@ endfunction
|
|||||||
|
|
||||||
// During flush, cRq MSHR is empty, so cache line cannot have owner
|
// During flush, cRq MSHR is empty, so cache line cannot have owner
|
||||||
doAssert(ram.info.owner == Invalid, "flushing line cannot have owner");
|
doAssert(ram.info.owner == Invalid, "flushing line cannot have owner");
|
||||||
|
doAssert(pipeOutNextInQueue == Invalid, "flushing line cannot have queued requests");
|
||||||
|
|
||||||
// flush always goes through cache pipeline, and is directly handled
|
// flush always goes through cache pipeline, and is directly handled
|
||||||
// here: either dropped or Done
|
// here: either dropped or Done
|
||||||
@@ -1107,7 +1156,7 @@ endfunction
|
|||||||
other: ?
|
other: ?
|
||||||
},
|
},
|
||||||
line: ?
|
line: ?
|
||||||
}, False);
|
}, Invalid, False);
|
||||||
|
|
||||||
// always reset link addr
|
// always reset link addr
|
||||||
linkAddr <= Invalid;
|
linkAddr <= Invalid;
|
||||||
@@ -1230,8 +1279,9 @@ endmodule
|
|||||||
// -- cRqMshr.releaseEntry
|
// -- cRqMshr.releaseEntry
|
||||||
// -- read cRq MSHR req/state/slot/data currently processed
|
// -- read cRq MSHR req/state/slot/data currently processed
|
||||||
// -- write cRq MSHR state/slot/data currently processed
|
// -- write cRq MSHR state/slot/data currently processed
|
||||||
|
// -- write cRq MSHR state/succ of some existing cRq MSHR entry (in Queued)
|
||||||
// -- write succ of some existing cRq MSHR entry (in WaitNewTag or WaitSt)
|
// -- write succ of some existing cRq MSHR entry (in WaitNewTag or WaitSt)
|
||||||
// -- read all state/req/succ in cRq MSHR entry (searchEOC)
|
// -- read all state/req/succ in cRq MSHR entry (searchDependEOC and searchQueueEOC)
|
||||||
// -- not affected by write in cRqTransfer
|
// -- not affected by write in cRqTransfer
|
||||||
// -- not affected by write in sendRsToP_cRq (state change is just WaitNewTag->WaitSt)
|
// -- not affected by write in sendRsToP_cRq (state change is just WaitNewTag->WaitSt)
|
||||||
|
|
||||||
@@ -1260,13 +1310,16 @@ endmodule
|
|||||||
|
|
||||||
// sendRqToP conflict free with pipelineResp_xxx
|
// sendRqToP conflict free with pipelineResp_xxx
|
||||||
|
|
||||||
|
// pipelineResp_cRq conflicts with itself, potentially writing state/succ of multiple entries
|
||||||
|
|
||||||
// ---- conclusion ----
|
// ---- conclusion ----
|
||||||
|
|
||||||
// we have 4 ports from cRq MSHR
|
// we have 5 ports from cRq MSHR
|
||||||
// 1. cRqTransfer
|
// 1. cRqTransfer
|
||||||
// 2. sendRsToP_cRq
|
// 2. sendRsToP_cRq
|
||||||
// 3. sendRqToP
|
// 3. sendRqToP
|
||||||
// 4. pipelineResp
|
// 4. pipelineResp
|
||||||
|
// 5. manageQueue
|
||||||
|
|
||||||
// we have 3 ports from pRq MSHR
|
// we have 3 ports from pRq MSHR
|
||||||
// 1. pRqTransfer
|
// 1. pRqTransfer
|
||||||
@@ -1280,7 +1333,8 @@ endmodule
|
|||||||
// safe version: use EHR ports
|
// safe version: use EHR ports
|
||||||
// sendRsToP_cRq/sendRsToP_pRq: port 0
|
// sendRsToP_cRq/sendRsToP_pRq: port 0
|
||||||
// pipelineResp: port 1
|
// pipelineResp: port 1
|
||||||
// cRqTransfer/sendRqToP/pRqTransfer: port 2
|
// manageQueue: port 2
|
||||||
|
// cRqTransfer/sendRqToP/pRqTransfer: port 3
|
||||||
|
|
||||||
// We put cRqTransfer at last because it is ordered after the issue method of
|
// We put cRqTransfer at last because it is ordered after the issue method of
|
||||||
// LSQ outside cache, while pipelineResp and sendRsToP will call other methods
|
// LSQ outside cache, while pipelineResp and sendRsToP will call other methods
|
||||||
@@ -1290,7 +1344,7 @@ endmodule
|
|||||||
|
|
||||||
// group banks into cache
|
// group banks into cache
|
||||||
module mkL1Cache#(
|
module mkL1Cache#(
|
||||||
module#(L1CRqMshr#(cRqNum, wayT, tagT, procRqT)) mkL1CRqMshrLocal,
|
module#(L1CRqMshr#(cRqNum, indexT, wayT, tagT, procRqT)) mkL1CRqMshrLocal,
|
||||||
module#(L1PRqMshr#(pRqNum)) mkL1PRqMshrLocal,
|
module#(L1PRqMshr#(pRqNum)) mkL1PRqMshrLocal,
|
||||||
module#(L1Pipe#(lgBankNum, wayNum, indexT, tagT, cRqIdxT, pRqIdxT)) mkL1Pipeline,
|
module#(L1Pipe#(lgBankNum, wayNum, indexT, tagT, cRqIdxT, pRqIdxT)) mkL1Pipeline,
|
||||||
L1ProcResp#(procRqIdT) procResp
|
L1ProcResp#(procRqIdT) procResp
|
||||||
@@ -1306,12 +1360,14 @@ module mkL1Cache#(
|
|||||||
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
Alias#(cRqIdxT, Bit#(TLog#(cRqNum))),
|
||||||
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
Alias#(pRqIdxT, Bit#(TLog#(pRqNum))),
|
||||||
Alias#(cacheOwnerT, Maybe#(cRqIdxT)),
|
Alias#(cacheOwnerT, Maybe#(cRqIdxT)),
|
||||||
|
Alias#(cacheOtherT, void),
|
||||||
|
Alias#(cacheSetAuxT, Maybe#(cRqIdxT)),
|
||||||
Alias#(procRqT, ProcRq#(procRqIdT)),
|
Alias#(procRqT, ProcRq#(procRqIdT)),
|
||||||
Alias#(cRqToPT, CRqMsg#(wayT, void)),
|
Alias#(cRqToPT, CRqMsg#(wayT, void)),
|
||||||
Alias#(cRsToPT, CRsMsg#(void)),
|
Alias#(cRsToPT, CRsMsg#(void)),
|
||||||
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
Alias#(pRqRsFromPT, PRqRsMsg#(wayT, void)),
|
||||||
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, l1CmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, cacheSetAuxT, l1CmdT)),
|
||||||
// requirements
|
// requirements
|
||||||
Bits#(procRqIdT, _procRqIdT),
|
Bits#(procRqIdT, _procRqIdT),
|
||||||
FShow#(procRqIdT),
|
FShow#(procRqIdT),
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ typedef enum {
|
|||||||
WaitNewTag, // waiting replacement resp to send (but tag in RAM is already updated)
|
WaitNewTag, // waiting replacement resp to send (but tag in RAM is already updated)
|
||||||
WaitSt, // wait pRs/cRs to come
|
WaitSt, // wait pRs/cRs to come
|
||||||
Done, // resp is in index FIFO
|
Done, // resp is in index FIFO
|
||||||
Depend
|
Depend,
|
||||||
|
Queued // wait for a way to be free
|
||||||
} L1CRqState deriving(Bits, Eq, FShow);
|
} L1CRqState deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
// CRq info returned to outside
|
// CRq info returned to outside
|
||||||
@@ -129,6 +130,7 @@ endinterface
|
|||||||
// port for pipelineResp
|
// port for pipelineResp
|
||||||
interface L1CRqMshr_pipelineResp#(
|
interface L1CRqMshr_pipelineResp#(
|
||||||
numeric type cRqNum,
|
numeric type cRqNum,
|
||||||
|
type indexT,
|
||||||
type wayT,
|
type wayT,
|
||||||
type tagT,
|
type tagT,
|
||||||
type reqT
|
type reqT
|
||||||
@@ -149,16 +151,26 @@ interface L1CRqMshr_pipelineResp#(
|
|||||||
// cannot be used to release MSHR entry (use releaseSlot instead)
|
// cannot be used to release MSHR entry (use releaseSlot instead)
|
||||||
|
|
||||||
method Maybe#(Bit#(TLog#(cRqNum))) getSucc(Bit#(TLog#(cRqNum)) n);
|
method Maybe#(Bit#(TLog#(cRqNum))) getSucc(Bit#(TLog#(cRqNum)) n);
|
||||||
|
method Maybe#(Bit#(TLog#(cRqNum))) getSucc2(Bit#(TLog#(cRqNum)) n);
|
||||||
method Action setSucc(Bit#(TLog#(cRqNum)) n, Maybe#(Bit#(TLog#(cRqNum))) succ);
|
method Action setSucc(Bit#(TLog#(cRqNum)) n, Maybe#(Bit#(TLog#(cRqNum))) succ);
|
||||||
// index in setSucc is usually different from other getXXX methods
|
// index in setSucc is usually different from other getXXX methods
|
||||||
|
|
||||||
// find existing cRq which has gone through pipeline, but not in Done state, and has not successor
|
// find existing cRq which has gone through pipeline, but not in Done state, and has not successor
|
||||||
// i.e. search the end of dependency chain
|
// i.e. search the end of dependency chain
|
||||||
method Maybe#(Bit#(TLog#(cRqNum))) searchEndOfChain(Addr addr);
|
method Maybe#(Bit#(TLog#(cRqNum))) searchDependEndOfChain(Addr addr);
|
||||||
|
method Maybe#(Bit#(TLog#(cRqNum))) searchQueuedEndOfChain(Addr addr);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
// port to manage the state of queued instructions in parallel with pipelineResp
|
||||||
|
interface L1CRqMshr_manageQueue#(
|
||||||
|
numeric type cRqNum
|
||||||
|
);
|
||||||
|
method Action resetEntry(Bit#(TLog#(cRqNum)) n);
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
interface L1CRqMshr#(
|
interface L1CRqMshr#(
|
||||||
numeric type cRqNum,
|
numeric type cRqNum,
|
||||||
|
type indexT,
|
||||||
type wayT,
|
type wayT,
|
||||||
type tagT,
|
type tagT,
|
||||||
type reqT // child req type
|
type reqT // child req type
|
||||||
@@ -173,7 +185,10 @@ interface L1CRqMshr#(
|
|||||||
interface L1CRqMshr_sendRqToP#(cRqNum, wayT, tagT, reqT) sendRqToP;
|
interface L1CRqMshr_sendRqToP#(cRqNum, wayT, tagT, reqT) sendRqToP;
|
||||||
|
|
||||||
// port for pipelineResp
|
// port for pipelineResp
|
||||||
interface L1CRqMshr_pipelineResp#(cRqNum, wayT, tagT, reqT) pipelineResp;
|
interface L1CRqMshr_pipelineResp#(cRqNum, indexT, wayT, tagT, reqT) pipelineResp;
|
||||||
|
|
||||||
|
// port for manageQueue
|
||||||
|
interface L1CRqMshr_manageQueue#(cRqNum) manageQueue;
|
||||||
|
|
||||||
// port for security flush
|
// port for security flush
|
||||||
method Bool emptyForFlush;
|
method Bool emptyForFlush;
|
||||||
@@ -187,12 +202,14 @@ endinterface
|
|||||||
// safe version //
|
// safe version //
|
||||||
//////////////////
|
//////////////////
|
||||||
module mkL1CRqMshrSafe#(
|
module mkL1CRqMshrSafe#(
|
||||||
function Addr getAddrFromReq(reqT r)
|
function Addr getAddrFromReq(reqT r),
|
||||||
|
function indexT getIndexFromAddr(Addr addr)
|
||||||
)(
|
)(
|
||||||
L1CRqMshr#(cRqNum, wayT, tagT, reqT)
|
L1CRqMshr#(cRqNum, indexT, wayT, tagT, reqT)
|
||||||
) provisos (
|
) provisos (
|
||||||
Alias#(cRqIndexT, Bit#(TLog#(cRqNum))),
|
Alias#(cRqIndexT, Bit#(TLog#(cRqNum))),
|
||||||
Alias#(slotT, L1CRqSlot#(wayT, tagT)),
|
Alias#(slotT, L1CRqSlot#(wayT, tagT)),
|
||||||
|
Alias#(indexT, Bit#(_indexSz)),
|
||||||
Alias#(wayT, Bit#(_waySz)),
|
Alias#(wayT, Bit#(_waySz)),
|
||||||
Alias#(tagT, Bit#(_tagSz)),
|
Alias#(tagT, Bit#(_tagSz)),
|
||||||
Bits#(reqT, _reqSz)
|
Bits#(reqT, _reqSz)
|
||||||
@@ -205,20 +222,21 @@ module mkL1CRqMshrSafe#(
|
|||||||
Integer sendRqToP_port = 0; // sendRqToP is read only
|
Integer sendRqToP_port = 0; // sendRqToP is read only
|
||||||
Integer sendRsToP_cRq_port = 0;
|
Integer sendRsToP_cRq_port = 0;
|
||||||
Integer pipelineResp_port = 1;
|
Integer pipelineResp_port = 1;
|
||||||
Integer cRqTransfer_port = 2;
|
Integer manageQueue_port = 2;
|
||||||
|
Integer cRqTransfer_port = 3;
|
||||||
|
|
||||||
// MSHR entry state
|
// MSHR entry state
|
||||||
Vector#(cRqNum, Ehr#(3, L1CRqState)) stateVec <- replicateM(mkEhr(Empty));
|
Vector#(cRqNum, Ehr#(4, L1CRqState)) stateVec <- replicateM(mkEhr(Empty));
|
||||||
// cRq req contents
|
// cRq req contents
|
||||||
Vector#(cRqNum, Ehr#(3, reqT)) reqVec <- replicateM(mkEhr(?));
|
Vector#(cRqNum, Ehr#(4, reqT)) reqVec <- replicateM(mkEhr(?));
|
||||||
// cRq mshr slots
|
// cRq mshr slots
|
||||||
Vector#(cRqNum, Ehr#(3, slotT)) slotVec <- replicateM(mkEhr(defaultValue));
|
Vector#(cRqNum, Ehr#(4, slotT)) slotVec <- replicateM(mkEhr(defaultValue));
|
||||||
// data valid bit
|
// data valid bit
|
||||||
Vector#(cRqNum, Ehr#(3, Bool)) dataValidVec <- replicateM(mkEhr(False));
|
Vector#(cRqNum, Ehr#(4, Bool)) dataValidVec <- replicateM(mkEhr(False));
|
||||||
// data values
|
// data values
|
||||||
RegFile#(cRqIndexT, Line) dataFile <- mkRegFile(0, fromInteger(valueOf(cRqNum) - 1));
|
RegFile#(cRqIndexT, Line) dataFile <- mkRegFile(0, fromInteger(valueOf(cRqNum) - 1));
|
||||||
// successor valid bit
|
// successor valid bit
|
||||||
Vector#(cRqNum, Ehr#(3, Bool)) succValidVec <- replicateM(mkEhr(False));
|
Vector#(cRqNum, Ehr#(4, Bool)) succValidVec <- replicateM(mkEhr(False));
|
||||||
// successor MSHR index
|
// successor MSHR index
|
||||||
RegFile#(cRqIndexT, cRqIndexT) succFile <- mkRegFile(0, fromInteger(valueOf(cRqNum) - 1));
|
RegFile#(cRqIndexT, cRqIndexT) succFile <- mkRegFile(0, fromInteger(valueOf(cRqNum) - 1));
|
||||||
// empty entry FIFO
|
// empty entry FIFO
|
||||||
@@ -346,24 +364,47 @@ module mkL1CRqMshrSafe#(
|
|||||||
return succValidVec[n][pipelineResp_port] ? (Valid (succFile.sub(n))) : Invalid;
|
return succValidVec[n][pipelineResp_port] ? (Valid (succFile.sub(n))) : Invalid;
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
method Action setSucc(cRqIndexT n, Maybe#(cRqIndexT) succ);
|
method Maybe#(cRqIndexT) getSucc2(cRqIndexT n);
|
||||||
succValidVec[n][pipelineResp_port] <= isValid(succ);
|
return succValidVec[n][pipelineResp_port] ? (Valid (succFile.sub(n))) : Invalid;
|
||||||
succFile.upd(n, fromMaybe(?, succ));
|
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
method Maybe#(cRqIndexT) searchEndOfChain(Addr addr);
|
method Action setSucc(cRqIndexT n, Maybe#(cRqIndexT) succ);
|
||||||
|
succValidVec[n][pipelineResp_port] <= isValid(succ);
|
||||||
|
if (succ matches tagged Valid .s)
|
||||||
|
succFile.upd(n, s);
|
||||||
|
endmethod
|
||||||
|
|
||||||
|
method Maybe#(cRqIndexT) searchDependEndOfChain(Addr addr);
|
||||||
function Bool isEndOfChain(Integer i);
|
function Bool isEndOfChain(Integer i);
|
||||||
// check entry i is end of chain or not
|
// check entry i is end of chain or not
|
||||||
L1CRqState state = stateVec[i][pipelineResp_port];
|
L1CRqState state = stateVec[i][pipelineResp_port];
|
||||||
Bool notDone = state != Done;
|
Bool isDepend = state == WaitSt || state == WaitNewTag || state == Depend;
|
||||||
Bool processedOnce = state != Empty && state != Init;
|
|
||||||
Bool addrMatch = getLineAddr(getAddrFromReq(reqVec[i][pipelineResp_port])) == getLineAddr(addr);
|
Bool addrMatch = getLineAddr(getAddrFromReq(reqVec[i][pipelineResp_port])) == getLineAddr(addr);
|
||||||
Bool noSucc = !succValidVec[i][pipelineResp_port];
|
Bool noSucc = !succValidVec[i][pipelineResp_port];
|
||||||
return notDone && processedOnce && addrMatch && noSucc;
|
return isDepend && addrMatch && noSucc;
|
||||||
endfunction
|
endfunction
|
||||||
Vector#(cRqNum, Integer) idxVec = genVector;
|
Vector#(cRqNum, Integer) idxVec = genVector;
|
||||||
return searchIndex(isEndOfChain, idxVec);
|
return searchIndex(isEndOfChain, idxVec);
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
|
method Maybe#(Bit#(TLog#(cRqNum))) searchQueuedEndOfChain(Addr addr);
|
||||||
|
function Bool isEndOfChain(Integer i);
|
||||||
|
L1CRqState state = stateVec[i][pipelineResp_port];
|
||||||
|
Bool isQueued = state == Queued;
|
||||||
|
Bool indexMatch = getIndexFromAddr(getAddrFromReq(reqVec[i][pipelineResp_port])) == getIndexFromAddr(addr);
|
||||||
|
Bool noSucc = !succValidVec[i][pipelineResp_port];
|
||||||
|
return isQueued && indexMatch && noSucc;
|
||||||
|
endfunction
|
||||||
|
Vector#(cRqNum, Integer) idxVec = genVector;
|
||||||
|
return searchIndex(isEndOfChain, idxVec);
|
||||||
|
endmethod
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
interface L1CRqMshr_manageQueue manageQueue;
|
||||||
|
method Action resetEntry(Bit#(TLog#(cRqNum)) n);
|
||||||
|
stateVec[n][manageQueue_port] <= Init;
|
||||||
|
succValidVec[n][manageQueue_port] <= False;
|
||||||
|
endmethod
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
method Bool emptyForFlush;
|
method Bool emptyForFlush;
|
||||||
@@ -381,14 +422,16 @@ endmodule
|
|||||||
|
|
||||||
// exported version
|
// exported version
|
||||||
module mkL1CRqMshr#(
|
module mkL1CRqMshr#(
|
||||||
function Addr getAddrFromReq(reqT r)
|
function Addr getAddrFromReq(reqT r),
|
||||||
|
function indexT getIndexFromAddr(Addr addr)
|
||||||
)(
|
)(
|
||||||
L1CRqMshr#(cRqNum, wayT, tagT, reqT)
|
L1CRqMshr#(cRqNum, indexT, wayT, tagT, reqT)
|
||||||
) provisos (
|
) provisos (
|
||||||
|
Alias#(indexT, Bit#(_indexSz)),
|
||||||
Alias#(wayT, Bit#(_waySz)),
|
Alias#(wayT, Bit#(_waySz)),
|
||||||
Alias#(tagT, Bit#(_tagSz)),
|
Alias#(tagT, Bit#(_tagSz)),
|
||||||
Bits#(reqT, _reqSz)
|
Bits#(reqT, _reqSz)
|
||||||
);
|
);
|
||||||
let m <- mkL1CRqMshrSafe(getAddrFromReq);
|
let m <- mkL1CRqMshrSafe(getAddrFromReq, getIndexFromAddr);
|
||||||
return m;
|
return m;
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@@ -126,11 +126,12 @@ interface L1Pipe#(
|
|||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, void, // no dir
|
tagT, Msi, void, // no dir
|
||||||
Maybe#(cRqIdxT), void, RandRepInfo, // no other
|
Maybe#(cRqIdxT), void, RandRepInfo, // no other
|
||||||
Line, L1Cmd#(indexT, cRqIdxT, pRqIdxT)
|
Line, Maybe#(cRqIdxT), L1Cmd#(indexT, cRqIdxT, pRqIdxT)
|
||||||
) first;
|
) first;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(cRqIdxT) swapRq,
|
Maybe#(cRqIdxT) swapRq,
|
||||||
RamData#(tagT, Msi, void, Maybe#(cRqIdxT), void, Line) wrRam, // always write BRAM
|
RamData#(tagT, Msi, void, Maybe#(cRqIdxT), void, Line) wrRam, // always write BRAM
|
||||||
|
Maybe#(cRqIdxT) nextInQueue,
|
||||||
Bool updateRep
|
Bool updateRep
|
||||||
);
|
);
|
||||||
endinterface
|
endinterface
|
||||||
@@ -162,11 +163,12 @@ module mkL1Pipe(
|
|||||||
Alias#(dirT, void), // no directory
|
Alias#(dirT, void), // no directory
|
||||||
Alias#(ownerT, Maybe#(cRqIdxT)),
|
Alias#(ownerT, Maybe#(cRqIdxT)),
|
||||||
Alias#(otherT, void), // no other cache info
|
Alias#(otherT, void), // no other cache info
|
||||||
|
Alias#(setAuxT, Maybe#(cRqIdxT)),
|
||||||
Alias#(repT, RandRepInfo), // use random replace
|
Alias#(repT, RandRepInfo), // use random replace
|
||||||
Alias#(pipeInT, L1PipeIn#(wayT, indexT, cRqIdxT, pRqIdxT)),
|
Alias#(pipeInT, L1PipeIn#(wayT, indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeCmdT, L1PipeCmd#(wayT, indexT, cRqIdxT, pRqIdxT)),
|
Alias#(pipeCmdT, L1PipeCmd#(wayT, indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, l1CmdT)), // output type
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, setAuxT, l1CmdT)), // output type
|
||||||
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
||||||
Alias#(respStateT, RespState#(Msi)),
|
Alias#(respStateT, RespState#(Msi)),
|
||||||
@@ -189,6 +191,7 @@ module mkL1Pipe(
|
|||||||
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCoreForwarded);
|
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCoreForwarded);
|
||||||
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
||||||
Vector#(wayNum, RWBramCore#(indexT, Line)) dataRam <- replicateM(mkRWBramCoreForwarded);
|
Vector#(wayNum, RWBramCore#(indexT, Line)) dataRam <- replicateM(mkRWBramCoreForwarded);
|
||||||
|
RWBramCore#(indexT, setAuxT) queueRam <- mkRWBramCoreForwarded;
|
||||||
|
|
||||||
// initialize RAM
|
// initialize RAM
|
||||||
Reg#(Bool) initDone <- mkReg(False);
|
Reg#(Bool) initDone <- mkReg(False);
|
||||||
@@ -205,6 +208,7 @@ module mkL1Pipe(
|
|||||||
});
|
});
|
||||||
end
|
end
|
||||||
repRam.wrReq(initIndex, randRepInitInfo); // useless for random replace
|
repRam.wrReq(initIndex, randRepInitInfo); // useless for random replace
|
||||||
|
queueRam.wrReq(initIndex, Invalid);
|
||||||
initIndex <= initIndex + 1;
|
initIndex <= initIndex + 1;
|
||||||
if(initIndex == maxBound) begin
|
if(initIndex == maxBound) begin
|
||||||
initDone <= True;
|
initDone <= True;
|
||||||
@@ -272,11 +276,11 @@ module mkL1Pipe(
|
|||||||
Addr addr = getAddrFromCmd(cmd);
|
Addr addr = getAddrFromCmd(cmd);
|
||||||
tagT tag = getTag(addr);
|
tagT tag = getTag(addr);
|
||||||
// find hit way (nothing is being replaced)
|
// find hit way (nothing is being replaced)
|
||||||
function Bool isMatch(Tuple2#(Msi, tagT) csTag);
|
function Bool isMatch(Tuple3#(Msi, tagT, ownerT) csTagOwner);
|
||||||
match {.cs, .t} = csTag;
|
match {.cs, .t, .o} = csTagOwner;
|
||||||
return cs > I && t == tag;
|
return (cs > I || isValid(o)) && t == tag;
|
||||||
endfunction
|
endfunction
|
||||||
Maybe#(wayT) hitWay = searchIndex(isMatch, zip(csVec, tagVec));
|
Maybe#(wayT) hitWay = searchIndex(isMatch, zip3(csVec, tagVec, ownerVec));
|
||||||
if(hitWay matches tagged Valid .w) begin
|
if(hitWay matches tagged Valid .w) begin
|
||||||
return TagMatchResult {
|
return TagMatchResult {
|
||||||
way: w,
|
way: w,
|
||||||
@@ -300,9 +304,14 @@ module mkL1Pipe(
|
|||||||
end
|
end
|
||||||
Maybe#(wayT) repWay = randRep.getReplaceWay(unlocked, invalid);
|
Maybe#(wayT) repWay = randRep.getReplaceWay(unlocked, invalid);
|
||||||
// sanity check: repWay must be valid
|
// sanity check: repWay must be valid
|
||||||
|
// ^ Not true if there are more MSHRs than ways
|
||||||
|
// Just choose a locked way. This will create a dependency chain.
|
||||||
|
// TODO: Maybe would be nice to replace the way that becomes free the soonest.
|
||||||
if(!isValid(repWay)) begin
|
if(!isValid(repWay)) begin
|
||||||
$fwrite(stderr, "[L1Pipe] ERROR: ", fshow(cmd), " cannot find way to replace\n");
|
if(verbose)
|
||||||
$finish;
|
$display("%t L1 %m tagMatch: set oversubscription", $time);
|
||||||
|
//$fwrite(stderr, "[L1Pipe] ERROR: ", fshow(cmd), " cannot find way to replace\n");
|
||||||
|
//$finish;
|
||||||
end
|
end
|
||||||
return TagMatchResult {
|
return TagMatchResult {
|
||||||
way: fromMaybe(?, repWay),
|
way: fromMaybe(?, repWay),
|
||||||
@@ -339,11 +348,11 @@ module mkL1Pipe(
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
CCPipe#(
|
CCPipe#(
|
||||||
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT
|
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, setAuxT, pipeCmdT
|
||||||
) pipe <- mkCCPipeSingleCycle(
|
) pipe <- mkCCPipeSingleCycle(
|
||||||
regToReadOnly(initDone), getIndex, tagMatch,
|
regToReadOnly(initDone), getIndex, tagMatch,
|
||||||
updateByUpCs, updateByDownDir, updateRepInfo,
|
updateByUpCs, updateByDownDir, updateRepInfo,
|
||||||
infoRam, repRam, dataRam
|
infoRam, repRam, dataRam, queueRam
|
||||||
);
|
);
|
||||||
|
|
||||||
method Action send(pipeInT req);
|
method Action send(pipeInT req);
|
||||||
@@ -387,11 +396,12 @@ module mkL1Pipe(
|
|||||||
way: pout.way,
|
way: pout.way,
|
||||||
pRqMiss: pout.pRqMiss,
|
pRqMiss: pout.pRqMiss,
|
||||||
ram: pout.ram,
|
ram: pout.ram,
|
||||||
repInfo: pout.repInfo
|
repInfo: pout.repInfo,
|
||||||
|
setAuxData: pout.setAuxData
|
||||||
};
|
};
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
method Action deqWrite(Maybe#(cRqIdxT) swapRq, ramDataT wrRam, Bool updateRep);
|
method Action deqWrite(Maybe#(cRqIdxT) swapRq, ramDataT wrRam, Maybe#(cRqIdxT) nextInQueue, Bool updateRep);
|
||||||
// get new cmd
|
// get new cmd
|
||||||
Maybe#(pipeCmdT) newCmd = Invalid;
|
Maybe#(pipeCmdT) newCmd = Invalid;
|
||||||
if(swapRq matches tagged Valid .idx) begin // swap in cRq
|
if(swapRq matches tagged Valid .idx) begin // swap in cRq
|
||||||
@@ -403,6 +413,6 @@ module mkL1Pipe(
|
|||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
// call pipe
|
// call pipe
|
||||||
pipe.deqWrite(newCmd, wrRam, updateRep);
|
pipe.deqWrite(newCmd, wrRam, nextInQueue, updateRep);
|
||||||
endmethod
|
endmethod
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ module mkLLBank#(
|
|||||||
Alias#(cRqT, LLRq#(cRqIdT, dmaRqIdT, childT)),
|
Alias#(cRqT, LLRq#(cRqIdT, dmaRqIdT, childT)),
|
||||||
Alias#(cRqSlotT, LLCRqSlot#(wayT, tagT, Vector#(childNum, DirPend))), // cRq MSHR slot
|
Alias#(cRqSlotT, LLCRqSlot#(wayT, tagT, Vector#(childNum, DirPend))), // cRq MSHR slot
|
||||||
Alias#(llCmdT, LLCmd#(childT, cRqIndexT)),
|
Alias#(llCmdT, LLCmd#(childT, cRqIndexT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, cacheOwnerT, void, RandRepInfo, Line, llCmdT)),
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, cacheOwnerT, void, RandRepInfo, Line, void, llCmdT)),
|
||||||
// requirements
|
// requirements
|
||||||
Bits#(cRqIdT, _cRqIdSz),
|
Bits#(cRqIdT, _cRqIdSz),
|
||||||
Bits#(dmaRqIdT, _dmaRqIdSz),
|
Bits#(dmaRqIdT, _dmaRqIdSz),
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ interface LLPipe#(
|
|||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, Vector#(childNum, Msi),
|
tagT, Msi, Vector#(childNum, Msi),
|
||||||
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
||||||
Line, LLCmd#(Bit#(TLog#(childNum)), cRqIdxT)
|
Line, void, LLCmd#(Bit#(TLog#(childNum)), cRqIdxT) // no aux set data
|
||||||
) first;
|
) first;
|
||||||
method PipeOut#(
|
method PipeOut#(
|
||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, Vector#(childNum, Msi),
|
tagT, Msi, Vector#(childNum, Msi),
|
||||||
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
||||||
Line, LLCmd#(Bit#(TLog#(childNum)), cRqIdxT)
|
Line, void, LLCmd#(Bit#(TLog#(childNum)), cRqIdxT) // no aux set data
|
||||||
) unguard_first;
|
) unguard_first;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(cRqIdxT) swapRq,
|
Maybe#(cRqIdxT) swapRq,
|
||||||
@@ -143,7 +143,7 @@ module mkLLPipe(
|
|||||||
Alias#(pipeInT, LLPipeIn#(childT, wayT, cRqIdxT)),
|
Alias#(pipeInT, LLPipeIn#(childT, wayT, cRqIdxT)),
|
||||||
Alias#(pipeCmdT, LLPipeCmd#(childT, wayT, cRqIdxT)),
|
Alias#(pipeCmdT, LLPipeCmd#(childT, wayT, cRqIdxT)),
|
||||||
Alias#(llCmdT, LLCmd#(childT, cRqIdxT)),
|
Alias#(llCmdT, LLCmd#(childT, cRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, llCmdT)), // output type
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, llCmdT)), // output type
|
||||||
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
||||||
Alias#(respStateT, RespState#(Msi)),
|
Alias#(respStateT, RespState#(Msi)),
|
||||||
@@ -165,6 +165,7 @@ module mkLLPipe(
|
|||||||
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCore);
|
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCore);
|
||||||
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
||||||
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
||||||
|
RWBramCore#(indexT, void) setAuxDataRam <- mkDummyBramCore;
|
||||||
|
|
||||||
// initialize RAM
|
// initialize RAM
|
||||||
Reg#(Bool) initDone <- mkReg(False);
|
Reg#(Bool) initDone <- mkReg(False);
|
||||||
@@ -322,14 +323,14 @@ module mkLLPipe(
|
|||||||
endactionvalue
|
endactionvalue
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
CCPipe#(wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT) pipe <- mkCCPipe(
|
CCPipe#(wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT) pipe <- mkCCPipe(
|
||||||
regToReadOnly(initDone), getIndex, tagMatch,
|
regToReadOnly(initDone), getIndex, tagMatch,
|
||||||
updateByUpCs, updateByDownDir, updateRepInfo,
|
updateByUpCs, updateByDownDir, updateRepInfo,
|
||||||
infoRam, repRam, dataRam
|
infoRam, repRam, dataRam, setAuxDataRam
|
||||||
);
|
);
|
||||||
|
|
||||||
// get first output from CCPipe output
|
// get first output from CCPipe output
|
||||||
function pipeOutT getFirst(PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT) pout);
|
function pipeOutT getFirst(PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT) pout);
|
||||||
return PipeOut {
|
return PipeOut {
|
||||||
cmd: (case(pout.cmd) matches
|
cmd: (case(pout.cmd) matches
|
||||||
tagged CRq .rq: LLCRq (rq.mshrIdx);
|
tagged CRq .rq: LLCRq (rq.mshrIdx);
|
||||||
@@ -340,7 +341,8 @@ module mkLLPipe(
|
|||||||
way: pout.way,
|
way: pout.way,
|
||||||
pRqMiss: pout.pRqMiss,
|
pRqMiss: pout.pRqMiss,
|
||||||
ram: pout.ram,
|
ram: pout.ram,
|
||||||
repInfo: pout.repInfo
|
repInfo: pout.repInfo,
|
||||||
|
setAuxData: ?
|
||||||
};
|
};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -383,6 +385,6 @@ module mkLLPipe(
|
|||||||
newCmd = Valid (CRq (LLPipeCRqIn {addr: addr, mshrIdx: idx}));
|
newCmd = Valid (CRq (LLPipeCRqIn {addr: addr, mshrIdx: idx}));
|
||||||
end
|
end
|
||||||
// call pipe
|
// call pipe
|
||||||
pipe.deqWrite(newCmd, wrRam, updateRep);
|
pipe.deqWrite(newCmd, wrRam, ?, updateRep);
|
||||||
endmethod
|
endmethod
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@@ -45,6 +45,34 @@ interface RWBramCore#(type addrT, type dataT);
|
|||||||
method Action deqRdResp;
|
method Action deqRdResp;
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
|
interface RBramCore#(type addrT, type dataT);
|
||||||
|
method Action rd1Req(addrT a);
|
||||||
|
method Action rd2Req(addrT a);
|
||||||
|
method dataT rd1Resp;
|
||||||
|
method dataT rd2Resp;
|
||||||
|
method Bool rd1RespValid;
|
||||||
|
method Bool rd2RespValid;
|
||||||
|
method Action deqRd1Resp;
|
||||||
|
method Action deqRd2Resp;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module mkDummyBramCore(RWBramCore#(addrT, dataT)) provisos(
|
||||||
|
Bits#(addrT, addrSz), Bits#(dataT, dataSz)
|
||||||
|
);
|
||||||
|
method Action wrReq(addrT a, dataT d);
|
||||||
|
endmethod
|
||||||
|
|
||||||
|
method Action rdReq(addrT a);
|
||||||
|
endmethod
|
||||||
|
|
||||||
|
method dataT rdResp = ?;
|
||||||
|
|
||||||
|
method rdRespValid = True;
|
||||||
|
|
||||||
|
method Action deqRdResp;
|
||||||
|
endmethod
|
||||||
|
endmodule
|
||||||
|
|
||||||
module mkRWBramCore(RWBramCore#(addrT, dataT)) provisos(
|
module mkRWBramCore(RWBramCore#(addrT, dataT)) provisos(
|
||||||
Bits#(addrT, addrSz), Bits#(dataT, dataSz)
|
Bits#(addrT, addrSz), Bits#(dataT, dataSz)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ interface SelfInvIPipe#(
|
|||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, void, // no dir
|
tagT, Msi, void, // no dir
|
||||||
Maybe#(cRqIdxT), void, RandRepInfo, // no other
|
Maybe#(cRqIdxT), void, RandRepInfo, // no other
|
||||||
Line, SelfInvICmd#(cRqIdxT)
|
Line, void, SelfInvICmd#(cRqIdxT) // no aux set data
|
||||||
) first;
|
) first;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(cRqIdxT) swapRq,
|
Maybe#(cRqIdxT) swapRq,
|
||||||
@@ -239,7 +239,7 @@ module mkSelfInvIPipe(
|
|||||||
Alias#(pipeInT, SelfInvIPipeIn#(wayT, cRqIdxT)),
|
Alias#(pipeInT, SelfInvIPipeIn#(wayT, cRqIdxT)),
|
||||||
Alias#(pipeCmdT, SelfInvIPipeCmd#(wayT, cRqIdxT)),
|
Alias#(pipeCmdT, SelfInvIPipeCmd#(wayT, cRqIdxT)),
|
||||||
Alias#(iCmdT, SelfInvICmd#(cRqIdxT)),
|
Alias#(iCmdT, SelfInvICmd#(cRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, iCmdT)), // output type
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, iCmdT)), // output type
|
||||||
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
||||||
Alias#(respStateT, RespState#(Msi)),
|
Alias#(respStateT, RespState#(Msi)),
|
||||||
@@ -262,6 +262,7 @@ module mkSelfInvIPipe(
|
|||||||
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
||||||
// data RAM
|
// data RAM
|
||||||
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
||||||
|
RWBramCore#(indexT, void) setAuxDataRam <- mkDummyBramCore;
|
||||||
|
|
||||||
// initialize RAM
|
// initialize RAM
|
||||||
Reg#(Bool) initDone <- mkReg(False);
|
Reg#(Bool) initDone <- mkReg(False);
|
||||||
@@ -392,11 +393,11 @@ module mkSelfInvIPipe(
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
CCPipe#(
|
CCPipe#(
|
||||||
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT
|
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT
|
||||||
) pipe <- mkCCPipe(
|
) pipe <- mkCCPipe(
|
||||||
regToReadOnly(initDone), getIndex, tagMatch,
|
regToReadOnly(initDone), getIndex, tagMatch,
|
||||||
updateByUpCs, updateByDownDir, updateRepInfo,
|
updateByUpCs, updateByDownDir, updateRepInfo,
|
||||||
infoRam, repRam, dataRam
|
infoRam, repRam, dataRam, setAuxDataRam
|
||||||
);
|
);
|
||||||
|
|
||||||
// reconcile: wait until pipeline empty and drop all S states. Stall
|
// reconcile: wait until pipeline empty and drop all S states. Stall
|
||||||
@@ -458,7 +459,8 @@ module mkSelfInvIPipe(
|
|||||||
way: pout.way,
|
way: pout.way,
|
||||||
pRqMiss: pout.pRqMiss,
|
pRqMiss: pout.pRqMiss,
|
||||||
ram: pout.ram,
|
ram: pout.ram,
|
||||||
repInfo: pout.repInfo
|
repInfo: pout.repInfo,
|
||||||
|
setAuxData: ?
|
||||||
};
|
};
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
@@ -470,7 +472,7 @@ module mkSelfInvIPipe(
|
|||||||
newCmd = Valid (CRq (SelfInvIPipeRqIn {addr: addr, mshrIdx: idx}));
|
newCmd = Valid (CRq (SelfInvIPipeRqIn {addr: addr, mshrIdx: idx}));
|
||||||
end
|
end
|
||||||
// call pipe
|
// call pipe
|
||||||
pipe.deqWrite(newCmd, wrRam, updateRep);
|
pipe.deqWrite(newCmd, wrRam, ?, updateRep);
|
||||||
// conflict with reconcile
|
// conflict with reconcile
|
||||||
conflict_reconcile_deq.wset(?);
|
conflict_reconcile_deq.wset(?);
|
||||||
endmethod
|
endmethod
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ interface SelfInvL1Pipe#(
|
|||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, void, // no dir
|
tagT, Msi, void, // no dir
|
||||||
Maybe#(cRqIdxT), SelfInvL1Hits#(maxHitNum), RandRepInfo,
|
Maybe#(cRqIdxT), SelfInvL1Hits#(maxHitNum), RandRepInfo,
|
||||||
Line, SelfInvL1Cmd#(cRqIdxT, pRqIdxT)
|
Line, void, SelfInvL1Cmd#(cRqIdxT, pRqIdxT) // no aux set data
|
||||||
) first;
|
) first;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(cRqIdxT) swapRq,
|
Maybe#(cRqIdxT) swapRq,
|
||||||
@@ -252,7 +252,7 @@ module mkSelfInvL1Pipe(
|
|||||||
Alias#(pipeInT, SelfInvL1PipeIn#(wayT, cRqIdxT, pRqIdxT)),
|
Alias#(pipeInT, SelfInvL1PipeIn#(wayT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeCmdT, SelfInvL1PipeCmd#(wayT, cRqIdxT, pRqIdxT)),
|
Alias#(pipeCmdT, SelfInvL1PipeCmd#(wayT, cRqIdxT, pRqIdxT)),
|
||||||
Alias#(l1CmdT, SelfInvL1Cmd#(cRqIdxT, pRqIdxT)),
|
Alias#(l1CmdT, SelfInvL1Cmd#(cRqIdxT, pRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, l1CmdT)), // output type
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, l1CmdT)), // output type
|
||||||
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
||||||
Alias#(respStateT, RespState#(Msi)),
|
Alias#(respStateT, RespState#(Msi)),
|
||||||
@@ -277,6 +277,7 @@ module mkSelfInvL1Pipe(
|
|||||||
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
||||||
// data RAM
|
// data RAM
|
||||||
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
||||||
|
RWBramCore#(indexT, void) setAuxDataRam <- mkDummyBramCore;
|
||||||
|
|
||||||
// initialize RAM
|
// initialize RAM
|
||||||
Reg#(Bool) initDone <- mkReg(False);
|
Reg#(Bool) initDone <- mkReg(False);
|
||||||
@@ -414,11 +415,11 @@ module mkSelfInvL1Pipe(
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
CCPipe#(
|
CCPipe#(
|
||||||
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT
|
wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT
|
||||||
) pipe <- mkCCPipe(
|
) pipe <- mkCCPipe(
|
||||||
regToReadOnly(initDone), getIndex, tagMatch,
|
regToReadOnly(initDone), getIndex, tagMatch,
|
||||||
updateByUpCs, updateByDownDir, updateRepInfo,
|
updateByUpCs, updateByDownDir, updateRepInfo,
|
||||||
infoRam, repRam, dataRam
|
infoRam, repRam, dataRam, setAuxDataRam
|
||||||
);
|
);
|
||||||
|
|
||||||
// reconcile: wait until pipeline empty and drop all S states. Stall
|
// reconcile: wait until pipeline empty and drop all S states. Stall
|
||||||
@@ -484,7 +485,8 @@ module mkSelfInvL1Pipe(
|
|||||||
way: pout.way,
|
way: pout.way,
|
||||||
pRqMiss: pout.pRqMiss,
|
pRqMiss: pout.pRqMiss,
|
||||||
ram: pout.ram,
|
ram: pout.ram,
|
||||||
repInfo: pout.repInfo
|
repInfo: pout.repInfo,
|
||||||
|
setAuxData: ?
|
||||||
};
|
};
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
@@ -496,7 +498,7 @@ module mkSelfInvL1Pipe(
|
|||||||
newCmd = Valid (CRq (SelfInvL1PipeRqIn {addr: addr, mshrIdx: idx}));
|
newCmd = Valid (CRq (SelfInvL1PipeRqIn {addr: addr, mshrIdx: idx}));
|
||||||
end
|
end
|
||||||
// call pipe
|
// call pipe
|
||||||
pipe.deqWrite(newCmd, wrRam, updateRep);
|
pipe.deqWrite(newCmd, wrRam, ?, updateRep);
|
||||||
// conflict with reconcile
|
// conflict with reconcile
|
||||||
conflict_reconcile_deq.wset(?);
|
conflict_reconcile_deq.wset(?);
|
||||||
endmethod
|
endmethod
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ interface SelfInvLLPipe#(
|
|||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, SelfInvDir#(Bit#(TLog#(childNum))),
|
tagT, Msi, SelfInvDir#(Bit#(TLog#(childNum))),
|
||||||
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
||||||
Line, SelfInvLLCmd#(Bit#(TLog#(childNum)), cRqIdxT)
|
Line, void, SelfInvLLCmd#(Bit#(TLog#(childNum)), cRqIdxT) // no aux set data
|
||||||
) first;
|
) first;
|
||||||
method PipeOut#(
|
method PipeOut#(
|
||||||
Bit#(TLog#(wayNum)),
|
Bit#(TLog#(wayNum)),
|
||||||
tagT, Msi, SelfInvDir#(Bit#(TLog#(childNum))),
|
tagT, Msi, SelfInvDir#(Bit#(TLog#(childNum))),
|
||||||
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
Maybe#(CRqOwner#(cRqIdxT)), void, RandRepInfo, // no other
|
||||||
Line, SelfInvLLCmd#(Bit#(TLog#(childNum)), cRqIdxT)
|
Line, void, SelfInvLLCmd#(Bit#(TLog#(childNum)), cRqIdxT) // no aux set data
|
||||||
) unguard_first;
|
) unguard_first;
|
||||||
method Action deqWrite(
|
method Action deqWrite(
|
||||||
Maybe#(cRqIdxT) swapRq,
|
Maybe#(cRqIdxT) swapRq,
|
||||||
@@ -143,7 +143,7 @@ module mkSelfInvLLPipe(
|
|||||||
Alias#(pipeInT, SelfInvLLPipeIn#(childT, wayT, cRqIdxT)),
|
Alias#(pipeInT, SelfInvLLPipeIn#(childT, wayT, cRqIdxT)),
|
||||||
Alias#(pipeCmdT, SelfInvLLPipeCmd#(childT, wayT, cRqIdxT)),
|
Alias#(pipeCmdT, SelfInvLLPipeCmd#(childT, wayT, cRqIdxT)),
|
||||||
Alias#(llCmdT, SelfInvLLCmd#(childT, cRqIdxT)),
|
Alias#(llCmdT, SelfInvLLCmd#(childT, cRqIdxT)),
|
||||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, llCmdT)), // output type
|
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, llCmdT)), // output type
|
||||||
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
Alias#(infoT, CacheInfo#(tagT, Msi, dirT, ownerT, otherT)),
|
||||||
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
Alias#(ramDataT, RamData#(tagT, Msi, dirT, ownerT, otherT, Line)),
|
||||||
Alias#(respStateT, RespState#(Msi)),
|
Alias#(respStateT, RespState#(Msi)),
|
||||||
@@ -165,6 +165,7 @@ module mkSelfInvLLPipe(
|
|||||||
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCore);
|
Vector#(wayNum, RWBramCore#(indexT, infoT)) infoRam <- replicateM(mkRWBramCore);
|
||||||
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
RWBramCore#(indexT, repT) repRam <- mkRandRepRam;
|
||||||
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
RWBramCore#(dataIndexT, Line) dataRam <- mkRWBramCore;
|
||||||
|
RWBramCore#(indexT, void) setAuxDataRam <- mkDummyBramCore;
|
||||||
|
|
||||||
// initialize RAM
|
// initialize RAM
|
||||||
Reg#(Bool) initDone <- mkReg(False);
|
Reg#(Bool) initDone <- mkReg(False);
|
||||||
@@ -318,14 +319,14 @@ module mkSelfInvLLPipe(
|
|||||||
endactionvalue
|
endactionvalue
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
CCPipe#(wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT) pipe <- mkCCPipe(
|
CCPipe#(wayNum, indexT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT) pipe <- mkCCPipe(
|
||||||
regToReadOnly(initDone), getIndex, tagMatch,
|
regToReadOnly(initDone), getIndex, tagMatch,
|
||||||
updateByUpCs, updateByDownDir, updateRepInfo,
|
updateByUpCs, updateByDownDir, updateRepInfo,
|
||||||
infoRam, repRam, dataRam
|
infoRam, repRam, dataRam, setAuxDataRam
|
||||||
);
|
);
|
||||||
|
|
||||||
// get first output from CCPipe output
|
// get first output from CCPipe output
|
||||||
function pipeOutT getFirst(PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, pipeCmdT) pout);
|
function pipeOutT getFirst(PipeOut#(wayT, tagT, Msi, dirT, ownerT, otherT, repT, Line, void, pipeCmdT) pout);
|
||||||
return PipeOut {
|
return PipeOut {
|
||||||
cmd: (case(pout.cmd) matches
|
cmd: (case(pout.cmd) matches
|
||||||
tagged CRq .rq: LLCRq (rq.mshrIdx);
|
tagged CRq .rq: LLCRq (rq.mshrIdx);
|
||||||
@@ -336,7 +337,8 @@ module mkSelfInvLLPipe(
|
|||||||
way: pout.way,
|
way: pout.way,
|
||||||
pRqMiss: pout.pRqMiss,
|
pRqMiss: pout.pRqMiss,
|
||||||
ram: pout.ram,
|
ram: pout.ram,
|
||||||
repInfo: pout.repInfo
|
repInfo: pout.repInfo,
|
||||||
|
setAuxData: ?
|
||||||
};
|
};
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -379,7 +381,7 @@ module mkSelfInvLLPipe(
|
|||||||
newCmd = Valid (CRq (SelfInvLLPipeCRqIn {addr: addr, mshrIdx: idx}));
|
newCmd = Valid (CRq (SelfInvLLPipeCRqIn {addr: addr, mshrIdx: idx}));
|
||||||
end
|
end
|
||||||
// call pipe
|
// call pipe
|
||||||
pipe.deqWrite(newCmd, wrRam, updateRep);
|
pipe.deqWrite(newCmd, wrRam, ?, updateRep);
|
||||||
endmethod
|
endmethod
|
||||||
endmodule
|
endmodule
|
||||||
`endif // SELF_INV_CACHE
|
`endif // SELF_INV_CACHE
|
||||||
|
|||||||
@@ -112,12 +112,15 @@ typedef Bit#(TMax#(SizeOf#(LdQTag), SizeOf#(SBIndex))) DProcReqId;
|
|||||||
|
|
||||||
(* synthesize *)
|
(* synthesize *)
|
||||||
module mkDCRqMshrWrapper(
|
module mkDCRqMshrWrapper(
|
||||||
L1CRqMshr#(DCRqNum, L1Way, DTag, ProcRq#(DProcReqId))
|
L1CRqMshr#(DCRqNum, DIndex, L1Way, DTag, ProcRq#(DProcReqId))
|
||||||
);
|
);
|
||||||
function Addr getAddrFromReq(ProcRq#(DProcReqId) r);
|
function Addr getAddrFromReq(ProcRq#(DProcReqId) r);
|
||||||
return r.addr;
|
return r.addr;
|
||||||
endfunction
|
endfunction
|
||||||
let m <- mkL1CRqMshr(getAddrFromReq);
|
function DIndex getIndexFromAddr(Addr addr);
|
||||||
|
return truncate(addr >> (valueOf(LgLineSzBytes) + valueOf(LgDBankNum)));
|
||||||
|
endfunction
|
||||||
|
let m <- mkL1CRqMshr(getAddrFromReq, getIndexFromAddr);
|
||||||
return m;
|
return m;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user