--- /dev/null
+from nmigen import (Elaboratable, Signal, Module)
+import math
+
+class MaskGen(Elaboratable):
+ def __init__(self, width):
+ self.width = width
+ self.shiftwidth = math.ceil(math.log2(width))
+ self.mb = Signal(self.shiftwidth, reset_less=True)
+ self.me = Signal(self.shiftwidth, reset_less=True)
+
+ self.o = Signal(width, reset_less=True)
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+
+ x = Signal.like(self.mb)
+ y = Signal.like(self.mb)
+
+ comb += x.eq(64 - self.mb)
+ comb += y.eq(63 - self.me)
+
+ mask_a = Signal.like(self.o)
+ mask_b = Signal.like(self.o)
+
+ comb += mask_a.eq((1<<x) - 1)
+ comb += mask_b.eq((1<<y) - 1)
+
+ with m.If(x > y):
+ comb += self.o.eq(mask_a ^ mask_b)
+ with m.Else():
+ comb += self.o.eq(mask_a ^ ~mask_b)
+
+
+ return m
+
+ def ports(self):
+ return [self.mb, self.me, self.o]
--- /dev/null
+from nmigen import Signal, Module
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmigen.test.utils import FHDLTestCase
+from soc.alu.maskgen import MaskGen
+from soc.decoder.helpers import MASK
+import random
+import unittest
+
+class MaskGenTestCase(FHDLTestCase):
+ def test_maskgen(self):
+ m = Module()
+ comb = m.d.comb
+ m.submodules.dut = dut = MaskGen(64)
+ mb = Signal.like(dut.mb)
+ me = Signal.like(dut.me)
+ o = Signal.like(dut.o)
+
+ comb += [
+ dut.mb.eq(mb),
+ dut.me.eq(me),
+ o.eq(dut.o)]
+
+ sim = Simulator(m)
+
+ def process():
+ for x in range(0, 64):
+ for y in range(0, 64):
+ yield mb.eq(x)
+ yield me.eq(y)
+ yield Delay(1e-6)
+
+ expected = MASK(x, y)
+ result = yield o
+ self.assertEqual(expected, result)
+
+ sim.add_process(process) # or sim.add_sync_process(process), see below
+ with sim.write_vcd("maskgen.vcd", "maskgen.gtkw", traces=dut.ports()):
+ sim.run()
+
+if __name__ == '__main__':
+ unittest.main()