Changes to make Prefetcher more deterministic, and also to report schedules.
This commit is contained in:
@@ -36,6 +36,8 @@ import Vector::*;
|
|||||||
import BuildVector::*;
|
import BuildVector::*;
|
||||||
import ProcTypes::*;
|
import ProcTypes::*;
|
||||||
|
|
||||||
|
Bool verbose = False;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HIT = 1'b0, MISS = 1'b1
|
HIT = 1'b0, MISS = 1'b1
|
||||||
} HitOrMiss deriving (Bits, Eq, FShow);
|
} HitOrMiss deriving (Bits, Eq, FShow);
|
||||||
@@ -193,7 +195,7 @@ module mkSingleWindowL1LLPrefetcher(Prefetcher);
|
|||||||
method ActionValue#(Addr) getNextPrefetchAddr if (nextToAsk != rangeEnd);
|
method ActionValue#(Addr) getNextPrefetchAddr if (nextToAsk != rangeEnd);
|
||||||
nextToAsk <= nextToAsk + 1;
|
nextToAsk <= nextToAsk + 1;
|
||||||
let retAddr = Addr'{nextToAsk, '0}; //extend cache line address to regular address
|
let retAddr = Addr'{nextToAsk, '0}; //extend cache line address to regular address
|
||||||
if(verbose) $display("%t Prefetcher getNextPrefetchAddr requesting %h", $time, retAddr);
|
if (verbose) $display("%t Prefetcher getNextPrefetchAddr requesting %h", $time, retAddr);
|
||||||
return retAddr;
|
return retAddr;
|
||||||
endmethod
|
endmethod
|
||||||
endmodule
|
endmodule
|
||||||
@@ -446,13 +448,13 @@ module mkTargetTable(TargetTable#(narrowTableSize, wideTableSize)) provisos
|
|||||||
if (narrowTable[narrowIdx][0] matches tagged Valid .entry
|
if (narrowTable[narrowIdx][0] matches tagged Valid .entry
|
||||||
&&& entry.tag == addr[31:valueOf(narrowTableIdxBits)]) begin
|
&&& entry.tag == addr[31:valueOf(narrowTableIdxBits)]) begin
|
||||||
narrowTable[narrowIdx][0] <= Invalid;
|
narrowTable[narrowIdx][0] <= Invalid;
|
||||||
//$display("%t found narrow table entry %h", $time, addr + signExtend(pack(entry.distance)));
|
//if (verbose) $display("%t found narrow table entry %h", $time, addr + signExtend(pack(entry.distance)));
|
||||||
return Valid(addr + signExtend(pack(entry.distance)));
|
return Valid(addr + signExtend(pack(entry.distance)));
|
||||||
end
|
end
|
||||||
else if (wideTable[wideIdx][0] matches tagged Valid .entry
|
else if (wideTable[wideIdx][0] matches tagged Valid .entry
|
||||||
&&& entry.tag == addr[31:valueOf(wideTableIdxBits)]) begin
|
&&& entry.tag == addr[31:valueOf(wideTableIdxBits)]) begin
|
||||||
wideTable[wideIdx][0] <= Invalid;
|
wideTable[wideIdx][0] <= Invalid;
|
||||||
//$display("%t found wide table entry %h", $time, entry.target);
|
//if (verbose) $display("%t found wide table entry %h", $time, entry.target);
|
||||||
return Valid(entry.target);
|
return Valid(entry.target);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -620,12 +622,12 @@ module mkTargetTableDouble(TargetTableDouble#(narrowTableSize, wideTableSize)) p
|
|||||||
actionvalue
|
actionvalue
|
||||||
if (narrowWrapped matches tagged Valid .narrow
|
if (narrowWrapped matches tagged Valid .narrow
|
||||||
&&& narrowTagMatch(addrHash, narrow)) begin
|
&&& narrowTagMatch(addrHash, narrow)) begin
|
||||||
//$display("%t found narrow table entry %h", $time, addr + signExtend(pack(narrow.distance)));
|
//if (verbose) $display("%t found narrow table entry %h", $time, addr + signExtend(pack(narrow.distance)));
|
||||||
return Valid(addr + signExtend(pack(narrow.distance)));
|
return Valid(addr + signExtend(pack(narrow.distance)));
|
||||||
end
|
end
|
||||||
else if (wideWrapped matches tagged Valid .wide
|
else if (wideWrapped matches tagged Valid .wide
|
||||||
&&& wideTagMatch(addrHash, wide)) begin
|
&&& wideTagMatch(addrHash, wide)) begin
|
||||||
//$display("%t found wide table entry %h", $time, wide.target);
|
//if (verbose) $display("%t found wide table entry %h", $time, wide.target);
|
||||||
return Valid(wide.target);
|
return Valid(wide.target);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -690,7 +692,7 @@ module mkTargetTableDouble(TargetTableDouble#(narrowTableSize, wideTableSize)) p
|
|||||||
entry.distance = truncate(distance);
|
entry.distance = truncate(distance);
|
||||||
|
|
||||||
if (Valid(entry) != lastMissNarrowMRUEntry) begin
|
if (Valid(entry) != lastMissNarrowMRUEntry) begin
|
||||||
//$display("%t Recording miss -- modifying narrow table", $time);
|
//if (verbose) $display("%t Recording miss -- modifying narrow table", $time);
|
||||||
//Maintain the property that one address can only have
|
//Maintain the property that one address can only have
|
||||||
// at most 2 of 4 table entries for it.
|
// at most 2 of 4 table entries for it.
|
||||||
//Shift narrow table entries down, storing in MRU.
|
//Shift narrow table entries down, storing in MRU.
|
||||||
@@ -710,7 +712,7 @@ module mkTargetTableDouble(TargetTableDouble#(narrowTableSize, wideTableSize)) p
|
|||||||
entry.target = currAddr;
|
entry.target = currAddr;
|
||||||
|
|
||||||
if (Valid(entry) != lastMissWideMRUEntry) begin
|
if (Valid(entry) != lastMissWideMRUEntry) begin
|
||||||
//$display("%t Recording miss -- modifying wide table", $time);
|
//if (verbose) $display("%t Recording miss -- modifying wide table", $time);
|
||||||
wideTableMRU.wrReq(idx, Valid(entry));
|
wideTableMRU.wrReq(idx, Valid(entry));
|
||||||
wideTableLRU.wrReq(idx, lastMissWideMRUEntry);
|
wideTableLRU.wrReq(idx, lastMissWideMRUEntry);
|
||||||
Bit#(narrowTableIdxBits) narrowIdx = truncate(lastMissAddrHash);
|
Bit#(narrowTableIdxBits) narrowIdx = truncate(lastMissAddrHash);
|
||||||
@@ -748,9 +750,9 @@ module mkTargetTableDouble(TargetTableDouble#(narrowTableSize, wideTableSize)) p
|
|||||||
//Update the entries for the last miss to point to this one
|
//Update the entries for the last miss to point to this one
|
||||||
writeMissEntry(addr);
|
writeMissEntry(addr);
|
||||||
//Save the raw table entries
|
//Save the raw table entries
|
||||||
//$display("idx: %x", addrHash);
|
//if (verbose) $display("idx: %x", addrHash);
|
||||||
//$display("%t Read resp: nMRU: ", fshow(narrowTableMRU.rdResp), "wMRU: ", fshow(wideTableMRU.rdResp));
|
//if (verbose) $display("%t Read resp: nMRU: ", fshow(narrowTableMRU.rdResp), "wMRU: ", fshow(wideTableMRU.rdResp));
|
||||||
//$display("%t Read resp: nLRU: ", fshow(narrowTableLRU.rdResp), "wLRU: ", fshow(wideTableLRU.rdResp));
|
//if (verbose) $display("%t Read resp: nLRU: ", fshow(narrowTableLRU.rdResp), "wLRU: ", fshow(wideTableLRU.rdResp));
|
||||||
lastMissWideMRUEntry <= wideTableMRU.rdResp;
|
lastMissWideMRUEntry <= wideTableMRU.rdResp;
|
||||||
lastMissNarrowMRUEntry <= narrowTableMRU.rdResp;
|
lastMissNarrowMRUEntry <= narrowTableMRU.rdResp;
|
||||||
lastMissWideLRUEntry <= wideTableLRU.rdResp;
|
lastMissWideLRUEntry <= wideTableLRU.rdResp;
|
||||||
@@ -1036,7 +1038,7 @@ module mkBRAMMarkovPrefetcher(Prefetcher) provisos
|
|||||||
|
|
||||||
if (hitMiss == MISS) begin
|
if (hitMiss == MISS) begin
|
||||||
//Don't start markov chain if its very recent
|
//Don't start markov chain if its very recent
|
||||||
//$display("%t Prefetcher start new chain with %h", $time, addr);
|
//if (verbose) $display("%t Prefetcher start new chain with %h", $time, addr);
|
||||||
chainNextToLookup <= cl;
|
chainNextToLookup <= cl;
|
||||||
chainNumberToPrefetch <= fromInteger(valueOf(maxChainLength));
|
chainNumberToPrefetch <= fromInteger(valueOf(maxChainLength));
|
||||||
end
|
end
|
||||||
@@ -1291,7 +1293,7 @@ provisos(
|
|||||||
strideTable.deqRdResp;
|
strideTable.deqRdResp;
|
||||||
StrideEntry seNext = se;
|
StrideEntry seNext = se;
|
||||||
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
|
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
|
||||||
if (verbose) $writeh("%t Stride Prefetcher updateStrideEntry ", $time,
|
if (verbose) $display("%t Stride Prefetcher updateStrideEntry ", $time,
|
||||||
fshow(hitMiss), " ", addr,
|
fshow(hitMiss), " ", addr,
|
||||||
". Entry ", index, " state is ", fshow(se.state));
|
". Entry ", index, " state is ", fshow(se.state));
|
||||||
if (se.state == EMPTY) begin
|
if (se.state == EMPTY) begin
|
||||||
@@ -1415,7 +1417,7 @@ provisos(
|
|||||||
);
|
);
|
||||||
Bool verbose = False;
|
Bool verbose = False;
|
||||||
RWBramCore#(strideTableIndexT, StrideEntry2) strideTable <- mkRWBramCoreForwarded;
|
RWBramCore#(strideTableIndexT, StrideEntry2) strideTable <- mkRWBramCoreForwarded;
|
||||||
FIFOF#(Tuple3#(Addr, Bit#(16), HitOrMiss)) memAccesses <- mkSizedBypassFIFOF(8);
|
FIFOF#(Tuple3#(Addr, Bit#(16), HitOrMiss)) memAccesses <- mkUGSizedFIFOF(8);
|
||||||
Reg#(Tuple3#(Addr, Bit#(16), HitOrMiss)) rdRespEntry <- mkReg(?);
|
Reg#(Tuple3#(Addr, Bit#(16), HitOrMiss)) rdRespEntry <- mkReg(?);
|
||||||
|
|
||||||
Fifo#(8, Addr) addrToPrefetch <- mkOverflowPipelineFifo;
|
Fifo#(8, Addr) addrToPrefetch <- mkOverflowPipelineFifo;
|
||||||
@@ -1423,7 +1425,7 @@ provisos(
|
|||||||
Reg#(Maybe#(Bit#(2))) cLinesPrefetchedLatest <- mkReg(?);
|
Reg#(Maybe#(Bit#(2))) cLinesPrefetchedLatest <- mkReg(?);
|
||||||
PulseWire holdReadReq <- mkPulseWire;
|
PulseWire holdReadReq <- mkPulseWire;
|
||||||
|
|
||||||
rule sendReadReq if (!holdReadReq);
|
rule sendReadReq if (!holdReadReq && memAccesses.notEmpty);
|
||||||
match {.addr, .pcHash, .hitMiss} = memAccesses.first;
|
match {.addr, .pcHash, .hitMiss} = memAccesses.first;
|
||||||
if (verbose) $display("%t Sending read req for %h!", $time, pcHash);
|
if (verbose) $display("%t Sending read req for %h!", $time, pcHash);
|
||||||
strideTable.rdReq(truncate(pcHash));
|
strideTable.rdReq(truncate(pcHash));
|
||||||
@@ -1445,7 +1447,7 @@ provisos(
|
|||||||
strideTable.deqRdResp;
|
strideTable.deqRdResp;
|
||||||
StrideEntry2 seNext = se;
|
StrideEntry2 seNext = se;
|
||||||
Int#(12) observedStride = unpack(addr[11:0] - se.lastAddr);
|
Int#(12) observedStride = unpack(addr[11:0] - se.lastAddr);
|
||||||
if (verbose) $writeh("%t Stride Prefetcher updateStrideEntry ", $time,
|
if (verbose) $display("%t Stride Prefetcher updateStrideEntry ", $time,
|
||||||
fshow(hitMiss), " ", addr,
|
fshow(hitMiss), " ", addr,
|
||||||
". Entry ", index, " state is ", fshow(se.state));
|
". Entry ", index, " state is ", fshow(se.state));
|
||||||
if (se.state == INIT && observedStride != 0) begin
|
if (se.state == INIT && observedStride != 0) begin
|
||||||
@@ -1548,7 +1550,7 @@ provisos(
|
|||||||
endrule
|
endrule
|
||||||
|
|
||||||
method Action reportAccess(Addr addr, Bit#(16) pcHash, HitOrMiss hitMiss);
|
method Action reportAccess(Addr addr, Bit#(16) pcHash, HitOrMiss hitMiss);
|
||||||
memAccesses.enq(tuple3 (addr, pcHash, hitMiss));
|
if (memAccesses.notFull) memAccesses.enq(tuple3 (addr, pcHash, hitMiss));
|
||||||
endmethod
|
endmethod
|
||||||
|
|
||||||
method ActionValue#(Addr) getNextPrefetchAddr;
|
method ActionValue#(Addr) getNextPrefetchAddr;
|
||||||
@@ -1726,7 +1728,7 @@ provisos(
|
|||||||
strideTable.deqRdResp;
|
strideTable.deqRdResp;
|
||||||
StrideEntryAdaptive seNext = se;
|
StrideEntryAdaptive seNext = se;
|
||||||
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
|
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
|
||||||
if (verbose) $writeh("%t Stride Prefetcher updateStrideEntry ", $time,
|
if (verbose) $display("%t Stride Prefetcher updateStrideEntry ", $time,
|
||||||
fshow(hitMiss), " ", addr,
|
fshow(hitMiss), " ", addr,
|
||||||
". Entry ", index, " state is ", fshow(se.state));
|
". Entry ", index, " state is ", fshow(se.state));
|
||||||
if (se.state == EMPTY) begin
|
if (se.state == EMPTY) begin
|
||||||
@@ -1946,7 +1948,7 @@ module mkLLIPrefetcher(Prefetcher);
|
|||||||
`endif
|
`endif
|
||||||
return m;
|
return m;
|
||||||
endmodule
|
endmodule
|
||||||
|
(* synthesize *)
|
||||||
module mkL1DPrefetcher(PCPrefetcher);
|
module mkL1DPrefetcher(PCPrefetcher);
|
||||||
`ifdef DATA_PREFETCHER_IN_L1
|
`ifdef DATA_PREFETCHER_IN_L1
|
||||||
`ifdef DATA_PREFETCHER_BLOCK
|
`ifdef DATA_PREFETCHER_BLOCK
|
||||||
|
|||||||
Reference in New Issue
Block a user