2-byte aligned instruction memory to simplify compressed instruction
fetch.
This commit is contained in:
@@ -97,7 +97,7 @@ typedef TDiv#(MemDataSz, 8) MemDataSzBytes;
|
||||
typedef TLog#(MemDataSzBytes) LgMemDataSzBytes;
|
||||
typedef Bit#(LgMemDataSzBytes) MemDataBytesOffset;
|
||||
|
||||
typedef TDiv#(InstSz, 8) InstSzBytes;
|
||||
typedef TDiv#(Inst16_Sz, 8) InstSzBytes;
|
||||
typedef TLog#(InstSzBytes) LgInstSzBytes;
|
||||
|
||||
// 64B cache line -- XXX same with parameters in CacheUtils.bsv
|
||||
@@ -230,7 +230,7 @@ typedef struct {
|
||||
// I$ req/resp
|
||||
interface InstServer#(numeric type supSz);
|
||||
interface Put#(Addr) req;
|
||||
interface Get#(Vector#(supSz, Maybe#(Instruction))) resp;
|
||||
interface Get#(Vector#(TMul#(supSz,2), Maybe#(Instruction16))) resp;
|
||||
`ifdef DEBUG_ICACHE
|
||||
interface Get#(DebugICacheResp) done; // the id and cache line of the I$ req that truly performs
|
||||
`endif
|
||||
|
||||
@@ -124,7 +124,8 @@ module mkIBank#(
|
||||
Alias#(cRqSlotT, ICRqSlot#(wayT, tagT)), // cRq MSHR slot
|
||||
Alias#(l1CmdT, L1Cmd#(indexT, cRqIdxT, pRqIdxT)),
|
||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, void, RandRepInfo, Line, l1CmdT)),
|
||||
Alias#(resultT, Vector#(supSz, Maybe#(Instruction))),
|
||||
Mul#(2, supSz, supSzX2),
|
||||
Alias#(resultT, Vector#(supSzX2, Maybe#(Instruction16))),
|
||||
// requirements
|
||||
FShow#(pipeOutT),
|
||||
Add#(tagSz, a__, AddrSz),
|
||||
@@ -156,13 +157,13 @@ module mkIBank#(
|
||||
|
||||
// index Q to order all in flight cRq for in-order resp
|
||||
FIFO#(cRqIdxT) cRqIndexQ <- mkSizedFIFO(valueof(cRqNum));
|
||||
|
||||
|
||||
`ifdef DEBUG_ICACHE
|
||||
// id for each cRq, incremented when each new req comes
|
||||
Reg#(Bit#(64)) cRqId <- mkReg(0);
|
||||
// FIFO to signal the id of cRq that is performed
|
||||
// FIFO has 0 cycle latency to match L1 D$ resp latency
|
||||
Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo;
|
||||
Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo;
|
||||
`endif
|
||||
|
||||
// security flush
|
||||
@@ -248,8 +249,8 @@ module mkIBank#(
|
||||
mshrIdx: n
|
||||
}));
|
||||
if (verbose)
|
||||
$display("%t I %m pRqTransfer: ", $time,
|
||||
fshow(n), " ; ",
|
||||
$display("%t I %m pRqTransfer: ", $time,
|
||||
fshow(n), " ; ",
|
||||
fshow(req)
|
||||
);
|
||||
endrule
|
||||
@@ -268,7 +269,7 @@ module mkIBank#(
|
||||
$display("%t I %m pRsTransfer: ", $time, fshow(resp));
|
||||
doAssert(resp.toState == S && isValid(resp.data), "I$ must upgrade to S with data");
|
||||
endrule
|
||||
|
||||
|
||||
`ifdef SECURITY
|
||||
// start flush when cRq MSHR is empty
|
||||
rule startFlushReq(!flushDone && !flushReqStart && cRqMshr.emptyForFlush);
|
||||
@@ -326,8 +327,8 @@ module mkIBank#(
|
||||
// (prevent parent resp from coming to release MSHR entry before replace resp is sent)
|
||||
rqToPIndexQ_sendRsToP.enq(n);
|
||||
if (verbose)
|
||||
$display("%t I %m sendRsToP: ", $time,
|
||||
fshow(rsToPIndexQ.first)," ; ",
|
||||
$display("%t I %m sendRsToP: ", $time,
|
||||
fshow(rsToPIndexQ.first)," ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(slot), " ; ",
|
||||
fshow(resp)
|
||||
@@ -347,9 +348,9 @@ module mkIBank#(
|
||||
rsToPQ.enq(resp);
|
||||
pRqMshr.sendRsToP_pRq.releaseEntry(n); // mshr entry released
|
||||
if (verbose)
|
||||
$display("%t I %m sendRsToP: ", $time,
|
||||
fshow(rsToPIndexQ.first), " ; ",
|
||||
fshow(req), " ; ",
|
||||
$display("%t I %m sendRsToP: ", $time,
|
||||
fshow(rsToPIndexQ.first), " ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(resp)
|
||||
);
|
||||
doAssert(req.toState == I, "I$ only has downgrade req to I");
|
||||
@@ -370,10 +371,10 @@ module mkIBank#(
|
||||
};
|
||||
rqToPQ.enq(cRqToP);
|
||||
if (verbose)
|
||||
$display("%t I %m sendRqToP: ", $time,
|
||||
fshow(n), " ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(slot), " ; ",
|
||||
$display("%t I %m sendRqToP: ", $time,
|
||||
fshow(n), " ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(slot), " ; ",
|
||||
fshow(cRqToP)
|
||||
);
|
||||
`ifdef PERF_COUNT
|
||||
@@ -404,14 +405,14 @@ module mkIBank#(
|
||||
|
||||
// function to get superscaler inst read result
|
||||
function resultT readInst(Line line, Addr addr);
|
||||
Vector#(LineSzInst, Instruction) instVec = unpack(pack(line.data));
|
||||
Vector#(LineSzInst, Instruction16) instVec = unpack(pack(line.data));
|
||||
// the start offset for reading inst
|
||||
LineInstOffset startSel = getLineInstOffset(addr);
|
||||
// calculate the maximum inst count that could be read from line
|
||||
LineInstOffset maxCntMinusOne = maxBound - startSel;
|
||||
// read inst superscalaer
|
||||
resultT val = ?;
|
||||
for(Integer i = 0; i < valueof(supSz); i = i+1) begin
|
||||
for(Integer i = 0; i < valueof(supSzX2); i = i+1) begin
|
||||
if(fromInteger(i) <= maxCntMinusOne) begin
|
||||
LineInstOffset sel = startSel + fromInteger(i);
|
||||
val[i] = Valid (instVec[sel]);
|
||||
@@ -474,7 +475,7 @@ module mkIBank#(
|
||||
procRqT procRq = pipeOutCRq;
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: ", $time, fshow(n), " ; ", fshow(procRq));
|
||||
|
||||
|
||||
// find end of dependency chain
|
||||
Maybe#(cRqIdxT) cRqEOC = cRqMshr.pipelineResp.searchEndOfChain(procRq.addr);
|
||||
|
||||
@@ -487,7 +488,7 @@ module mkIBank#(
|
||||
// and this func is only called when cs < S (otherwise will hit)
|
||||
// because L1 has no children to wait for
|
||||
doAssert(!cSlot.waitP && ram.info.cs == I, "waitP must be false and cs must be I");
|
||||
// Thus we must send req to parent
|
||||
// Thus we must send req to parent
|
||||
// XXX first send to a temp indexQ to avoid conflict, then merge to rqToPIndexQ later
|
||||
rqToPIndexQ_pipelineResp.enq(n);
|
||||
// update mshr
|
||||
@@ -537,7 +538,7 @@ module mkIBank#(
|
||||
rsToPIndexQ.enq(CRq (n));
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
|
||||
// function to set cRq to Depend, and make no further change to cache
|
||||
function Action cRqSetDepNoCacheChange;
|
||||
action
|
||||
@@ -786,7 +787,7 @@ module mkIBank#(
|
||||
};
|
||||
endmethod
|
||||
endinterface
|
||||
|
||||
|
||||
interface pRqStuck = pRqMshr.stuck;
|
||||
|
||||
`ifdef SECURITY
|
||||
@@ -886,4 +887,3 @@ endmodule
|
||||
// unsafe version: all reads read the original reg value, except sendRsToC, which should bypass from pipelineResp
|
||||
// all writes are cononicalized. NOTE: writes of sendRsToC should be after pipelineResp
|
||||
// we maintain the logical ordering in safe version
|
||||
|
||||
|
||||
@@ -122,7 +122,8 @@ module mkSelfInvIBank#(
|
||||
Alias#(cRqSlotT, ICRqSlot#(wayT, tagT)), // cRq MSHR slot
|
||||
Alias#(iCmdT, SelfInvICmd#(cRqIdxT)),
|
||||
Alias#(pipeOutT, PipeOut#(wayT, tagT, Msi, void, cacheOwnerT, otherT, RandRepInfo, Line, iCmdT)),
|
||||
Alias#(resultT, Vector#(supSz, Maybe#(Instruction))),
|
||||
Mul#(2, supSz, supSzX2),
|
||||
Alias#(resultT, Vector#(supSzX2, Maybe#(Instruction16))),
|
||||
// requirements
|
||||
FShow#(pipeOutT),
|
||||
Add#(tagSz, a__, AddrSz),
|
||||
@@ -146,7 +147,7 @@ module mkSelfInvIBank#(
|
||||
|
||||
// index Q to order all in flight cRq for in-order resp
|
||||
FIFO#(cRqIdxT) cRqIndexQ <- mkSizedFIFO(valueof(cRqNum));
|
||||
|
||||
|
||||
// Reconcile states
|
||||
Reg#(Bool) needReconcile <- mkReg(False);
|
||||
Reg#(Bool) waitReconcileDone <- mkReg(False);
|
||||
@@ -156,7 +157,7 @@ module mkSelfInvIBank#(
|
||||
Reg#(Bit#(64)) cRqId <- mkReg(0);
|
||||
// FIFO to signal the id of cRq that is performed
|
||||
// FIFO has 0 cycle latency to match L1 D$ resp latency
|
||||
Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo;
|
||||
Fifo#(1, DebugICacheResp) cRqDoneQ <- mkBypassFifo;
|
||||
`endif
|
||||
|
||||
`ifdef PERF_COUNT
|
||||
@@ -244,7 +245,7 @@ module mkSelfInvIBank#(
|
||||
$display("%t I %m pRsTransfer: ", $time, fshow(resp));
|
||||
doAssert(resp.toState == S && isValid(resp.data), "I$ must upgrade to S with data");
|
||||
endrule
|
||||
|
||||
|
||||
rule sendRqToP;
|
||||
rqToPIndexQ.deq;
|
||||
cRqIdxT n = rqToPIndexQ.first;
|
||||
@@ -260,10 +261,10 @@ module mkSelfInvIBank#(
|
||||
};
|
||||
rqToPQ.enq(cRqToP);
|
||||
if (verbose)
|
||||
$display("%t I %m sendRqToP: ", $time,
|
||||
fshow(n), " ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(slot), " ; ",
|
||||
$display("%t I %m sendRqToP: ", $time,
|
||||
fshow(n), " ; ",
|
||||
fshow(req), " ; ",
|
||||
fshow(slot), " ; ",
|
||||
fshow(cRqToP)
|
||||
);
|
||||
`ifdef PERF_COUNT
|
||||
@@ -294,14 +295,14 @@ module mkSelfInvIBank#(
|
||||
|
||||
// function to get superscaler inst read result
|
||||
function resultT readInst(Line line, Addr addr);
|
||||
Vector#(LineSzInst, Instruction) instVec = unpack(pack(line.data));
|
||||
Vector#(LineSzInst, Instruction16) instVec = unpack(pack(line.data));
|
||||
// the start offset for reading inst
|
||||
LineInstOffset startSel = getLineInstOffset(addr);
|
||||
// calculate the maximum inst count that could be read from line
|
||||
LineInstOffset maxCntMinusOne = maxBound - startSel;
|
||||
// read inst superscalaer
|
||||
resultT val = ?;
|
||||
for(Integer i = 0; i < valueof(supSz); i = i+1) begin
|
||||
for(Integer i = 0; i < valueof(supSzX2); i = i+1) begin
|
||||
if(fromInteger(i) <= maxCntMinusOne) begin
|
||||
LineInstOffset sel = startSel + fromInteger(i);
|
||||
val[i] = Valid (instVec[sel]);
|
||||
@@ -364,7 +365,7 @@ module mkSelfInvIBank#(
|
||||
procRqT procRq = pipeOutCRq;
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: ", $time, fshow(n), " ; ", fshow(procRq));
|
||||
|
||||
|
||||
// find end of dependency chain
|
||||
Maybe#(cRqIdxT) cRqEOC = cRqMshr.pipelineResp.searchEndOfChain(procRq.addr);
|
||||
|
||||
@@ -380,7 +381,7 @@ module mkSelfInvIBank#(
|
||||
doAssert(ram.info.cs <= S, "no exclusive in I$");
|
||||
// This cannot be a hit
|
||||
doAssert(ram.info.cs == I || ram.info.tag != getTag(procRq.addr), "cannot hit");
|
||||
// Thus we must send req to parent
|
||||
// Thus we must send req to parent
|
||||
rqToPIndexQ.enq(n);
|
||||
// update mshr
|
||||
cRqMshr.pipelineResp.setStateSlot(n, WaitSt, ICRqSlot {
|
||||
@@ -551,7 +552,7 @@ module mkSelfInvIBank#(
|
||||
};
|
||||
endmethod
|
||||
endinterface
|
||||
|
||||
|
||||
interface pRqStuck = nullGet;
|
||||
|
||||
`ifdef SECURITY
|
||||
@@ -659,4 +660,3 @@ endmodule
|
||||
// unsafe version: all reads read the original reg value, except sendRsToC, which should bypass from pipelineResp
|
||||
// all writes are cononicalized. NOTE: writes of sendRsToC should be after pipelineResp
|
||||
// we maintain the logical ordering in safe version
|
||||
|
||||
|
||||
Reference in New Issue
Block a user