From a2b80100e204d7382dee1ddb3b33ac36c8d3a731 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 1 Nov 2017 01:47:23 -0700 Subject: [PATCH] Make PseudoLRU policy support non-power-of-2 sizes --- src/main/scala/util/Replacement.scala | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/scala/util/Replacement.scala b/src/main/scala/util/Replacement.scala index 1509a276..9a2d28d0 100644 --- a/src/main/scala/util/Replacement.scala +++ b/src/main/scala/util/Replacement.scala @@ -38,45 +38,47 @@ class SeqRandom(n_ways: Int) extends SeqReplacementPolicy { class PseudoLRU(n: Int) { - require(isPow2(n)) - val state_reg = Reg(Bits(width = n)) + private val state_reg = Reg(UInt(width = n-1)) def access(way: UInt) { state_reg := get_next_state(state_reg,way) } def get_next_state(state: UInt, way: UInt) = { - var next_state = state + var next_state = state << 1 var idx = UInt(1,1) for (i <- log2Up(n)-1 to 0 by -1) { val bit = way(i) next_state = next_state.bitSet(idx, !bit) idx = Cat(idx, bit) } - next_state + next_state(n-1, 1) } def replace = get_replace_way(state_reg) - def get_replace_way(state: Bits) = { + def get_replace_way(state: UInt) = { + val shifted_state = state << 1 var idx = UInt(1,1) - for (i <- 0 until log2Up(n)) - idx = Cat(idx, state(idx)) + for (i <- log2Up(n)-1 to 0 by -1) { + val in_bounds = Cat(idx, UInt(BigInt(1) << i))(log2Up(n)-1, 0) < UInt(n) + idx = Cat(idx, in_bounds && shifted_state(idx)) + } idx(log2Up(n)-1,0) } } class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy { - val state = SeqMem(n_sets, Bits(width = n_ways-1)) + val state = SeqMem(n_sets, UInt(width = n_ways-1)) val logic = new PseudoLRU(n_ways) - val current_state = Wire(Bits()) + val current_state = Wire(UInt()) val plru_way = logic.get_replace_way(current_state) - val next_state = Wire(Bits()) + val next_state = Wire(UInt()) def access(set: UInt) = { - current_state := Cat(state.read(set), Bits(0, width = 1)) + current_state := state.read(set) } def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { val update_way = Mux(hit, way, plru_way) next_state := logic.get_next_state(current_state, update_way) - when (valid) { state.write(set, next_state(n_ways-1,1)) } + when (valid) { state.write(set, next_state) } } def way = plru_way