From 360ccd92698f39160f639524083e442b9ef34778 Mon Sep 17 00:00:00 2001 From: Sindre Stephansen Date: Fri, 22 Nov 2019 16:00:05 +0100 Subject: [PATCH] Implement profiling tests --- src/test/scala/RISCV/testRunner.scala | 100 +++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/src/test/scala/RISCV/testRunner.scala b/src/test/scala/RISCV/testRunner.scala index 3d9d60c..33b0bbb 100644 --- a/src/test/scala/RISCV/testRunner.scala +++ b/src/test/scala/RISCV/testRunner.scala @@ -165,7 +165,48 @@ object TestRunner { helper(events, initState) } + /** + * This is profiler for a 2-bit 8-slot branch predictor. + */ + def TwoBitEightSlots(events: List[BranchEvent]): Int = { + // Uncomment to take a look at the event log + // say(events.mkString("\n","\n","\n")) + + // Helper inspects the next element of the event list. If the event is a mispredict the prediction table is updated + // to reflect this. + // As long as there are remaining events the helper calls itself recursively on the remainder + def helper(events: List[BranchEvent], predictionTable: Map[Int, Int]): Int = { + events match { + case Taken(from, to) :: t if(predictionTable(hash(from)) == 0) => 1 + helper(t, predictionTable.updated(hash(from), 1)) + case Taken(from, to) :: t if(predictionTable(hash(from)) == 1) => 1 + helper(t, predictionTable.updated(hash(from), 2)) + case Taken(from, to) :: t if(predictionTable(hash(from)) == 2) => helper(t, predictionTable.updated(hash(from), 3)) + case Taken(from, to) :: t if(predictionTable(hash(from)) == 3) => helper(t, predictionTable) + case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 0) => helper(t, predictionTable) + case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 1) => helper(t, predictionTable.updated(hash(addr), 0)) + case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 2) => 1 + helper(t, predictionTable.updated(hash(addr), 1)) + case NotTaken(addr) :: t if(predictionTable(hash(addr)) == 3) => 1 + helper(t, predictionTable.updated(hash(addr), 2)) + case Nil => 0 + } + } + + def hash(addr: Int): Int = addr.getTag(8) + + def initState = Map( + 0 -> 0, + 1 -> 0, + 2 -> 0, + 3 -> 0, + 4 -> 0, + 5 -> 0, + 6 -> 0, + 7 -> 0, + ) + + helper(events, initState) + } + say(OneBitInfiniteSlots(events)) + say(TwoBitEightSlots(events)) } @@ -190,9 +231,66 @@ object TestRunner { case MemRead(x,_) => Read(x.value) } - // Your cache here + case class CacheEntry(var tag: Int, var lru: Boolean) + type Cache = Map[Int, List[CacheEntry]] + + /** + * This is profiler for a 2-way associative 4 word cache + */ + def TwoWayFourWord(events: List[MemoryEvent]): Int = { + def helper(events: List[MemoryEvent], cache: Cache): Int = { + events match { + case Write(addr) :: t => helper(t, cache) + case Read(addr) :: t if( inCache(addr, cache)) => 1+helper(t, useCache(addr, cache)) + case Read(addr) :: t if(!inCache(addr, cache)) => helper(t, addToCache(addr, cache)) + case Nil => say(cache); 0 + } + } + + def getIndex(addr: Int): Int = addr.getTag(2) + def getTag(addr: Int): Int = addr >>> 3 + + def inCache(addr: Int, cache: Cache): Boolean = { + cache(getIndex(addr))(0).tag == getTag(addr) || cache(getIndex(addr))(1).tag == getTag(addr) + } + + def useCache(addr: Int, cache: Cache): Cache = { + if (cache(getIndex(addr))(0).tag == getTag(addr)) { + cache(getIndex(addr))(0).lru = false + cache(getIndex(addr))(1).lru = true + } else { + cache(getIndex(addr))(1).lru = false + cache(getIndex(addr))(0).lru = true + } + + cache + } + + def addToCache(addr: Int, cache: Cache): Cache = { + if (cache(getIndex(addr))(0).lru) { + cache(getIndex(addr))(0).tag = getTag(addr) + cache(getIndex(addr))(0).lru = false + cache(getIndex(addr))(1).lru = true + } else { + cache(getIndex(addr))(1).tag = getTag(addr) + cache(getIndex(addr))(1).lru = false + cache(getIndex(addr))(0).lru = true + } + + cache + } + def initState = Map( + 0 -> List(CacheEntry(-1, true), CacheEntry(-1, true)), + 1 -> List(CacheEntry(-1, true), CacheEntry(-1, true)), + ) + + helper(events, initState) + } + + say(TwoWayFourWord(events)) } + true } }