diff --git a/src_Core/RISCY_OOO/coherence/src/Prefetcher.bsv b/src_Core/RISCY_OOO/coherence/src/Prefetcher.bsv index 1b58f1e..1833427 100644 --- a/src_Core/RISCY_OOO/coherence/src/Prefetcher.bsv +++ b/src_Core/RISCY_OOO/coherence/src/Prefetcher.bsv @@ -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 diff --git a/src_Core/RISCY_OOO/coherence/src/test/Prefetcher_test.bsv b/src_Core/RISCY_OOO/coherence/src/test/Prefetcher_test.bsv index 97da0be..7c93a0c 100644 --- a/src_Core/RISCY_OOO/coherence/src/test/Prefetcher_test.bsv +++ b/src_Core/RISCY_OOO/coherence/src/test/Prefetcher_test.bsv @@ -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;