Implement adaptive stride prefetcher, update prefetcher tests

This commit is contained in:
Karlis Susters
2023-03-17 10:58:54 +00:00
parent 65ed55cb8a
commit cef4990ce3
2 changed files with 326 additions and 416 deletions

View File

@@ -996,6 +996,218 @@ provisos(
endmethod
endmodule
typedef enum {
EMPTY = 3'd0, INIT = 3'd1, TRANSIENT = 3'd2, STEADY1 = 3'd3,
STEADY2 = 3'd4, STEADY3 = 3'd5, STEADY4 = 4'd6, STEADYLAST = 3'd7
} StrideStateAdaptive deriving (Bits, Eq, FShow);
typedef struct {
Bit#(12) lastAddr;
Bit#(13) stride;
StrideStateAdaptive state;
Bit#(4) cLinesPrefetched; //Stores how many cache lines have been prefetched for this instruction
} StrideEntryAdaptive deriving (Bits, Eq, FShow);
module mkBRAMStrideAdaptivePCPrefetcher(PCPrefetcher)
provisos(
NumAlias#(strideTableSize, 64),
NumAlias#(cLinesPrefetchMin, 2),
NumAlias#(cLinesSmallStridePrefetchMax, 3),
NumAlias#(cLinesBigStridePrefetchMax, 5),
Alias#(strideTableIndexT, Bit#(TLog#(strideTableSize)))
);
RWBramCore#(strideTableIndexT, StrideEntryAdaptive) strideTable <- mkRWBramCoreForwarded;
FIFOF#(Tuple3#(Addr, Bit#(16), HitOrMiss)) memAccesses <- mkSizedBypassFIFOF(8);
Reg#(Tuple3#(Addr, Bit#(16), HitOrMiss)) rdRespEntry <- mkReg(?);
Fifo#(8, Addr) addrToPrefetch <- mkOverflowPipelineFifo;
FIFO#(Tuple3#(StrideEntryAdaptive, Addr, Bit#(16))) strideEntryForPrefetch <- mkBypassFIFO();
Reg#(Maybe#(Bit#(4))) cLinesPrefetchedLatest <- mkReg(?);
PulseWire holdReadReq <- mkPulseWire;
function StrideStateAdaptive incrementSteady(StrideStateAdaptive state);
case (state)
STEADY1: return STEADY2;
STEADY2: return STEADY3;
STEADY3: return STEADY4;
STEADY4: return STEADYLAST;
STEADYLAST: return STEADYLAST;
default: return STEADY1;
endcase
endfunction
function Bool stateAtLeastSteady(StrideStateAdaptive state);
return (state == STEADY1 ||
state == STEADY2 ||
state == STEADY3 ||
state == STEADY4 ||
state == STEADYLAST);
endfunction
function Bit#(4) cLinesAheadToPrefetch(StrideStateAdaptive state, Bit#(13) stride);
let absStride = abs(stride);
if (absStride <= 8) begin
if (state == STEADY4 || state == STEADYLAST) begin
return fromInteger(valueof(cLinesSmallStridePrefetchMax));
end
else begin
return fromInteger(valueof(cLinesPrefetchMin));
end
end
else begin
//big strides
if (state == STEADYLAST) begin
return fromInteger(valueof(cLinesBigStridePrefetchMax));
end
else if (state == STEADY3 || state == STEADY4) begin
return fromInteger(valueof(cLinesBigStridePrefetchMax))-1;
end
else begin
return fromInteger(valueof(cLinesPrefetchMin));
end
end
endfunction
rule sendReadReq if (!holdReadReq);
match {.addr, .pcHash, .hitMiss} = memAccesses.first;
$display("%t Sending read req for %h!", $time, pcHash);
strideTable.rdReq(truncate(pcHash));
rdRespEntry <= memAccesses.first;
memAccesses.deq;
endrule
rule updateStrideEntry;
//Find slot in vector
//if miss and slot empty
//if slot init, put address, stride and move to transit
//if slot transit or steady, verify stride, and move to steady
// also put last_prefetched
//if stride wrong, move to transit
match {.addr, .pcHash, .hitMiss} = rdRespEntry;
strideTableIndexT index = truncate(pcHash);
StrideEntryAdaptive se = strideTable.rdResp;
strideTable.deqRdResp;
StrideEntryAdaptive seNext = se;
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
$writeh("%t Stride Prefetcher updateStrideEntry ", $time,
fshow(hitMiss), " ", addr,
". Entry ", index, " state is ", fshow(se.state));
if (se.state == EMPTY) begin
if (hitMiss == MISS) begin
seNext.lastAddr = truncate(addr);
seNext.state = INIT;
$display(", allocate entry");
end
else begin
$display(", ignore");
end
end
else if (se.state == INIT && observedStride != 0) begin
seNext.stride = observedStride;
seNext.state = TRANSIENT;
seNext.lastAddr = truncate(addr);
$display(", set stride to %h", seNext.stride);
end
else if (se.state == TRANSIENT && observedStride != 0) begin
if (observedStride == se.stride) begin
//Here we transition from TRANSIENT to STEADY, so init this field
seNext.cLinesPrefetched = 0;
seNext.state = STEADY1;
$display(", stride %h is confirmed!", seNext.stride);
end
else begin
seNext.state = TRANSIENT;
seNext.stride = observedStride;
$display(", old stride is broken! New stride: %h", seNext.stride);
end
seNext.lastAddr = truncate(addr);
end
else if (stateAtLeastSteady(se.state) && observedStride != 0) begin
if (observedStride == se.stride) begin
if (se.lastAddr[11:6] != addr[11:6]) begin
//This means we have crossed a cache line since last access
seNext.cLinesPrefetched =
(se.cLinesPrefetched == 0) ? 0 : se.cLinesPrefetched - 1;
end
seNext.state = incrementSteady(se.state);
$display(", stride %h is sustained, advance STEADY number!", se.stride);
end
else if (se.state == STEADY4 || se.state == STEADYLAST) begin
//Leniency towards some stride changes
seNext.state = STEADY1;
seNext.cLinesPrefetched = 0; //We've jumped to some other address, so start fetching again!
$display(", old stride is broken, but tolerate it! Keep old stride: %h", se.stride);
end
else begin
seNext.state = TRANSIENT;
seNext.stride = observedStride;
$display(", old stride is broken! New stride: %h", seNext.stride);
end
seNext.lastAddr = truncate(addr);
end
else
$display("");
strideEntryForPrefetch.enq(tuple3(seNext, addr, pcHash));
endrule
rule createPrefetchRequests;
match {.se, .addr, .pcHash} = strideEntryForPrefetch.first;
//If this rule is looping, then we'll have a valid cLinesPrefetchedLatest
Bit#(4) cLinesPrefetched = fromMaybe(se.cLinesPrefetched, cLinesPrefetchedLatest);
if (stateAtLeastSteady(se.state) &&
cLinesPrefetched !=
cLinesAheadToPrefetch(se.state, se.stride)) begin
//can prefetch
Bit#(13) strideToUse;
Bit#(13) cLineSize = fromInteger(valueof(DataSz));
if (se.stride[12] == 1 && se.stride > -cLineSize) begin
//stride is negative and jumps less than one cline
strideToUse = -cLineSize;
end
else if (se.stride[12] == 0 && se.stride < cLineSize) begin
//stride is positive and jumps less than one cline
strideToUse = cLineSize;
end
else begin
strideToUse = se.stride;
end
let reqAddr = addr +
(signExtend(strideToUse) * zeroExtend(cLinesPrefetched + 1));
addrToPrefetch.enq(reqAddr);
// We will still be processing this StrideEntry next cycle,
// so hold off any potential read requests until we do a writeback
holdReadReq.send();
cLinesPrefetchedLatest <= Valid(cLinesPrefetched + 1);
$display("%t Stride Prefetcher getNextPrefetchAddr requesting %h for entry %h", $time, reqAddr, pcHash[7:0]);
end
else begin
//cant prefetch
$display("%t Stride Prefetcher no possible prefetch for entry %h", $time, strideTableIndexT'(truncate(pcHash)));
strideEntryForPrefetch.deq;
se.cLinesPrefetched = cLinesPrefetched;
cLinesPrefetchedLatest <= Invalid;
strideTable.wrReq(truncate(pcHash), se);
end
endrule
method Action reportAccess(Addr addr, Bit#(16) pcHash, HitOrMiss hitMiss);
memAccesses.enq(tuple3 (addr, pcHash, hitMiss));
endmethod
method ActionValue#(Addr) getNextPrefetchAddr;
addrToPrefetch.deq;
return addrToPrefetch.first;
endmethod
endmodule
module mkL1IPrefetcher(Prefetcher);
`ifdef INSTR_PREFETCHER_IN_L1
`ifdef INSTR_PREFETCHER_NEXT_LINE_ON_ALL
@@ -1071,6 +1283,8 @@ module mkL1DPrefetcher(PCPrefetcher);
let m <- mkPCPrefetcherAdapter(mkBlockPrefetcher);
`elsif DATA_PREFETCHER_STRIDE
let m <- mkBRAMStridePCPrefetcher;
`elsif DATA_PREFETCHER_STRIDE_ADAPTIVE
let m <- mkBRAMStridePCPrefetcher;
`elsif DATA_PREFETCHER_MARKOV
let m <- mkPCPrefetcherAdapter(mkBRAMMarkovPrefetcher);
`endif
@@ -1087,6 +1301,8 @@ module mkLLDPrefetcherInL1D(PCPrefetcher);
let m <- mkPCPrefetcherAdapter(mkBlockPrefetcher);
`elsif DATA_PREFETCHER_STRIDE
let m <- mkBRAMStridePCPrefetcher;
`elsif DATA_PREFETCHER_STRIDE_ADAPTIVE
let m <- mkBRAMStridePCPrefetcher;
`elsif DATA_PREFETCHER_MARKOV
let m <- mkPCPrefetcherAdapter(mkBRAMMarkovPrefetcher);
`endif
@@ -1103,6 +1319,8 @@ module mkLLDPrefetcher(Prefetcher);
let m <- mkBlockPrefetcher;
`elsif DATA_PREFETCHER_STRIDE
doAssert(False, "Illegal data prefetcher type for LL cache!")
`elsif DATA_PREFETCHER_STRIDE
doAssert(False, "Illegal data prefetcher type for LL cache!")
`elsif DATA_PREFETCHER_MARKOV
let m <- mkBRAMMarkovPrefetcher;
`endif

View File

@@ -58,14 +58,14 @@ module mkTargetTableBRAMTest(Empty);
t.readReq('h8000); // comes from short table
endaction
action
let x <- t.readRespAndClear(); // comes from short table
let x <- t.readResp(True); // comes from short table
doAssert(x == Valid('h800a), "test fail!");
endaction
action
t.readReq('h8000); // comes from long table
endaction
action
let x <- t.readRespAndClear(); // comes from long table
let x <- t.readResp(True); // comes from long table
doAssert(x == Valid('h80008000), "test fail!");
endaction
action
@@ -75,7 +75,7 @@ module mkTargetTableBRAMTest(Empty);
t.readReq('h80000000); // comes from long table
endaction
action
let x <- t.readRespAndClear(); // comes from long table
let x <- t.readResp(True); // comes from long table
doAssert(x == Valid('h21230000), "test fail!");
endaction
action
@@ -85,248 +85,20 @@ module mkTargetTableBRAMTest(Empty);
t.readReq('h7000); // get from short table
endaction
action
let x <- t.readRespAndClear(); // get from short table
let x <- t.readResp(True); // get from short table
doAssert(x == Valid('h6fde), "test fail!");
endaction
action
t.readReq('h7000); // get from short table
endaction
action
let x <- t.readRespAndClear(); // get from short table
let x <- t.readResp(True); // get from short table
doAssert(x == Invalid, "test fail!"); //entry was removed!
endaction
endseq
);
endmodule
module mkMultiWindowPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkMultiWindowPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.reportAccess('h80000040, MISS);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000080, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800000c0, "test fail!");
endaction
action
p.reportAccess('h800000c0, HIT); //Report hit inside window
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000100, "test fail!");
endaction
action
p.reportAccess('h80004000, HIT); //Report hit outside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000140, "test fail!");
endaction
action
p.reportAccess('h80000140, MISS); //Report miss inside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000180, "test fail!");
endaction
// ----- Allocate other windows -----
action
p.reportAccess('h70000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h70000040, "test fail!");
endaction
action
p.reportAccess('h90000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h90000040, "test fail!");
endaction
action
p.reportAccess('h60000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h60000040, "test fail!");
endaction
action
p.reportAccess('h80000180, HIT); //Report hit inside oldest window
endaction
action
let x <- p.getNextPrefetchAddr; //oldest window recommended
doAssert(x == 'h800001c0, "test fail!");
endaction
// ----- Trigger window deletion -----
action
p.reportAccess('h50000000, MISS); //Report miss outside window,
//discard window with 'h70..
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h50000040, "test fail!");
endaction
action
p.reportAccess('h70000040, HIT); //Report hit inside now deleted window
endaction
action
let x <- p.getNextPrefetchAddr; //most recent window still recommended
doAssert(x == 'h50000080, "test fail!");
endaction
// ----- Reorder some more windows around
action
p.reportAccess('h800001c0, MISS); //Report hit inside now deleted window
endaction
action
let x <- p.getNextPrefetchAddr; //most recent window still recommended
doAssert(x == 'h80000200, "test fail!");
endaction
endseq
);
endmodule
module mkMultiWindowTargetPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkMultiWindowTargetPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.reportAccess('h80000040, MISS);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000080, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800000c0, "test fail!");
endaction
action
p.reportAccess('h800000c0, HIT); //Report hit inside window
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000100, "test fail!");
endaction
action
p.reportAccess('h80004000, HIT); //Report hit outside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000140, "test fail!");
endaction
action
p.reportAccess('h80000140, MISS); //Report miss inside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000180, "test fail!");
endaction
// ----- Allocate other windows -----
action
p.reportAccess('h70000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h70000040, "test fail!");
endaction
action
p.reportAccess('h90000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h90000040, "test fail!");
endaction
action
p.reportAccess('h60000000, MISS); //Report miss outside window
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h60000040, "test fail!");
endaction
action
p.reportAccess('h80000180, HIT); //Report hit inside oldest window
endaction
action
let x <- p.getNextPrefetchAddr; //oldest window recommended
doAssert(x == 'h800001c0, "test fail!");
endaction
// ----- Trigger window deletion -----
action
p.reportAccess('h50000000, MISS); //Report miss outside window,
//discard window with 'h70..
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h50000040, "test fail!");
endaction
action
p.reportAccess('h70000040, HIT); //Report hit inside now deleted window
endaction
action
let x <- p.getNextPrefetchAddr; //most recent window still recommended
doAssert(x == 'h50000080, "test fail!");
endaction
// ----- Reorder some more windows around
action
p.reportAccess('h800001c0, MISS); //Report hit inside now deleted window
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000200, "test fail!");
endaction
// ------ Test saving and prefetching target clines
action
p.reportAccess('h81000000, MISS); //Report miss somewhere far away
endaction
action
let x <- p.getNextPrefetchAddr; //New window allocated and recommended
doAssert(x == 'h81000040, "test fail!");
endaction
action
p.reportAccess('h80000180, MISS); //Report miss back home
endaction
action
let x <- p.getNextPrefetchAddr; //new window recommended
doAssert(x == 'h50000000, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800001c0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr; //target address recommended
doAssert(x == 'h81000000, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000200, "test fail!"); // window addresss recommended
endaction
endseq
);
endmodule
module mkBRAMMultiWindowTargetPrefetcherTest(Empty);
let p <- mkBRAMMultiWindowTargetPrefetcher;
mkAutoFSM(
@@ -451,70 +223,6 @@ module mkBRAMMultiWindowTargetPrefetcherTest(Empty);
endseq
);
endmodule
module mkSingleWindowTargetPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkSingleWindowTargetPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.reportAccess('h80000040, MISS);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000080, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800000c0, "test fail!");
endaction
action
p.reportAccess('h800000c0, HIT); //Report hit inside window
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000100, "test fail!");
endaction
action
p.reportAccess('h80004000, HIT); //Report hit outside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000140, "test fail!");
endaction
action
p.reportAccess('h80000140, MISS); //Report miss inside window
endaction
action
let x <- p.getNextPrefetchAddr; //Previous window still recommended
doAssert(x == 'h80000180, "test fail!");
endaction
action
p.reportAccess('h81000000, MISS); //Report miss somewhere far away
endaction
action
let x <- p.getNextPrefetchAddr; //New window allocated and recommended
doAssert(x == 'h81000040, "test fail!");
endaction
action
p.reportAccess('h80000100, MISS); //Report miss back home
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000140, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr; //target address recommended
doAssert(x == 'h81000000, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000180, "test fail!"); // window addresss recommended
endaction
endseq
);
endmodule
module mkBRAMSingleWindowTargetPrefetcherTest(Empty);
let p <- mkBRAMSingleWindowTargetPrefetcher;
@@ -589,77 +297,6 @@ module mkBRAMSingleWindowTargetPrefetcherTest(Empty);
);
endmodule
module mkStridePCPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkStridePCPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action p.reportAccess('h80000040, 'h0069, MISS); endaction
action p.reportAccess('h80000080, 'h0069, HIT); endaction
action p.reportAccess('h800000a0, 'h0069, HIT); endaction
action p.reportAccess('h800000c0, 'h0069, MISS); endaction
action p.reportAccess('h800000e0, 'h0069, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000120, "test fail!");
endaction
action p.reportAccess('h80000100, 'h0069, HIT); endaction
action p.reportAccess('h80000120, 'h0069, HIT); endaction
action p.reportAccess('h80000140, 'h0069, HIT); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000180, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800001c0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000200, "test fail!");
endaction
action p.reportAccess('h900001f0, 'h006a, MISS); endaction
action p.reportAccess('h900001c0, 'h006a, HIT); endaction
action p.reportAccess('h90000190, 'h006a, HIT); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000150, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000110, "test fail!");
endaction
action p.reportAccess('h90000100, 'h006b, MISS); endaction
action p.reportAccess('h90000200, 'h006b, MISS); endaction
action p.reportAccess('h90000300, 'h006b, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000400, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000500, "test fail!");
endaction
action p.reportAccess('h90000160, 'h006a, HIT); endaction
// -- use older entry
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000e0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000a0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000600, "test fail!");
endaction
endseq
);
endmodule
module mkBRAMStridePCPrefetcherTest(Empty);
let p <- mkBRAMStridePCPrefetcher;
mkAutoFSM(
@@ -734,6 +371,109 @@ module mkBRAMStridePCPrefetcherTest(Empty);
);
endmodule
module mkBRAMStrideAdaptivePCPrefetcherTest(Empty);
let p <- mkBRAMStrideAdaptivePCPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action $display("%t", $time); p.reportAccess('h80000040, 'h0069, MISS); endaction
action p.reportAccess('h80000080, 'h0069, HIT); endaction
action p.reportAccess('h800000a0, 'h0069, HIT); endaction
action p.reportAccess('h800000c0, 'h0069, MISS); endaction
action p.reportAccess('h800000e0, 'h0069, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000100, "test fail!");
endaction
action p.reportAccess('h80000100, 'h0069, HIT); endaction
action p.reportAccess('h80000120, 'h0069, HIT); endaction
action p.reportAccess('h80000140, 'h0069, HIT); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000140, "test fail!");
endaction
action endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000180, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800001c0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000200, "test fail!");
endaction
action p.reportAccess('h900001f0, 'h006a, MISS); endaction
action p.reportAccess('h900001c0, 'h006a, HIT); endaction
action p.reportAccess('h90000190, 'h006a, HIT); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000240, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000280, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000150, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000110, "test fail!");
endaction
action p.reportAccess('h90000100, 'h006b, MISS); endaction
action p.reportAccess('h90000200, 'h006b, MISS); endaction
action p.reportAccess('h90000300, 'h006b, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000400, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000500, "test fail!");
endaction
action p.reportAccess('h90000160, 'h006a, HIT); endaction
// -- use older entry
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000e0, "test fail!");
endaction
action p.reportAccess('h80000080, 'h0069, MISS); endaction
//Tolerate broken stride, request again
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800000c0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000100, "test fail!");
endaction
action p.reportAccess('h80000088, 'h0069, MISS); endaction
action p.reportAccess('h80000090, 'h0069, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800000d0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000110, "test fail!");
endaction
action p.reportAccess('h80000098, 'h0069, MISS); endaction
action p.reportAccess('h800000a0, 'h0069, MISS); endaction
action p.reportAccess('h800000a8, 'h0069, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000168, "test fail!");
endaction
action p.reportAccess('h800000b0, 'h0069, MISS); endaction
action p.reportAccess('h800000b8, 'h0069, MISS); endaction
endseq
);
endmodule
module mkBRAMMarkovPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
@@ -781,54 +521,6 @@ module mkBRAMMarkovPrefetcherTest(Empty);
endseq
);
endmodule
module mkMarkovPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkMarkovPrefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.reportAccess('h80000000, MISS);
endaction
action
p.reportAccess('h80000700, MISS);
endaction
action
p.reportAccess('h90000000, MISS);
endaction
action
p.reportAccess('ha0000000, MISS);
endaction
action
p.reportAccess('h80000000, HIT); //back to start
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000700, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000000, "test fail!");
endaction
action
p.reportAccess('h80000700, HIT);
endaction
action
p.reportAccess('ha0000000, HIT);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000000, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000700, "test fail!");
endaction
endseq
);
endmodule
module mkOverflowPipelineFifoTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
Fifo#(4, Bit#(8)) p <- mkOverflowPipelineFifo;