From 3895b75a560f6a337b4822e0b283115b9aed53b1 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 24 Aug 2013 17:33:11 -0700 Subject: [PATCH] Support non-power-of-2 BTBs; prefer invalid entries --- rocket/src/main/scala/dpath_util.scala | 16 +++++++++------- rocket/src/main/scala/util.scala | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index 6e3d00a9..127ac851 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -23,27 +23,29 @@ class rocketDpathBTB(entries: Int) extends Module { val io = new DpathBTBIO - val repl_way = LFSR16(io.wen)(log2Up(entries)-1,0) // TODO: pseudo-LRU - var hit_reduction = Bool(false) val hit = Bool() val update = Bool() var update_reduction = Bool(false) + val valid = Vec.fill(entries){Reg(init=Bool(false))} val hits = Vec.fill(entries){Bool()} val updates = Vec.fill(entries){Bool()} val targets = Vec.fill(entries){Reg(UInt())} val anyUpdate = updates.toBits.orR + val random_way = Random(entries, io.wen) + val invalid_way = valid.indexWhere((x: Bool) => !x) + val repl_way = Mux(valid.contains(Bool(false)), invalid_way, random_way) + for (i <- 0 until entries) { val tag = Reg(UInt()) - val valid = Reg(init=Bool(false)) - hits(i) := valid && tag === io.current_pc - updates(i) := valid && tag === io.correct_pc + hits(i) := valid(i) && tag === io.current_pc + updates(i) := valid(i) && tag === io.correct_pc when (io.wen && (updates(i) || !anyUpdate && UInt(i) === repl_way)) { - valid := Bool(false) + valid(i) := Bool(false) when (!io.clr) { - valid := Bool(true) + valid(i) := Bool(true) tag := io.correct_pc targets(i) := io.correct_target } diff --git a/rocket/src/main/scala/util.scala b/rocket/src/main/scala/util.scala index 9b735f1d..b99d3d43 100644 --- a/rocket/src/main/scala/util.scala +++ b/rocket/src/main/scala/util.scala @@ -130,3 +130,21 @@ case class WideCounter(width: Int, inc: Bool = Bool(true)) if (isWide) large := (if (w < smallWidth) UInt(0) else x(w.min(width)-1,smallWidth)) } } + +object Random +{ + def apply(mod: Int, inc: Bool = Bool(true)): UInt = { + if (isPow2(mod)) { + require(mod <= 65536) + LFSR16(inc)(log2Up(mod)-1,0).toUInt + } else { + val max = 1 << log2Up(mod*8) + val rand_pow2 = apply(max, inc) + + var res = UInt(mod-1) + for (i <- mod-1 to 1 by -1) + res = Mux(rand_pow2 < UInt(i*max/mod), UInt(i-1), res) + res + } + } +}