be to turn the last 16 bits into a byte-level bitmap. LD/ST on a byte
would have 1 of the 16 bits set. LD/ST on a DWORD would have 8 of the 16
bits set (offset if the LD/ST was misaligned). TODO.
+
+Notes:
+
+> I have used bits <11:6> as they are not translated (4KB pages)
+> and larger than a cache line (64 bytes).
+> I have used bits <11:4> when the L1 cache was QuadW sized and
+> the L2 cache was Line sized.
"""
from nmigen.compat.sim import run_simulation
from nmigen.cli import verilog, rtlil
from nmigen import Module, Signal, Const, Array, Cat, Elaboratable
+from nmutil.latch import latchregister, SRLatch
+
class PartialAddrMatch(Elaboratable):
"""A partial address matcher
# inputs
self.addrs_i = Array(Signal(bitwid, name="addr") for i in range(n_adr))
self.addr_we_i = Signal(n_adr) # write-enable for incoming address
- self.addr_en_i = Signal(n_adr) # address activated (0 == ignore)
+ self.addr_en_i = Signal(n_adr) # address latched in
+ self.addr_rs_i = Signal(n_adr) # address deactivated
# output
- self.addr_match_o = Signal(n_adr)
+ self.addr_nomatch_o = Signal(n_adr, name="nomatch_o")
+ self.addr_nomatch_a_o = Array(Signal(n_adr, name="nomatch_array_o") \
+ for i in range(n_adr))
def elaborate(self, platform):
m = Module()
+ return self._elaborate(m, platform)
+
+ def _elaborate(self, m, platform):
comb = m.d.comb
sync = m.d.sync
+ m.submodules.l = l = SRLatch(llen=self.n_adr, sync=False)
addrs_r = Array(Signal(self.bitwid, "a_r") for i in range(self.n_adr))
- addr_en_r = Signal(self.n_adr)
+
+ # latch set/reset
+ comb += l.s.eq(self.addr_en_i)
+ comb += l.r.eq(self.addr_rs_i)
# copy in addresses (and "enable" signals)
for i in range(self.n_adr):
- with m.If(self.addr_we_i[i]):
- sync += addrs_r[i].eq(self.addrs_i[i])
- sync += addr_en_r[i].eq(self.addr_en_i[i])
+ latchregister(m, self.addrs_i[i], addrs_r[i], l.q[i])
# is there a clash, yes/no
+ matchgrp = []
for i in range(self.n_adr):
match = []
for j in range(self.n_adr):
match.append(Const(0)) # don't match against self!
else:
match.append(addrs_r[i] == addrs_r[j])
- comb += self.addr_match_o.eq(Cat(*match).bool() & addr_en_r)
+ comb += self.addr_nomatch_a_o[i].eq(~Cat(*match) & l.q)
+ matchgrp.append(self.addr_nomatch_a_o[i] == l.q)
+ comb += self.addr_nomatch_o.eq(Cat(*matchgrp) & l.q)
return m
yield from self.addrs_i
yield self.addr_we_i
yield self.addr_en_i
- yield self.addr_match_o
+ yield from self.addr_nomatch_a_o
+ yield self.addr_nomatch_o
def ports(self):
return list(self)