1
0

Make PseudoLRU policy support non-power-of-2 sizes

This commit is contained in:
Andrew Waterman 2017-11-01 01:47:23 -07:00
parent 9e77045213
commit a2b80100e2

View File

@ -38,45 +38,47 @@ class SeqRandom(n_ways: Int) extends SeqReplacementPolicy {
class PseudoLRU(n: Int) class PseudoLRU(n: Int)
{ {
require(isPow2(n)) private val state_reg = Reg(UInt(width = n-1))
val state_reg = Reg(Bits(width = n))
def access(way: UInt) { def access(way: UInt) {
state_reg := get_next_state(state_reg,way) state_reg := get_next_state(state_reg,way)
} }
def get_next_state(state: UInt, way: UInt) = { def get_next_state(state: UInt, way: UInt) = {
var next_state = state var next_state = state << 1
var idx = UInt(1,1) var idx = UInt(1,1)
for (i <- log2Up(n)-1 to 0 by -1) { for (i <- log2Up(n)-1 to 0 by -1) {
val bit = way(i) val bit = way(i)
next_state = next_state.bitSet(idx, !bit) next_state = next_state.bitSet(idx, !bit)
idx = Cat(idx, bit) idx = Cat(idx, bit)
} }
next_state next_state(n-1, 1)
} }
def replace = get_replace_way(state_reg) 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) var idx = UInt(1,1)
for (i <- 0 until log2Up(n)) for (i <- log2Up(n)-1 to 0 by -1) {
idx = Cat(idx, state(idx)) 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) idx(log2Up(n)-1,0)
} }
} }
class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy { 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 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 plru_way = logic.get_replace_way(current_state)
val next_state = Wire(Bits()) val next_state = Wire(UInt())
def access(set: 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) = { def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = {
val update_way = Mux(hit, way, plru_way) val update_way = Mux(hit, way, plru_way)
next_state := logic.get_next_state(current_state, update_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 def way = plru_way