From: Luke Kenneth Casson Leighton Date: Mon, 6 Dec 2021 15:45:40 +0000 (+0000) Subject: move bank of PLRUs to their own submodule in both dcache.py and icache.py X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9047bcb369ec804733bb1c595a2e203dc0e22588;p=soc.git move bank of PLRUs to their own submodule in both dcache.py and icache.py --- diff --git a/src/soc/experiment/dcache.py b/src/soc/experiment/dcache.py index 7fc94be4..04c19745 100644 --- a/src/soc/experiment/dcache.py +++ b/src/soc/experiment/dcache.py @@ -50,7 +50,7 @@ from soc.experiment.wb_types import (WB_ADDR_BITS, WB_DATA_BITS, WB_SEL_BITS, from soc.experiment.cache_ram import CacheRam #from soc.experiment.plru import PLRU -from nmutil.plru import PLRU +from nmutil.plru import PLRU, PLRUs # for test from soc.bus.sram import SRAM @@ -698,20 +698,11 @@ class DCache(Elaboratable): return # Binary-to-Unary one-hot, enabled by tlb_hit valid - m.submodules.tlb_hit_e = te = Decoder(TLB_SET_SIZE) - comb += te.n.eq(~r1.tlb_hit.valid) - comb += te.i.eq(r1.tlb_hit_index) - - for i in range(TLB_SET_SIZE): - # TLB PLRU interface - tlb_plru = PLRU(TLB_WAY_BITS) - setattr(m.submodules, "maybe_plru_%d" % i, tlb_plru) - tlb_plru_acc_en = Signal() - - comb += tlb_plru_acc_en.eq(te.o[i]) - comb += tlb_plru.acc_en.eq(tlb_plru_acc_en) - comb += tlb_plru.acc_i.eq(r1.tlb_hit.way) - comb += tlb_plru_victim[i].eq(tlb_plru.lru_o) + tlb_plrus = PLRUs(TLB_SET_SIZE, TLB_WAY_BITS, tlb_plru_victim) + 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) def tlb_search(self, m, tlb_req_index, r0, r0_valid, tlb_way, @@ -822,22 +813,10 @@ class DCache(Elaboratable): if TLB_NUM_WAYS == 0: return - # XXX TODO: use a Binary-to-Unary one-hot here, - # enabled by cache_hit - m.submodules.hit_e = he = Decoder(NUM_LINES) - comb += he.n.eq(~r1.cache_hit) - comb += he.i.eq(r1.hit_index) - - for i in range(NUM_LINES): - # PLRU interface - plru = PLRU(WAY_BITS) - m.submodules["plru%d" % i] = plru - plru_acc_en = Signal() - - comb += plru_acc_en.eq(he.o[i]) - comb += plru.acc_en.eq(plru_acc_en) - comb += plru.acc_i.eq(r1.hit_way) - comb += plru_victim[i].eq(plru.lru_o) + m.submodules.plrus = plrus = PLRUs(NUM_LINES, WAY_BITS, plru_victim) + comb += plrus.way.eq(r1.hit_way) + comb += plrus.valid.eq(r1.cache_hit) + comb += plrus.index.eq(r1.hit_index) def cache_tag_read(self, m, r0_stall, req_index, cache_tag_set, cache_tags): """Cache tag RAM read port diff --git a/src/soc/experiment/icache.py b/src/soc/experiment/icache.py index 226b8da3..393bb712 100644 --- a/src/soc/experiment/icache.py +++ b/src/soc/experiment/icache.py @@ -29,8 +29,8 @@ from nmigen.lib.coding import Decoder from nmutil.util import Display #from nmutil.plru import PLRU +from soc.experiment.plru import PLRU, PLRUs from soc.experiment.cache_ram import CacheRam -from soc.experiment.plru import PLRU from soc.experiment.mem_types import (Fetch1ToICacheType, ICacheToDecode1Type, @@ -380,20 +380,13 @@ class ICache(Elaboratable): def maybe_plrus(self, m, r, plru_victim): comb = m.d.comb - with m.If(NUM_WAYS > 1): - m.submodules.plru_e = e = Decoder(NUM_LINES) - comb += e.i.eq(get_index(r.hit_nia)) + if NUM_WAYS == 0: + return - for i in range(NUM_LINES): - plru = PLRU(WAY_BITS) - m.submodules["plru_%d" % i] = plru - - # PLRU interface - with m.If(e.o[i]): - comb += plru.acc_en.eq(r.hit_valid) - - comb += plru.acc_i.eq(r.hit_way) - comb += plru_victim[i].eq(plru.lru_o) + m.submodules.plrus = plru = PLRUs(NUM_LINES, WAY_BITS, plru_victim) + comb += plru.way.eq(r.hit_way) + comb += plru.valid.eq(r.hit_valid) + comb += plru.index.eq(get_index(r.hit_nia)) # TLB hit detection and real address generation def itlb_lookup(self, m, tlb_req_index, itlb, diff --git a/src/soc/experiment/plru.py b/src/soc/experiment/plru.py index 31f84c20..1812af6e 100644 --- a/src/soc/experiment/plru.py +++ b/src/soc/experiment/plru.py @@ -1,7 +1,8 @@ # based on microwatt plru.vhdl -from nmigen import Elaboratable, Signal, Array, Module, Mux, Const +from nmigen import Elaboratable, Signal, Array, Module, Mux, Const, Cat from nmigen.cli import rtlil +from nmigen.lib.coding import Decoder class PLRU(Elaboratable): @@ -52,6 +53,47 @@ class PLRU(Elaboratable): def ports(self): return [self.acc_en, self.lru_o, self.acc_i] + +class PLRUs(Elaboratable): + def __init__(self, n_plrus, n_bits, out=None): + 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 + + def elaborate(self, platform): + """Generate TLB PLRUs + """ + m = Module() + comb = m.d.comb + + if self.n_plrus == 0: + return m + + # Binary-to-Unary one-hot, enabled by valid + m.submodules.te = te = Decoder(self.n_plrus) + comb += te.n.eq(~self.valid) + comb += te.i.eq(self.index) + + 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) + + return m + + def ports(self): + return [self.valid, self.way, self.index] + list(self.out) + + if __name__ == '__main__': dut = PLRU(2) vl = rtlil.convert(dut, ports=dut.ports()) @@ -59,3 +101,9 @@ if __name__ == '__main__': f.write(vl) + dut = PLRUs(4, 2) + vl = rtlil.convert(dut, ports=dut.ports()) + with open("test_plrus.il", "w") as f: + f.write(vl) + +