# SPDX-License-Identifier: LGPL-2.1-or-later
# See Notices.txt for copyright information
-from nmigen import Signal, Module, Elaboratable, Mux, Cat, Shape
+from nmigen import Signal, Module, Elaboratable, Mux, Cat, Shape, Repl
from nmigen.back.pysim import Simulator, Delay, Settle
from nmigen.cli import rtlil
self.partpoints = partpoints
self.a = PartitionedSignal(partpoints, width)
self.b = PartitionedSignal(partpoints, width*2)
- self.cat_sel = Signal(len(partpoints)+1)
self.cat_out = Signal(width*3)
def elaborate(self, platform):
comb = m.d.comb
self.a.set_module(m)
self.b.set_module(m)
- #self.cat_sel.set_module(m)
comb += self.cat_out.eq(Cat(self.a, self.b))
return m
+class TestReplMod(Elaboratable):
+ def __init__(self, width, partpoints):
+ self.partpoints = partpoints
+ self.a = PartitionedSignal(partpoints, width)
+ self.repl_sel = Signal(len(partpoints)+1)
+ self.repl_out = Signal(width*2)
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+ self.a.set_module(m)
+
+ comb += self.repl_out.eq(Repl(self.a, 2))
+
+ return m
+
+
class TestAssMod(Elaboratable):
def __init__(self, width, out_shape, partpoints, scalar):
self.partpoints = partpoints
sim.run()
+class TestRepl(unittest.TestCase):
+ def test(self):
+ width = 16
+ part_mask = Signal(3) # divide into 4-bits
+ module = TestReplMod(width, part_mask)
+
+ test_name = "part_sig_repl"
+ traces = [part_mask,
+ module.a.sig,
+ module.repl_out]
+ sim = create_simulator(module, traces, test_name)
+
+ # annoying recursive import issue
+ from ieee754.part_repl.repl import get_runlengths
+
+ def async_process():
+
+ def test_replop(msg_prefix):
+ # define lengths of a/b test input
+ alen, blen = 16, 32
+ # pairs of test values a, b
+ for a, b in [(0x0000, 0x00000000),
+ (0xDCBA, 0x12345678),
+ (0xABCD, 0x01234567),
+ (0xFFFF, 0x0000),
+ (0x0000, 0x0000),
+ (0x1F1F, 0xF1F1F1F1),
+ (0x0000, 0xFFFFFFFF)]:
+
+ # convert a and b to partitions
+ apart, bpart = [], []
+ ajump, bjump = alen // 4, blen // 4
+ for i in range(4):
+ apart.append((a >> (ajump*i) & ((1<<ajump)-1)))
+ bpart.append((b >> (bjump*i) & ((1<<bjump)-1)))
+
+ print ("apart bpart", hex(a), hex(b),
+ list(map(hex, apart)), list(map(hex, bpart)))
+
+ yield module.a.lower().eq(a)
+ yield module.b.lower().eq(b)
+ yield Delay(0.1e-6)
+
+ y = 0
+ # work out the runlengths for this mask.
+ # 0b011 returns [1,1,2] (for a mask of length 3)
+ mval = yield part_mask
+ runlengths = get_runlengths(mval, 3)
+ j = 0
+ ai = 0
+ bi = 0
+ for i in runlengths:
+ # a first
+ for _ in range(i):
+ print ("runlength", i,
+ "ai", ai,
+ "apart", hex(apart[ai]),
+ "j", j)
+ y |= apart[ai] << j
+ print (" y", hex(y))
+ j += ajump
+ ai += 1
+ # now b
+ for _ in range(i):
+ print ("runlength", i,
+ "bi", bi,
+ "bpart", hex(bpart[bi]),
+ "j", j)
+ y |= bpart[bi] << j
+ print (" y", hex(y))
+ j += bjump
+ bi += 1
+
+ # check the result
+ outval = (yield module.repl_out)
+ msg = f"{msg_prefix}: repl " + \
+ f"0x{mval:X} 0x{a:X} : 0x{b:X}" + \
+ f" => 0x{y:X} != 0x{outval:X}"
+ self.assertEqual(y, outval, msg)
+
+ yield part_mask.eq(0)
+ yield from test_replop("16-bit")
+ yield part_mask.eq(0b10)
+ yield from test_replop("8-bit")
+ yield part_mask.eq(0b1111)
+ yield from test_replop("4-bit")
+
+ sim.add_process(async_process)
+ with sim.write_vcd(
+ vcd_file=open(test_name + ".vcd", "w"),
+ gtkw_file=open(test_name + ".gtkw", "w"),
+ traces=traces):
+ sim.run()
+
+
class TestAssign(unittest.TestCase):
def run_tst(self, in_width, out_width, out_signed, scalar):
part_mask = Signal(3) # divide into 4-bits