From d32c6c0d1d71dfa10d6b5b04e4712315431dbd27 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 6 Dec 2021 17:00:29 +0000 Subject: [PATCH] PLRUs were selecting an output index, only one selected therefore move the selection from the PLRUs into the module. simplified --- src/soc/experiment/dcache.py | 20 ++++++++++++-------- src/soc/experiment/icache.py | 9 ++++++--- src/soc/experiment/plru.py | 18 +++++++++++------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/soc/experiment/dcache.py b/src/soc/experiment/dcache.py index bf14e18d..a32456c8 100644 --- a/src/soc/experiment/dcache.py +++ b/src/soc/experiment/dcache.py @@ -688,7 +688,7 @@ class DCache(Elaboratable): 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 @@ -698,11 +698,13 @@ class DCache(Elaboratable): 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, @@ -800,7 +802,7 @@ class DCache(Elaboratable): 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) @@ -813,10 +815,12 @@ class DCache(Elaboratable): 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 @@ -916,7 +920,7 @@ class DCache(Elaboratable): # 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) @@ -1636,7 +1640,7 @@ class DCache(Elaboratable): 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 @@ -1654,7 +1658,7 @@ class DCache(Elaboratable): 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 @@ -1689,7 +1693,7 @@ class DCache(Elaboratable): 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, diff --git a/src/soc/experiment/icache.py b/src/soc/experiment/icache.py index 56f69c39..845ed5ec 100644 --- a/src/soc/experiment/icache.py +++ b/src/soc/experiment/icache.py @@ -384,10 +384,13 @@ class ICache(Elaboratable): 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, @@ -519,7 +522,7 @@ class ICache(Elaboratable): # 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) @@ -815,7 +818,7 @@ class ICache(Elaboratable): 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 diff --git a/src/soc/experiment/plru.py b/src/soc/experiment/plru.py index 1812af6e..92b8fc14 100644 --- a/src/soc/experiment/plru.py +++ b/src/soc/experiment/plru.py @@ -55,16 +55,14 @@ class PLRU(Elaboratable): 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 @@ -80,18 +78,24 @@ class PLRUs(Elaboratable): 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__': -- 2.30.2