class PartialAddrMatch(Elaboratable):
"""A partial address matcher
"""
+
def __init__(self, n_adr, bitwid):
self.n_adr = n_adr
self.bitwid = bitwid
# inputs
self.addrs_i = Array(Signal(bitwid, name="addr") for i in range(n_adr))
- #self.addr_we_i = Signal(n_adr, reset_less=True) # write-enable
- self.addr_en_i = Signal(n_adr, reset_less=True) # address latched in
- self.addr_rs_i = Signal(n_adr, reset_less=True) # address deactivated
+ # self.addr_we_i = Signal(n_adr, reset_less=True) # write-enable
+ self.addr_en_i = Signal(n_adr, reset_less=True) # address latched in
+ self.addr_rs_i = Signal(n_adr, reset_less=True) # address deactivated
# output: a nomatch for each address plus individual nomatch signals
self.addr_nomatch_o = Signal(n_adr, name="nomatch_o", reset_less=True)
self.addr_nomatch_a_o = Array(Signal(n_adr, reset_less=True,
- name="nomatch_array_o") \
- for i in range(n_adr))
+ name="nomatch_array_o")
+ for i in range(n_adr))
def elaborate(self, platform):
m = Module()
# array of address-latches
m.submodules.l = self.l = l = SRLatch(llen=self.n_adr, sync=False)
self.adrs_r = adrs_r = Array(Signal(self.bitwid, reset_less=True,
- name="a_r") \
- for i in range(self.n_adr))
+ name="a_r")
+ for i in range(self.n_adr))
# latch set/reset
comb += l.s.eq(self.addr_en_i)
def is_match(self, i, j):
if i == j:
- return Const(0) # don't match against self!
+ return Const(0) # don't match against self!
return self.adrs_r[i] == self.adrs_r[j]
def __iter__(self):
yield from self.addrs_i
- #yield self.addr_we_i
+ # yield self.addr_we_i
yield self.addr_en_i
yield from self.addr_nomatch_a_o
yield self.addr_nomatch_o
self.lexp_o = Signal(self.llen(1), reset_less=True)
if cover > 1:
self.rexp_o = Signal(self.llen(cover), reset_less=True)
- print ("LenExpand", bit_len, cover, self.lexp_o.shape())
+ print("LenExpand", bit_len, cover, self.lexp_o.shape())
def llen(self, cover):
cl = log2_int(self.cover)
- return (cover<<(self.bit_len))+(cl<<self.bit_len)
+ return (cover << (self.bit_len))+(cl << self.bit_len)
def elaborate(self, platform):
m = Module()
# covers N bits
llen = self.llen(1)
# temp
- binlen = Signal((1<<self.bit_len)+1, reset_less=True)
+ binlen = Signal((1 << self.bit_len)+1, reset_less=True)
lexp_o = Signal(llen, reset_less=True)
comb += binlen.eq((Const(1, self.bit_len+1) << (self.len_i)) - 1)
comb += self.lexp_o.eq(binlen << self.addr_i)
if self.cover == 1:
return m
l = []
- print ("llen", llen)
+ print("llen", llen)
for i in range(llen):
l.append(Repl(self.lexp_o[i], self.cover))
comb += self.rexp_o.eq(Cat(*l))
return m
def ports(self):
- return [self.len_i, self.addr_i, self.lexp_o,]
+ return [self.len_i, self.addr_i, self.lexp_o, ]
class TwinPartialAddrBitmap(PartialAddrMatch):
are 1 apart is *guaranteed* to be a miss for those two addresses.
therefore is_match specially takes that into account.
"""
+
def __init__(self, n_adr, lsbwid, bitlen):
- self.lsbwid = lsbwid # number of bits to turn into unary
+ self.lsbwid = lsbwid # number of bits to turn into unary
self.midlen = bitlen-lsbwid
PartialAddrMatch.__init__(self, n_adr, self.midlen)
# input: length of the LOAD/STORE
- expwid = 1+self.lsbwid # XXX assume LD/ST no greater than 8
- self.lexp_i = Array(Signal(1<<expwid, reset_less=True,
- name="len") for i in range(n_adr))
+ expwid = 1+self.lsbwid # XXX assume LD/ST no greater than 8
+ self.lexp_i = Array(Signal(1 << expwid, reset_less=True,
+ name="len") for i in range(n_adr))
# input: full address
self.faddrs_i = Array(Signal(bitlen, reset_less=True,
- name="fadr") for i in range(n_adr))
+ name="fadr") for i in range(n_adr))
# registers for expanded len
- self.len_r = Array(Signal(expwid, reset_less=True, name="l_r") \
- for i in range(self.n_adr))
+ self.len_r = Array(Signal(expwid, reset_less=True, name="l_r")
+ for i in range(self.n_adr))
def elaborate(self, platform):
m = PartialAddrMatch.elaborate(self, platform)
# TODO make this a module. too much.
def is_match(self, i, j):
if i == j:
- return Const(0) # don't match against self!
+ return Const(0) # don't match against self!
# we know that pairs have addr and addr+1 therefore it is
# guaranteed that they will not match.
if (i // 2) == (j // 2):
- return Const(0) # don't match against twin, either.
+ return Const(0) # don't match against twin, either.
# the bitmask contains data for *two* cache lines (16 bytes).
# however len==8 only covers *half* a cache line so we only
# need to compare half the bits
- expwid = 1<<self.lsbwid
- #if i % 2 == 1 or j % 2 == 1: # XXX hmmm...
+ expwid = 1 << self.lsbwid
+ # if i % 2 == 1 or j % 2 == 1: # XXX hmmm...
# expwid >>= 1
# straight compare: binary top bits of addr, *unary* compare on bottom
therefore, because this now covers two addresses, we need *two*
comparisons per address *not* one.
"""
+
def __init__(self, n_adr, lsbwid, bitlen):
- self.lsbwid = lsbwid # number of bits to turn into unary
+ self.lsbwid = lsbwid # number of bits to turn into unary
self.midlen = bitlen-lsbwid
PartialAddrMatch.__init__(self, n_adr, self.midlen)
name="len") for i in range(n_adr))
# input: full address
self.faddrs_i = Array(Signal(bitlen, reset_less=True,
- name="fadr") for i in range(n_adr))
+ name="fadr") for i in range(n_adr))
# intermediary: address + 1
self.addr1s = Array(Signal(self.midlen, reset_less=True,
- name="adr1") \
+ name="adr1")
for i in range(n_adr))
# expanded lengths, needed in match
- expwid = 1+self.lsbwid # XXX assume LD/ST no greater than 8
- self.lexp = Array(Signal(1<<expwid, reset_less=True,
- name="a_l") \
- for i in range(self.n_adr))
+ expwid = 1+self.lsbwid # XXX assume LD/ST no greater than 8
+ self.lexp = Array(Signal(1 << expwid, reset_less=True,
+ name="a_l")
+ for i in range(self.n_adr))
def elaborate(self, platform):
m = PartialAddrMatch.elaborate(self, platform)
# intermediaries
adrs_r, l = self.adrs_r, self.l
len_r = Array(Signal(self.lsbwid, reset_less=True,
- name="l_r") \
- for i in range(self.n_adr))
+ name="l_r")
+ for i in range(self.n_adr))
for i in range(self.n_adr):
# create a bit-expander for each address
# TODO make this a module. too much.
def is_match(self, i, j):
if i == j:
- return Const(0) # don't match against self!
+ return Const(0) # don't match against self!
# the bitmask contains data for *two* cache lines (16 bytes).
# however len==8 only covers *half* a cache line so we only
# need to compare half the bits
- expwid = 1<<self.lsbwid
+ expwid = 1 << self.lsbwid
hexp = expwid >> 1
expwid2 = expwid + hexp
- print (self.lsbwid, expwid)
+ print(self.lsbwid, expwid)
# straight compare: binary top bits of addr, *unary* compare on bottom
straight_eq = (self.adrs_r[i] == self.adrs_r[j]) & \
(self.lexp[i][:expwid] & self.lexp[j][:expwid]).bool()
def __iter__(self):
yield from self.faddrs_i
yield from self.len_i
- #yield self.addr_we_i
+ # yield self.addr_we_i
yield self.addr_en_i
yield from self.addr_nomatch_a_o
yield self.addr_nomatch_o
yield dut.go_wr_i.eq(0)
yield
+
def part_addr_bit(dut):
# 0b110 | 0b101 |
# 0b101 1011 / 8 ==> 0b0000 0000 0000 0111 | 1111 1000 0000 0000 |
def part_addr_byte(dut):
for l in range(8):
- for a in range(1<<dut.bit_len):
- maskbit = (1<<(l))-1
- mask = (1<<(l*8))-1
+ for a in range(1 << dut.bit_len):
+ maskbit = (1 << (l))-1
+ mask = (1 << (l*8))-1
yield dut.len_i.eq(l)
yield dut.addr_i.eq(a)
yield Settle()
lexp = yield dut.lexp_o
exp = yield dut.rexp_o
- print ("pa", l, a, bin(lexp), hex(exp))
+ print("pa", l, a, bin(lexp), hex(exp))
assert exp == (mask << (a*8))
assert lexp == (maskbit << (a))
run_simulation(dut, part_addr_sim(dut), vcd_name='test_part_addr.vcd')
+
if __name__ == '__main__':
test_part_addr()
test_lenexpand_byte()