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
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,
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
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,
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,
# 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):
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())
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)
+
+