Add mask generator for shift class instructions
authorMichael Nolan <mtnolan2640@gmail.com>
Sat, 9 May 2020 15:58:19 +0000 (11:58 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Sat, 9 May 2020 15:58:19 +0000 (11:58 -0400)
src/soc/alu/maskgen.py [new file with mode: 0644]
src/soc/alu/test/test_maskgen.py [new file with mode: 0644]
src/soc/alu/test/test_pipe_caller.py

diff --git a/src/soc/alu/maskgen.py b/src/soc/alu/maskgen.py
new file mode 100644 (file)
index 0000000..dd6b957
--- /dev/null
@@ -0,0 +1,38 @@
+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]
diff --git a/src/soc/alu/test/test_maskgen.py b/src/soc/alu/test/test_maskgen.py
new file mode 100644 (file)
index 0000000..f9d28d7
--- /dev/null
@@ -0,0 +1,41 @@
+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()
index 9b9152b16aa90d7a6a8086c72308fdebaa02ac68..899b764fa644b41fdb85f4c829662857c6db4f0b 100644 (file)
@@ -134,6 +134,7 @@ class ALUTestCase(FHDLTestCase):
             with Program(lst) as program:
                 sim = self.run_tst_program(program, initial_regs)
 
+    @unittest.skip("broken")
     def test_ilang(self):
         rec = CompALUOpSubset()