Add ShifterMask modules to part_shift_scalar
authorMichael Nolan <mtnolan2640@gmail.com>
Mon, 17 Feb 2020 14:10:13 +0000 (09:10 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 17 Feb 2020 14:10:13 +0000 (09:10 -0500)
src/ieee754/part_shift/part_shift_scalar.py
src/ieee754/part_shift/test/test_shift_scalar.py [new file with mode: 0644]

index 21b8db82569c97e797301b8d4a7113d9d8124214..d6e6c830d7d80f39af5e4ace90a30c24cff7c0e8 100644 (file)
@@ -14,6 +14,7 @@ See:
 """
 from nmigen import Signal, Module, Elaboratable, Cat, Mux
 from ieee754.part_mul_add.partpoints import PartitionPoints
+from ieee754.part_shift.part_shift_dynamic import ShifterMask
 import math
 
 
@@ -33,6 +34,7 @@ class PartitionedScalarShift(Elaboratable):
         width = self.width
         shiftbits = self.shiftbits
         shifted = Signal(self.data.width)
+        pwid = self.partition_points.get_max_partition_count(width)-1
         gates = self.partition_points.as_sig()
         comb += shifted.eq(self.data << self.shifter)
 
@@ -42,12 +44,26 @@ class PartitionedScalarShift(Elaboratable):
         intervals = []
         keys = list(self.partition_points.keys()) + [self.width]
         start = 0
+
+        shifter_masks = []
         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))
+            start = end
+
+        min_bits = math.ceil(math.log2(intervals[0][1] - intervals[0][0]))
+        for i in range(len(keys)):
+            max_bits = math.ceil(math.log2(width-intervals[i][0]))
+            sm = ShifterMask(pwid-i, shiftbits, max_bits, min_bits)
+            setattr(m.submodules, "sm%d" % i, sm)
+            comb += sm.gates.eq(gates[i:pwid])
+            shifter_masks.append(sm.mask)
 
+        start = 0
+        for i in range(len(keys)):
+            end = keys[i]
             sp = Signal(width)
             comb += sp[start:].eq(self.data[start:end] << self.shifter)
             shiftparts.append(sp)
diff --git a/src/ieee754/part_shift/test/test_shift_scalar.py b/src/ieee754/part_shift/test/test_shift_scalar.py
new file mode 100644 (file)
index 0000000..579e1dc
--- /dev/null
@@ -0,0 +1,73 @@
+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_scalar import \
+    PartitionedScalarShift
+
+import unittest
+
+class ScalarShiftTestCase(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_scalar(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)
+        output_intervals = self.get_intervals(output, points)
+
+        m.submodules.dut = dut = PartitionedScalarShift(width, points)
+        comb += [dut.data.eq(a),
+                 dut.shifter.eq(b),
+                 output.eq(dut.output)]
+
+        sim = Simulator(m)
+        def process():
+            yield a.eq(0x01010101)
+            yield b.eq(2)
+            for i in range(1<<(mwidth-1)):
+                yield gates.eq(i)
+                yield Delay(1e-6)
+                yield Settle()
+            yield b.eq(9)
+            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()
+
+
+
+