with m.If(~r0_stall):
sync += tlb_way.eq(dtlb[index])
- def maybe_tlb_plrus(self, m, r1, tlb_plru_victim):
+ def maybe_tlb_plrus(self, m, r1, tlb_plru_victim, tlb_req_index):
"""Generate TLB PLRUs
"""
comb = m.d.comb
return
# Binary-to-Unary one-hot, enabled by tlb_hit valid
- tlb_plrus = PLRUs(TLB_SET_SIZE, TLB_WAY_BITS, tlb_plru_victim)
+ tlb_plrus = PLRUs(TLB_SET_SIZE, TLB_WAY_BITS)
m.submodules.tlb_plrus = tlb_plrus
comb += tlb_plrus.way.eq(r1.tlb_hit.way)
comb += tlb_plrus.valid.eq(r1.tlb_hit.valid)
comb += tlb_plrus.index.eq(r1.tlb_hit_index)
+ comb += tlb_plrus.isel.eq(tlb_req_index) # select victim
+ comb += tlb_plru_victim.eq(tlb_plrus.o_index) # selected victim
def tlb_search(self, m, tlb_req_index, r0, r0_valid,
tlb_way,
with m.If(tlb_hit.valid):
comb += d.repl_way.eq(tlb_hit.way)
with m.Else():
- comb += d.repl_way.eq(tlb_plru_victim[tlb_req_index])
+ comb += d.repl_way.eq(tlb_plru_victim)
comb += d.eatag.eq(r0.req.addr[TLB_LG_PGSZ + TLB_SET_BITS:64])
comb += d.pte_data.eq(r0.req.data)
if TLB_NUM_WAYS == 0:
return
- m.submodules.plrus = plrus = PLRUs(NUM_LINES, WAY_BITS, plru_victim)
+ m.submodules.plrus = plrus = PLRUs(NUM_LINES, WAY_BITS)
comb += plrus.way.eq(r1.hit_way)
comb += plrus.valid.eq(r1.cache_hit)
comb += plrus.index.eq(r1.hit_index)
+ comb += plrus.isel.eq(r1.store_index) # select victim
+ comb += plru_victim.eq(plrus.o_index) # selected victim
def cache_tag_read(self, m, r0_stall, req_index, cache_tag_set, cache_tags):
"""Cache tag RAM read port
# The way to replace on a miss
with m.If(r1.write_tag):
- comb += replace_way.eq(plru_victim[r1.store_index])
+ comb += replace_way.eq(plru_victim)
with m.Else():
comb += replace_way.eq(r1.store_way)
cache_out_row = Signal(WB_DATA_BITS)
- plru_victim = PLRUOut()
+ plru_victim = Signal(WAY_BITS)
replace_way = Signal(WAY_BITS)
# Wishbone read/write/cache write formatting signals
perm_ok = Signal()
access_ok = Signal()
- tlb_plru_victim = TLBPLRUOut()
+ tlb_plru_victim = Signal(TLB_WAY_BITS)
# we don't yet handle collisions between loadstore1 requests
# and MMU requests
tlb_hit, tlb_plru_victim,
tlb_way)
self.maybe_plrus(m, r1, plru_victim)
- self.maybe_tlb_plrus(m, r1, tlb_plru_victim)
+ self.maybe_tlb_plrus(m, r1, tlb_plru_victim, tlb_req_index)
self.cache_tag_read(m, r0_stall, req_index, cache_tag_set, cache_tags)
self.dcache_request(m, r0, ra, req_index, req_row, req_tag,
r0_valid, r1, cache_tags, replace_way,
if NUM_WAYS == 0:
return
- m.submodules.plrus = plru = PLRUs(NUM_LINES, WAY_BITS, plru_victim)
+
+ m.submodules.plrus = plru = PLRUs(NUM_LINES, WAY_BITS)
comb += plru.way.eq(r.hit_way)
comb += plru.valid.eq(r.hit_valid)
comb += plru.index.eq(get_index(r.hit_nia))
+ comb += plru.isel.eq(r.store_index) # select victim
+ comb += plru_victim.eq(plru.o_index) # selected victim
# TLB hit detection and real address generation
def itlb_lookup(self, m, tlb_req_index, itlb,
# The way to replace on a miss
with m.If(r.state == State.CLR_TAG):
- comb += replace_way.eq(plru_victim[r.store_index])
+ comb += replace_way.eq(plru_victim)
with m.Else():
comb += replace_way.eq(r.store_way)
cache_out_row = Signal(ROW_SIZE_BITS)
- plru_victim = PLRUOut()
+ plru_victim = Signal(WAY_BITS)
replace_way = Signal(WAY_BITS)
# fake-up the wishbone stall signal to comply with pipeline mode
class PLRUs(Elaboratable):
- def __init__(self, n_plrus, n_bits, out=None):
+ def __init__(self, n_plrus, n_bits):
self.n_plrus = n_plrus
self.n_bits = n_bits
self.valid = Signal()
self.way = Signal(n_bits)
self.index = Signal(n_plrus.bit_length())
- if out is None:
- out = Array(Signal(n_bits, name="plru_out%d" % x) \
- for x in range(n_plrus))
- self.out = out
+ self.isel = Signal(n_plrus.bit_length())
+ self.o_index = Signal(n_bits)
def elaborate(self, platform):
"""Generate TLB PLRUs
comb += te.n.eq(~self.valid)
comb += te.i.eq(self.index)
+ out = Array(Signal(self.n_bits, name="plru_out%d" % x) \
+ for x in range(self.n_plrus))
+
for i in range(self.n_plrus):
# PLRU interface
m.submodules["plru_%d" % i] = plru = PLRU(self.n_bits)
comb += plru.acc_en.eq(te.o[i])
comb += plru.acc_i.eq(self.way)
- comb += self.out[i].eq(plru.lru_o)
+ comb += out[i].eq(plru.lru_o)
+
+ # select output based on index
+ comb += self.o_index.eq(out[self.isel])
return m
def ports(self):
- return [self.valid, self.way, self.index] + list(self.out)
+ return [self.valid, self.way, self.index, self.isel, self.o_index]
if __name__ == '__main__':