Files
Toooba/src_Testbench/Unit/Prefetcher_test.bsv
2023-05-23 13:37:43 +01:00

1129 lines
41 KiB
Plaintext

// Copyright (c) 2023 Karlis Susters
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import Prefetcher::*;
import RWBramCore::*;
import StmtFSM::*;
import Types::*;
import Fifos::*;
module mkTargetTableTest(Empty);
TargetTable#(64, 16) t <- mkTargetTable;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
t.set('h8000, 'h800a); // goes in short table
endaction
action
t.set('h8000, 'h80008000); // goes in long table
endaction
action
let x <- t.getAndRemove('h8000); // comes from short table
doAssert(x == Valid('h800a), "test fail!");
endaction
action
let x <- t.getAndRemove('h8000); // comes from long table
doAssert(x == Valid('h80008000), "test fail!");
endaction
action
t.set('h80000000, 'h21230000); // goes in long table
endaction
action
let x <- t.getAndRemove('h80000000); // comes from long table
doAssert(x == Valid('h21230000), "test fail!");
endaction
action
t.set('h7000, 'h6fde); // goes in short table backwards
endaction
action
let x <- t.getAndRemove('h7000); // get from short table
doAssert(x == Valid('h6fde), "test fail!");
endaction
action
let x <- t.getAndRemove('h7000); // get from short table
doAssert(x == Invalid, "test fail!"); //entry was removed!
endaction
endseq
);
endmodule
module mkTargetTableBRAMTest(Empty);
TargetTableBRAM#(64, 16) t <- mkTargetTableBRAM;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
t.writeReq('h8000, 'h800a); // goes in short table
endaction
action
t.writeReq('h8000, 'h80008000); // goes in long table
endaction
action
t.readReq('h8000); // comes from short table
endaction
action
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.readResp(True); // comes from long table
doAssert(x == Valid('h80008000), "test fail!");
endaction
action
t.writeReq('h80000000, 'h21230000); // goes in long table
endaction
action
t.readReq('h80000000); // comes from long table
endaction
action
let x <- t.readResp(True); // comes from long table
doAssert(x == Valid('h21230000), "test fail!");
endaction
action
t.writeReq('h7000, 'h6fde); // goes in short table backwards
endaction
action
t.readReq('h7000); // get from short table
endaction
action
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.readResp(True); // get from short table
doAssert(x == Invalid, "test fail!"); //entry was removed!
endaction
endseq
);
endmodule
module mkTargetTableDoubleTest(Empty);
TargetTableDouble#(2048, 128) t <- mkTargetTableDouble;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
t.sendReadWriteReq('h8000, MISS); // goes in short table
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h800a, MISS); // goes in short table
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8080000b, MISS); // goes in long table
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS); // comes from short table
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h800a), Invalid), "test fail!");
endaction
action
t.sendReadWriteReq('h800a, MISS); // comes from long table
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h8080000b), Invalid), "test fail!");
endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h2123000c, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, HIT);
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h2123000c), Valid('h800a)), "test fail!");
endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h2123000c, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h2123000c), Valid('h800a)), "test fail!");
endaction
/// ---- Add third entry (narrow) 8003
action
t.sendReadWriteReq('h8003, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
//wide entry is moved to LRU
let x <- t.readResp();
doAssert(x == tuple2(Valid('h8003), Valid('h2123000c)), "test fail!");
endaction
action
t.sendReadWriteReq('h8003, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h8003), Valid('h2123000c)), "test fail!");
endaction
//refresh 21230000
action
t.sendReadWriteReq('h2123000c, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h2123000c), Valid('h8003)), "test fail!");
endaction
/// ---- Add another entry (wide) 2123000d
action
t.sendReadWriteReq('h2123000d, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
//wide entry is moved to LRU
let x <- t.readResp();
doAssert(x == tuple2(Valid('h2123000d), Valid('h2123000c)), "test fail!");
endaction
/// ---- Add fifth entry (narrow) 8004
action
t.sendReadWriteReq('h8004, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
//wide entry is moved to LRU
let x <- t.readResp();
doAssert(x == tuple2(Valid('h8004), Valid('h2123000d)), "test fail!");
endaction
// --- Add a sixth narrow entry 8005
action
t.sendReadWriteReq('h8005, MISS);
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h8000, MISS);
endaction
action
//wide entry is moved to LRU
let x <- t.readResp();
doAssert(x == tuple2(Valid('h8005), Valid('h8004)), "test fail!");
endaction
action
t.sendReadWriteReq('h7004, MISS); // get from short table
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Invalid, Invalid), "test fail!");
endaction
action
t.sendReadWriteReq('h6fde, MISS); // get from short table
endaction
action let x <- t.readResp(); endaction
action
t.sendReadWriteReq('h7004, MISS); // get from short table
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Valid('h6fde), Invalid), "test fail!");
endaction
action
t.sendReadWriteReq('h200, HIT); // get from short table
endaction
action
let x <- t.readResp();
doAssert(x == tuple2(Invalid, Invalid), "test fail!"); //entry was removed!
endaction
endseq
);
endmodule
module mkBRAMMultiWindowTargetPrefetcherTest(Empty);
let p <- mkBRAMMultiWindowTargetPrefetcher;
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;
doAssert(x == 'h800001c0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr; //target address recommended
doAssert(x == 'h50000000, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000200, "test fail!"); // window addresss recommended
endaction
endseq
);
endmodule
module mkBRAMSingleWindowTargetPrefetcherTest(Empty);
//2 ahead
//remember last 2 target table requests.
let p <- mkBRAMSingleWindowTargetPrefetcher;
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('h81000200, MISS); //Report miss somewhere far away
endaction
action
let x <- p.getNextPrefetchAddr; //New window allocated and recommended
doAssert(x == 'h81000240, "test fail!");
endaction
action
p.reportAccess('h80000180, MISS); //Report miss back home
endaction
action endaction
action
p.reportAccess('h82000000, MISS); //Report miss far away 2
endaction
action
p.reportAccess('h80000140, MISS); //Report miss back home
endaction
action
let x <- p.getNextPrefetchAddr; //target address recommended
doAssert(x == 'h81000200, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000180, "test fail!"); // window addresss recommended
endaction
action
p.reportAccess('h80000140, HIT); //Report miss back home
endaction
action
p.reportAccess('h81000200, HIT);
endaction
action
p.reportAccess('h80000140, HIT); //overwrite last target entry
endaction
action
let x <- p.getNextPrefetchAddr; //target addresss recommended
doAssert(x == 'h81000200, "test fail!");
endaction
endseq
);
endmodule
module mkBRAMStridePCPrefetcherTest(Empty);
let p <- mkBRAMStridePCPrefetcher;
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 == '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 == 'h900000d0, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000400, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000500, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h90000600, "test fail!");
endaction
action p.reportAccess('h90000160, 'h006a, HIT); endaction
// -- use older entry
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000a0, "test fail!");
endaction
endseq
);
endmodule
module mkBRAMStrideAdaptivePCPrefetcherTest(Empty);
// config is 2 - 3 - 5
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 mkMarkovOnHit2PrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkMarkovOnHit2Prefetcher;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.reportAccess('h80010000, MISS);
endaction
action
p.reportAccess('h80010700, MISS);
endaction
action
p.reportAccess('h90010000, MISS);
endaction
action
p.reportAccess('ha0010300, MISS);
endaction
action
p.reportAccess('h80010000, MISS); //back to start
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80010700, "test fail!");
endaction
//Add second target
action
p.reportAccess('h80010900, MISS);
endaction
action
p.reportAccess('h80010000, MISS); //back to start
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80010900, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80010700, "test fail!");
endaction
action
p.reportAccess('ha0010300, MISS);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80010000, "test fail!");
endaction
action
p.reportAccess('ha0010200, MISS);
endaction
action
p.reportAccess('ha0010300, MISS);
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'ha0010200, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80010000, "test fail!");
endaction
endseq
);
endmodule
module mkBRAMMarkovPrefetcherTest(Empty);
//let p <- mkMultipleWindowPrefetcher;
//TODO pass in value of cachelinesinrange
let p <- mkBRAMMarkovPrefetcher;
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;
mkAutoFSM(
seq
// ----- Send misses and stuff to one window -----
action
p.enq('h01);
endaction
action
p.enq('h02);
endaction
action
p.enq('h03);
endaction
action
p.enq('h04);
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h01, "test fail!");
endaction
action
p.enq('h05);
let x = p.first;
p.deq;
doAssert(x == 'h02, "test fail!");
endaction
action
p.enq('h06);
endaction
action
p.enq('h07);
let x = p.first;
p.deq;
doAssert(x == 'h03, "test fail!");
endaction
action
p.enq('h08);
endaction
action
p.enq('h09);
let x = p.first;
p.deq;
doAssert(x == 'h05, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h06, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h07, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h08, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h09, "test fail!");
endaction
action
doAssert(!p.notEmpty, "test fail!");
endaction
action
$display("test done!");
endaction
endseq
);
endmodule
module mkOverflowBypassFifoTest(Empty);
Fifo#(4, Bit#(8)) p <- mkOverflowBypassFifo;
mkAutoFSM(
seq
action
p.enq('h01);
endaction
action
p.enq('h02);
endaction
action
p.enq('h03);
endaction
action
p.enq('h04);
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h01, "test fail!");
endaction
action
p.enq('h05);
let x = p.first;
p.deq;
doAssert(x == 'h02, "test fail!");
endaction
action
p.enq('h06);
endaction
action
p.enq('h07);
let x = p.first;
p.deq;
$display("found %x", x);
doAssert(x == 'h04, "test fail!");
endaction
action
p.enq('h08);
endaction
action
p.enq('h09);
let x = p.first;
p.deq;
doAssert(x == 'h06, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h07, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h08, "test fail!");
endaction
action
let x = p.first;
p.deq;
doAssert(x == 'h09, "test fail!");
endaction
action
doAssert(!p.notEmpty, "test fail!");
endaction
action
$display("test done!");
endaction
endseq
);
endmodule
module mkStride2PCPrefetcherTest(Empty);
//paremeter - 2 ahead
let p <- mkStride2PCPrefetcher;
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 == '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 == 'h80000160, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000180, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h800001c0, "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 p.reportAccess('h90000160, '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
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000e0, "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('ha0000420, 'h006b, MISS); endaction
action p.reportAccess('ha0000520, 'h006b, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'ha0000620, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'ha0000720, "test fail!");
endaction
action p.reportAccess('h90000130, 'h006a, HIT); endaction
// -- use older entry
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000b0, "test fail!");
endaction
// -- test blocking on page boundaries
action p.reportAccess('ha0000000, 'h006c, MISS); endaction
action p.reportAccess('ha0000400, 'h006c, MISS); endaction
action p.reportAccess('ha0000800, 'h006c, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'ha0000c00, "test fail!");
endaction
action p.reportAccess('ha0000c00, 'h006c, MISS); endaction
action p.reportAccess('hb0000000, 'h006c, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'hb0000400, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'hb0000800, "test fail!");
endaction
endseq
);
endmodule
module mkPrefetcherVectorTest(Empty);
//config - 2 lines
PrefetcherVector#(3) p <- mkPrefetcherVector(mkNextLineOnMissPrefetcher);
mkAutoFSM(
seq
action p.reportAccess(1, 'h90000000, MISS); endaction
action p.reportAccess(0, 'h80000000, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h90000040, 1), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h90000080, 1), "test fail!");
endaction
action p.reportAccess(0, 'h40000000, MISS); endaction
action p.reportAccess(1, 'h50000000, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h80000040, 0), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h40000040, 0), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h50000040, 1), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h40000080, 0), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('h50000080, 1), "test fail!");
endaction
action p.reportAccess(2, 'ha0000000, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('ha0000040, 2), "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
$display("%t Got %x", $time, x);
doAssert(x == tuple2('ha0000080, 2), "test fail!");
endaction
endseq
);
endmodule
module mkSimpleStridePCPrefetcherTest(Empty);
//paremeter - 2 ahead
let p <- mkSimpleStridePCPrefetcher;
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 == 'h80000120, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000160, "test fail!");
endaction
action p.reportAccess('h80000400, 'h0069, MISS); endaction
action p.reportAccess('h80000300, 'h0069, MISS); endaction
action p.reportAccess('h80000200, 'h0069, MISS); endaction
action p.reportAccess('h80000100, 'h0069, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h80000000, "test fail!");
endaction
endseq
);
endmodule