Rename part_shift_scalar/ to part_shift
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 12 Feb 2020 16:43:56 +0000 (11:43 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 12 Feb 2020 16:43:56 +0000 (11:43 -0500)
12 files changed:
src/ieee754/part_shift/formal/.gitignore [new file with mode: 0644]
src/ieee754/part_shift/formal/proof_shift_dynamic.py [new file with mode: 0644]
src/ieee754/part_shift/formal/proof_shift_scalar.py [new file with mode: 0644]
src/ieee754/part_shift/part_shift_dynamic.py [new file with mode: 0644]
src/ieee754/part_shift/part_shift_scalar.py [new file with mode: 0644]
src/ieee754/part_shift/test/test_shift_dynamic.py [new file with mode: 0644]
src/ieee754/part_shift_scalar/formal/.gitignore [deleted file]
src/ieee754/part_shift_scalar/formal/proof_shift_dynamic.py [deleted file]
src/ieee754/part_shift_scalar/formal/proof_shift_scalar.py [deleted file]
src/ieee754/part_shift_scalar/part_shift_dynamic.py [deleted file]
src/ieee754/part_shift_scalar/part_shift_scalar.py [deleted file]
src/ieee754/part_shift_scalar/test/test_shift_dynamic.py [deleted file]

diff --git a/src/ieee754/part_shift/formal/.gitignore b/src/ieee754/part_shift/formal/.gitignore
new file mode 100644 (file)
index 0000000..37ad79e
--- /dev/null
@@ -0,0 +1 @@
+proof_*/**
diff --git a/src/ieee754/part_shift/formal/proof_shift_dynamic.py b/src/ieee754/part_shift/formal/proof_shift_dynamic.py
new file mode 100644 (file)
index 0000000..ad9e651
--- /dev/null
@@ -0,0 +1,113 @@
+# Proof of correctness for partitioned dynamic shifter
+# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+from nmigen import Module, Signal, Elaboratable, Mux, Cat
+from nmigen.asserts import Assert, AnyConst, Assume
+from nmigen.test.utils import FHDLTestCase
+from nmigen.cli import rtlil
+
+from ieee754.part_mul_add.partpoints import PartitionPoints
+from ieee754.part_shift.part_shift_dynamic import \
+    PartitionedDynamicShift
+import unittest
+
+
+# This defines a module to drive the device under test and assert
+# properties about its outputs
+class ShifterDriver(Elaboratable):
+    def __init__(self):
+        # inputs and outputs
+        pass
+
+    def get_intervals(self, signal, points):
+        start = 0
+        interval = []
+        keys = list(points.keys()) + [signal.width]
+        for key in keys:
+            end = key
+            interval.append(signal[start:end])
+            start = end
+        return interval
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+        width = 24
+        mwidth = 3
+
+        # setup the inputs and outputs of the DUT as anyconst
+        a = Signal(width)
+        b = Signal(width)
+        out = Signal(width)
+        points = PartitionPoints()
+        gates = Signal(mwidth-1)
+        step = int(width/mwidth)
+        for i in range(mwidth-1):
+            points[(i+1)*step] = gates[i]
+        print(points)
+
+        comb += [a.eq(AnyConst(width)),
+                 b.eq(AnyConst(width)),
+                 gates.eq(AnyConst(mwidth-1))]
+
+        m.submodules.dut = dut = PartitionedDynamicShift(width, points)
+
+        a_intervals = self.get_intervals(a, points)
+        b_intervals = self.get_intervals(b, points)
+        out_intervals = self.get_intervals(out, points)
+
+        comb += [dut.a.eq(a),
+                 dut.b.eq(b),
+                 out.eq(dut.output)]
+
+
+        with m.Switch(points.as_sig()):
+            with m.Case(0b00):
+                comb += Assume(b < 24)
+                comb += Assert(out == (a<<b[0:5]) & 0xffffff)
+            with m.Case(0b01):
+                comb += Assume(b_intervals[0] <= 8)
+                comb += Assert(out_intervals[0] ==
+                               (a_intervals[0]<<b_intervals[0]) & 0xff)
+                comb += Assume(b_intervals[1] <= 16)
+                comb += Assert(Cat(out_intervals[1:3]) ==
+                               (Cat(a_intervals[1:3])
+                                <<b_intervals[1]) & 0xffff)
+            with m.Case(0b10):
+                comb += Assume(b_intervals[0] <= 16)
+                comb += Assert(Cat(out_intervals[0:2]) ==
+                               (Cat(a_intervals[0:2])
+                                <<b_intervals[0]) & 0xffff)
+                comb += Assume(b_intervals[2] <= 16)
+                comb += Assert(out_intervals[2] ==
+                               (a_intervals[2]<<b_intervals[2]) & 0xff)
+            with m.Case(0b11):
+                for i, o in enumerate(out_intervals):
+                    comb += Assume(b_intervals[i] < 8)
+                    comb += Assert(o ==
+                                   (a_intervals[i] << b_intervals[i]) & 0xff)
+
+        return m
+
+class PartitionedDynamicShiftTestCase(FHDLTestCase):
+    def test_shift(self):
+        module = ShifterDriver()
+        self.assertFormal(module, mode="bmc", depth=4)
+    def test_ilang(self):
+        width = 64
+        mwidth = 8
+        gates = Signal(mwidth-1)
+        points = PartitionPoints()
+        step = int(width/mwidth)
+        for i in range(mwidth-1):
+            points[(i+1)*step] = gates[i]
+        print(points)
+        dut = PartitionedDynamicShift(width, points)
+        vl = rtlil.convert(dut, ports=[gates, dut.a, dut.b, dut.output])
+        with open("dynamic_shift.il", "w") as f:
+            f.write(vl)
+
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/src/ieee754/part_shift/formal/proof_shift_scalar.py b/src/ieee754/part_shift/formal/proof_shift_scalar.py
new file mode 100644 (file)
index 0000000..dcb9556
--- /dev/null
@@ -0,0 +1,90 @@
+# Proof of correctness for partitioned scalar shifter
+# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+from nmigen import Module, Signal, Elaboratable, Mux, Cat
+from nmigen.asserts import Assert, AnyConst, Assume
+from nmigen.test.utils import FHDLTestCase
+from nmigen.cli import rtlil
+
+from ieee754.part_mul_add.partpoints import PartitionPoints
+from ieee754.part_shift_scalar.part_shift_scalar import PartitionedScalarShift
+import unittest
+
+
+# This defines a module to drive the device under test and assert
+# properties about its outputs
+class ShifterDriver(Elaboratable):
+    def __init__(self):
+        # inputs and outputs
+        pass
+
+    def get_intervals(self, signal, points):
+        start = 0
+        interval = []
+        keys = list(points.keys()) + [signal.width]
+        for key in keys:
+            end = key
+            interval.append(signal[start:end])
+            start = end
+        return interval
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+        width = 24
+        shifterwidth = 5
+        mwidth = 3
+
+        # setup the inputs and outputs of the DUT as anyconst
+        data = Signal(width)
+        out = Signal(width)
+        shifter = Signal(shifterwidth)
+        points = PartitionPoints()
+        gates = Signal(mwidth-1)
+        step = int(width/mwidth)
+        for i in range(mwidth-1):
+            points[(i+1)*step] = gates[i]
+        print(points)
+
+        comb += [data.eq(AnyConst(width)),
+                 shifter.eq(AnyConst(shifterwidth)),
+                 gates.eq(AnyConst(mwidth-1))]
+
+        m.submodules.dut = dut = PartitionedScalarShift(width, points)
+
+        data_intervals = self.get_intervals(data, points)
+        out_intervals = self.get_intervals(out, points)
+
+        comb += [dut.data.eq(data),
+                 dut.shifter.eq(shifter),
+                 out.eq(dut.output)]
+
+        expected = Signal(width)
+        comb += expected.eq(data << shifter)
+
+        with m.Switch(points.as_sig()):
+            with m.Case(0b00):
+                comb += Assert(out[0:24] == (data[0:24] << shifter) & 0xffffff)
+
+            with m.Case(0b01):
+                comb += Assert(out[0:8] == expected[0:8])
+                comb += Assert(out[8:24] == (data[8:24] << shifter) & 0xffff)
+
+            with m.Case(0b10):
+                comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
+                comb += Assert(out[0:16] == (data[0:16] << shifter) & 0xffff)
+
+            with m.Case(0b11):
+                comb += Assert(out[0:8] == expected[0:8])
+                comb += Assert(out[8:16] == (data[8:16] << shifter) & 0xff)
+                comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
+        return m
+
+class PartitionedScalarShiftTestCase(FHDLTestCase):
+    def test_shift(self):
+        module = ShifterDriver()
+        self.assertFormal(module, mode="bmc", depth=4)
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/src/ieee754/part_shift/part_shift_dynamic.py b/src/ieee754/part_shift/part_shift_dynamic.py
new file mode 100644 (file)
index 0000000..a32e5bf
--- /dev/null
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# See Notices.txt for copyright information
+
+"""
+Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+dynamically partitionable shifter. Unlike part_shift_scalar, both
+operands can be partitioned
+
+See:
+
+* http://libre-riscv.org/3d_gpu/architecture/dynamic_simd/shift/
+* http://bugs.libre-riscv.org/show_bug.cgi?id=173
+"""
+from nmigen import Signal, Module, Elaboratable, Cat, Mux
+from ieee754.part_mul_add.partpoints import PartitionPoints
+import math
+
+
+class PartitionedDynamicShift(Elaboratable):
+    def __init__(self, width, partition_points):
+        self.width = width
+        self.partition_points = PartitionPoints(partition_points)
+
+        self.a = Signal(width)
+        self.b = Signal(width)
+        self.output = Signal(width)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+        width = self.width
+        gates = Signal(self.partition_points.get_max_partition_count(width)-1)
+        comb += gates.eq(self.partition_points.as_sig())
+
+        matrix = []
+        keys = list(self.partition_points.keys()) + [self.width]
+        start = 0
+
+        for i in range(len(keys)):
+            row = []
+            start = 0
+            for j in range(len(keys)):
+                end = keys[j]
+                row.append(Signal(width - start,
+                           name="matrix[%d][%d]" % (i, j)))
+            matrix.append(row)
+
+        a_intervals = []
+        b_intervals = []
+        out_intervals = []
+        intervals = []
+        start = 0
+        for i in range(len(keys)):
+            end = keys[i]
+            a_intervals.append(self.a[start:end])
+            b_intervals.append(self.b[start:end])
+            out_intervals.append(self.output[start:end])
+            intervals.append([start,end])
+            start = end
+
+        for i, b in enumerate(b_intervals):
+            start = 0
+            for j, a in enumerate(a_intervals):
+                end = keys[i]
+                comb += matrix[i][j].eq(a << b)
+                start = end
+
+        intermed = matrix[0][0]
+        comb += out_intervals[0].eq(intermed)
+        for i in range(1, len(out_intervals)):
+            index = gates[:i]  # selects the 'i' least significant bits
+                               # of gates
+            element = Signal(width, name="element%d" % i)
+            for index in range(1<<i):
+                print(index)
+                with m.Switch(gates[:i]):
+                    with m.Case(index):
+                        index = math.ceil(math.log2(index + 1))
+                        comb += element.eq(matrix[index][i])
+            print(keys[i-1])
+            temp = Signal(width, name="intermed%d" % i)
+            print(intermed[keys[0]:])
+            intermed = Mux(gates[i-1], element, element | intermed[keys[0]:])
+            comb += temp.eq(intermed)
+            comb += out_intervals[i].eq(intermed)
+
+
+        return m
+
diff --git a/src/ieee754/part_shift/part_shift_scalar.py b/src/ieee754/part_shift/part_shift_scalar.py
new file mode 100644 (file)
index 0000000..21b8db8
--- /dev/null
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# See Notices.txt for copyright information
+
+"""
+Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+dynamically partitionable shifter. Only the operand to be shifted can
+be partitioned, the amount to shift by *must* be a scalar
+
+See:
+
+* http://libre-riscv.org/3d_gpu/architecture/dynamic_simd/shift/
+* http://bugs.libre-riscv.org/show_bug.cgi?id=173
+"""
+from nmigen import Signal, Module, Elaboratable, Cat, Mux
+from ieee754.part_mul_add.partpoints import PartitionPoints
+import math
+
+
+class PartitionedScalarShift(Elaboratable):
+    def __init__(self, width, partition_points):
+        self.width = width
+        self.partition_points = PartitionPoints(partition_points)
+
+        self.data = Signal(width)
+        self.shiftbits = math.ceil(math.log2(width))
+        self.shifter = Signal(self.shiftbits)
+        self.output = Signal(width)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+        width = self.width
+        shiftbits = self.shiftbits
+        shifted = Signal(self.data.width)
+        gates = self.partition_points.as_sig()
+        comb += shifted.eq(self.data << self.shifter)
+
+        parts = []
+        outputs = []
+        shiftparts = []
+        intervals = []
+        keys = list(self.partition_points.keys()) + [self.width]
+        start = 0
+        for i in range(len(keys)):
+            end = keys[i]
+            parts.append(self.data[start:end])
+            outputs.append(self.output[start:end])
+            intervals.append((start,end))
+
+            sp = Signal(width)
+            comb += sp[start:].eq(self.data[start:end] << self.shifter)
+            shiftparts.append(sp)
+
+            start = end  # for next time round loop
+
+        for i, interval in enumerate(intervals):
+            start, end = interval
+            if i == 0:
+                intermed = shiftparts[i]
+            else:
+                intermed = shiftparts[i] | Mux(gates[i-1], 0, prev)
+            comb += outputs[i].eq(intermed[start:end])
+            prev = intermed
+
+        return m
diff --git a/src/ieee754/part_shift/test/test_shift_dynamic.py b/src/ieee754/part_shift/test/test_shift_dynamic.py
new file mode 100644 (file)
index 0000000..6857991
--- /dev/null
@@ -0,0 +1,69 @@
+from nmigen import Module, Signal
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmigen.test.utils import FHDLTestCase
+from ieee754.part_mul_add.partpoints import PartitionPoints
+
+from ieee754.part_shift.part_shift_dynamic import \
+    PartitionedDynamicShift
+
+import unittest
+
+class DynamicShiftTestCase(FHDLTestCase):
+    def get_intervals(self, signal, points):
+        start = 0
+        interval = []
+        keys = list(points.keys()) + [signal.width]
+        for key in keys:
+            end = key
+            interval.append(signal[start:end])
+            start = end
+        return interval
+
+    def test_dynamic(self):
+        m = Module()
+        comb = m.d.comb
+        mwidth = 4
+        width = 32
+        step = int(width/mwidth)
+        gates = Signal(mwidth-1)
+        points = PartitionPoints()
+        for i in range(mwidth-1):
+            points[(i+1)*step] = gates[i]
+        a = Signal(width)
+        b = Signal(width)
+        output = Signal(width)
+        a_intervals = self.get_intervals(a, points)
+        b_intervals = self.get_intervals(b, points)
+        output_intervals = self.get_intervals(output, points)
+
+        m.submodules.dut = dut = PartitionedDynamicShift(width, points)
+        comb += [dut.a.eq(a),
+                 dut.b.eq(b),
+                 output.eq(dut.output)]
+
+        sim = Simulator(m)
+        def process():
+            yield a.eq(0x01010101)
+            yield b.eq(0x04030201)
+            for i in range(1<<(mwidth-1)):
+                yield gates.eq(i)
+                yield Delay(1e-6)
+                yield Settle()
+            yield gates.eq(1)
+            yield Delay(1e-6)
+            yield Settle()
+            yield gates.eq(0)
+            yield Delay(1e-6)
+            yield Settle()
+
+
+        sim.add_process(process)
+        with sim.write_vcd("test.vcd", "test.gtkw", traces=[a,b,output]):
+            sim.run()
+
+if __name__ == "__main__":
+    unittest.main()
+
+
+
+
diff --git a/src/ieee754/part_shift_scalar/formal/.gitignore b/src/ieee754/part_shift_scalar/formal/.gitignore
deleted file mode 100644 (file)
index 37ad79e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-proof_*/**
diff --git a/src/ieee754/part_shift_scalar/formal/proof_shift_dynamic.py b/src/ieee754/part_shift_scalar/formal/proof_shift_dynamic.py
deleted file mode 100644 (file)
index ea2cc74..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# Proof of correctness for partitioned dynamic shifter
-# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-
-from nmigen import Module, Signal, Elaboratable, Mux, Cat
-from nmigen.asserts import Assert, AnyConst, Assume
-from nmigen.test.utils import FHDLTestCase
-from nmigen.cli import rtlil
-
-from ieee754.part_mul_add.partpoints import PartitionPoints
-from ieee754.part_shift_scalar.part_shift_dynamic import \
-    PartitionedDynamicShift
-import unittest
-
-
-# This defines a module to drive the device under test and assert
-# properties about its outputs
-class ShifterDriver(Elaboratable):
-    def __init__(self):
-        # inputs and outputs
-        pass
-
-    def get_intervals(self, signal, points):
-        start = 0
-        interval = []
-        keys = list(points.keys()) + [signal.width]
-        for key in keys:
-            end = key
-            interval.append(signal[start:end])
-            start = end
-        return interval
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = 24
-        mwidth = 3
-
-        # setup the inputs and outputs of the DUT as anyconst
-        a = Signal(width)
-        b = Signal(width)
-        out = Signal(width)
-        points = PartitionPoints()
-        gates = Signal(mwidth-1)
-        step = int(width/mwidth)
-        for i in range(mwidth-1):
-            points[(i+1)*step] = gates[i]
-        print(points)
-
-        comb += [a.eq(AnyConst(width)),
-                 b.eq(AnyConst(width)),
-                 gates.eq(AnyConst(mwidth-1))]
-
-        m.submodules.dut = dut = PartitionedDynamicShift(width, points)
-
-        a_intervals = self.get_intervals(a, points)
-        b_intervals = self.get_intervals(b, points)
-        out_intervals = self.get_intervals(out, points)
-
-        comb += [dut.a.eq(a),
-                 dut.b.eq(b),
-                 out.eq(dut.output)]
-
-
-        with m.Switch(points.as_sig()):
-            with m.Case(0b00):
-                comb += Assume(b < 24)
-                comb += Assert(out == (a<<b[0:5]) & 0xffffff)
-            with m.Case(0b01):
-                comb += Assume(b_intervals[0] <= 8)
-                comb += Assert(out_intervals[0] ==
-                               (a_intervals[0]<<b_intervals[0]) & 0xff)
-                comb += Assume(b_intervals[1] <= 16)
-                comb += Assert(Cat(out_intervals[1:3]) ==
-                               (Cat(a_intervals[1:3])
-                                <<b_intervals[1]) & 0xffff)
-            with m.Case(0b10):
-                comb += Assume(b_intervals[0] <= 16)
-                comb += Assert(Cat(out_intervals[0:2]) ==
-                               (Cat(a_intervals[0:2])
-                                <<b_intervals[0]) & 0xffff)
-                comb += Assume(b_intervals[2] <= 16)
-                comb += Assert(out_intervals[2] ==
-                               (a_intervals[2]<<b_intervals[2]) & 0xff)
-            with m.Case(0b11):
-                for i, o in enumerate(out_intervals):
-                    comb += Assume(b_intervals[i] < 8)
-                    comb += Assert(o ==
-                                   (a_intervals[i] << b_intervals[i]) & 0xff)
-
-        return m
-
-class PartitionedDynamicShiftTestCase(FHDLTestCase):
-    def test_shift(self):
-        module = ShifterDriver()
-        self.assertFormal(module, mode="bmc", depth=4)
-    def test_ilang(self):
-        width = 64
-        mwidth = 8
-        gates = Signal(mwidth-1)
-        points = PartitionPoints()
-        step = int(width/mwidth)
-        for i in range(mwidth-1):
-            points[(i+1)*step] = gates[i]
-        print(points)
-        dut = PartitionedDynamicShift(width, points)
-        vl = rtlil.convert(dut, ports=[gates, dut.a, dut.b, dut.output])
-        with open("dynamic_shift.il", "w") as f:
-            f.write(vl)
-
-
-if __name__ == "__main__":
-    unittest.main()
-
diff --git a/src/ieee754/part_shift_scalar/formal/proof_shift_scalar.py b/src/ieee754/part_shift_scalar/formal/proof_shift_scalar.py
deleted file mode 100644 (file)
index 11c8648..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-# Proof of correctness for partitioned scalar shifter
-# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-
-from nmigen import Module, Signal, Elaboratable, Mux, Cat
-from nmigen.asserts import Assert, AnyConst, Assume
-from nmigen.test.utils import FHDLTestCase
-from nmigen.cli import rtlil
-
-from ieee754.part_mul_add.partpoints import PartitionPoints
-from ieee754.part_shift_scalar.part_shift_scalar import PartitionedScalarShift
-import unittest
-
-
-# This defines a module to drive the device under test and assert
-# properties about its outputs
-class ShifterDriver(Elaboratable):
-    def __init__(self):
-        # inputs and outputs
-        pass
-
-    def get_intervals(self, signal, points):
-        start = 0
-        interval = []
-        keys = list(points.keys()) + [signal.width]
-        for key in keys:
-            end = key
-            interval.append(signal[start:end])
-            start = end
-        return interval
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = 24
-        shifterwidth = 5
-        mwidth = 3
-
-        # setup the inputs and outputs of the DUT as anyconst
-        data = Signal(width)
-        out = Signal(width)
-        shifter = Signal(shifterwidth)
-        points = PartitionPoints()
-        gates = Signal(mwidth-1)
-        step = int(width/mwidth)
-        for i in range(mwidth-1):
-            points[(i+1)*step] = gates[i]
-        print(points)
-
-        comb += [data.eq(AnyConst(width)),
-                 shifter.eq(AnyConst(shifterwidth)),
-                 gates.eq(AnyConst(mwidth-1))]
-
-        m.submodules.dut = dut = PartitionedScalarShift(width, points)
-
-        data_intervals = self.get_intervals(data, points)
-        out_intervals = self.get_intervals(out, points)
-
-        comb += [dut.data.eq(data),
-                 dut.shifter.eq(shifter),
-                 out.eq(dut.output)]
-
-        expected = Signal(width)
-        comb += expected.eq(data << shifter)
-
-        with m.Switch(points.as_sig()):
-            with m.Case(0b00):
-                comb += Assert(out[0:24] == (data[0:24] << shifter) & 0xffffff)
-
-            with m.Case(0b01):
-                comb += Assert(out[0:8] == expected[0:8])
-                comb += Assert(out[8:24] == (data[8:24] << shifter) & 0xffff)
-
-            with m.Case(0b10):
-                comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
-                comb += Assert(out[0:16] == (data[0:16] << shifter) & 0xffff)
-
-            with m.Case(0b11):
-                comb += Assert(out[0:8] == expected[0:8])
-                comb += Assert(out[8:16] == (data[8:16] << shifter) & 0xff)
-                comb += Assert(out[16:24] == (data[16:24] << shifter) & 0xff)
-        
-        return m
-
-class PartitionedScalarShiftTestCase(FHDLTestCase):
-    def test_shift(self):
-        module = ShifterDriver()
-        self.assertFormal(module, mode="bmc", depth=4)
-
-if __name__ == "__main__":
-    unittest.main()
-
diff --git a/src/ieee754/part_shift_scalar/part_shift_dynamic.py b/src/ieee754/part_shift_scalar/part_shift_dynamic.py
deleted file mode 100644 (file)
index a32e5bf..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-# See Notices.txt for copyright information
-
-"""
-Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
-Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-
-dynamically partitionable shifter. Unlike part_shift_scalar, both
-operands can be partitioned
-
-See:
-
-* http://libre-riscv.org/3d_gpu/architecture/dynamic_simd/shift/
-* http://bugs.libre-riscv.org/show_bug.cgi?id=173
-"""
-from nmigen import Signal, Module, Elaboratable, Cat, Mux
-from ieee754.part_mul_add.partpoints import PartitionPoints
-import math
-
-
-class PartitionedDynamicShift(Elaboratable):
-    def __init__(self, width, partition_points):
-        self.width = width
-        self.partition_points = PartitionPoints(partition_points)
-
-        self.a = Signal(width)
-        self.b = Signal(width)
-        self.output = Signal(width)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = self.width
-        gates = Signal(self.partition_points.get_max_partition_count(width)-1)
-        comb += gates.eq(self.partition_points.as_sig())
-
-        matrix = []
-        keys = list(self.partition_points.keys()) + [self.width]
-        start = 0
-
-        for i in range(len(keys)):
-            row = []
-            start = 0
-            for j in range(len(keys)):
-                end = keys[j]
-                row.append(Signal(width - start,
-                           name="matrix[%d][%d]" % (i, j)))
-            matrix.append(row)
-
-        a_intervals = []
-        b_intervals = []
-        out_intervals = []
-        intervals = []
-        start = 0
-        for i in range(len(keys)):
-            end = keys[i]
-            a_intervals.append(self.a[start:end])
-            b_intervals.append(self.b[start:end])
-            out_intervals.append(self.output[start:end])
-            intervals.append([start,end])
-            start = end
-
-        for i, b in enumerate(b_intervals):
-            start = 0
-            for j, a in enumerate(a_intervals):
-                end = keys[i]
-                comb += matrix[i][j].eq(a << b)
-                start = end
-
-        intermed = matrix[0][0]
-        comb += out_intervals[0].eq(intermed)
-        for i in range(1, len(out_intervals)):
-            index = gates[:i]  # selects the 'i' least significant bits
-                               # of gates
-            element = Signal(width, name="element%d" % i)
-            for index in range(1<<i):
-                print(index)
-                with m.Switch(gates[:i]):
-                    with m.Case(index):
-                        index = math.ceil(math.log2(index + 1))
-                        comb += element.eq(matrix[index][i])
-            print(keys[i-1])
-            temp = Signal(width, name="intermed%d" % i)
-            print(intermed[keys[0]:])
-            intermed = Mux(gates[i-1], element, element | intermed[keys[0]:])
-            comb += temp.eq(intermed)
-            comb += out_intervals[i].eq(intermed)
-
-
-        return m
-
diff --git a/src/ieee754/part_shift_scalar/part_shift_scalar.py b/src/ieee754/part_shift_scalar/part_shift_scalar.py
deleted file mode 100644 (file)
index 21b8db8..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-# See Notices.txt for copyright information
-
-"""
-Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-
-dynamically partitionable shifter. Only the operand to be shifted can
-be partitioned, the amount to shift by *must* be a scalar
-
-See:
-
-* http://libre-riscv.org/3d_gpu/architecture/dynamic_simd/shift/
-* http://bugs.libre-riscv.org/show_bug.cgi?id=173
-"""
-from nmigen import Signal, Module, Elaboratable, Cat, Mux
-from ieee754.part_mul_add.partpoints import PartitionPoints
-import math
-
-
-class PartitionedScalarShift(Elaboratable):
-    def __init__(self, width, partition_points):
-        self.width = width
-        self.partition_points = PartitionPoints(partition_points)
-
-        self.data = Signal(width)
-        self.shiftbits = math.ceil(math.log2(width))
-        self.shifter = Signal(self.shiftbits)
-        self.output = Signal(width)
-
-    def elaborate(self, platform):
-        m = Module()
-        comb = m.d.comb
-        width = self.width
-        shiftbits = self.shiftbits
-        shifted = Signal(self.data.width)
-        gates = self.partition_points.as_sig()
-        comb += shifted.eq(self.data << self.shifter)
-
-        parts = []
-        outputs = []
-        shiftparts = []
-        intervals = []
-        keys = list(self.partition_points.keys()) + [self.width]
-        start = 0
-        for i in range(len(keys)):
-            end = keys[i]
-            parts.append(self.data[start:end])
-            outputs.append(self.output[start:end])
-            intervals.append((start,end))
-
-            sp = Signal(width)
-            comb += sp[start:].eq(self.data[start:end] << self.shifter)
-            shiftparts.append(sp)
-
-            start = end  # for next time round loop
-
-        for i, interval in enumerate(intervals):
-            start, end = interval
-            if i == 0:
-                intermed = shiftparts[i]
-            else:
-                intermed = shiftparts[i] | Mux(gates[i-1], 0, prev)
-            comb += outputs[i].eq(intermed[start:end])
-            prev = intermed
-
-        return m
diff --git a/src/ieee754/part_shift_scalar/test/test_shift_dynamic.py b/src/ieee754/part_shift_scalar/test/test_shift_dynamic.py
deleted file mode 100644 (file)
index ec60d7c..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmigen.test.utils import FHDLTestCase
-from ieee754.part_mul_add.partpoints import PartitionPoints
-
-from ieee754.part_shift_scalar.part_shift_dynamic import \
-    PartitionedDynamicShift
-
-import unittest
-
-class DynamicShiftTestCase(FHDLTestCase):
-    def get_intervals(self, signal, points):
-        start = 0
-        interval = []
-        keys = list(points.keys()) + [signal.width]
-        for key in keys:
-            end = key
-            interval.append(signal[start:end])
-            start = end
-        return interval
-
-    def test_dynamic(self):
-        m = Module()
-        comb = m.d.comb
-        mwidth = 4
-        width = 32
-        step = int(width/mwidth)
-        gates = Signal(mwidth-1)
-        points = PartitionPoints()
-        for i in range(mwidth-1):
-            points[(i+1)*step] = gates[i]
-        a = Signal(width)
-        b = Signal(width)
-        output = Signal(width)
-        a_intervals = self.get_intervals(a, points)
-        b_intervals = self.get_intervals(b, points)
-        output_intervals = self.get_intervals(output, points)
-
-        m.submodules.dut = dut = PartitionedDynamicShift(width, points)
-        comb += [dut.a.eq(a),
-                 dut.b.eq(b),
-                 output.eq(dut.output)]
-
-        sim = Simulator(m)
-        def process():
-            yield a.eq(0x01010101)
-            yield b.eq(0x04030201)
-            for i in range(1<<(mwidth-1)):
-                yield gates.eq(i)
-                yield Delay(1e-6)
-                yield Settle()
-            yield gates.eq(1)
-            yield Delay(1e-6)
-            yield Settle()
-            yield gates.eq(0)
-            yield Delay(1e-6)
-            yield Settle()
-
-
-        sim.add_process(process)
-        with sim.write_vcd("test.vcd", "test.gtkw", traces=[a,b,output]):
-            sim.run()
-
-if __name__ == "__main__":
-    unittest.main()
-
-
-
-