use PipelineSpec object in AllTerms
[ieee754fpu.git] / src / ieee754 / part_mul_add / multiply.py
index 8aecf8ae4a87dd50d3bff4d6daddb98fa7131946..7202c9cf653d99c30ded41442eab875dcfd12532 100644 (file)
@@ -8,6 +8,8 @@ from abc import ABCMeta, abstractmethod
 from nmigen.cli import main
 from functools import reduce
 from operator import or_
+from ieee754.pipeline import PipelineSpec
+from nmutil.pipemodbase import PipeModBase
 
 
 class PartitionPoints(dict):
@@ -889,7 +891,7 @@ class Part(Elaboratable):
         the extra terms - as separate terms - are then thrown at the
         AddReduce alongside the multiplication part-results.
     """
-    def __init__(self, part_pts, width, n_parts, n_levels, pbwid):
+    def __init__(self, part_pts, width, n_parts, pbwid):
 
         self.pbwid = pbwid
         self.part_pts = part_pts
@@ -1179,33 +1181,17 @@ class OutputData:
                 self.output.eq(rhs.output)]
 
 
-class AllTerms(Elaboratable):
+class AllTerms(PipeModBase):
     """Set of terms to be added together
     """
 
-    def __init__(self, n_inputs, output_width, n_parts, register_levels):
-        """Create an ``AddReduce``.
-
-        :param inputs: input ``Signal``s to be summed.
-        :param output_width: bit-width of ``output``.
-        :param register_levels: List of nesting levels that should have
-            pipeline registers.
-        :param partition_points: the input partition points.
+    def __init__(self, pspec):
+        """Create an ``AllTerms``.
         """
-        self.register_levels = register_levels
-        self.n_inputs = n_inputs
-        self.n_parts = n_parts
-        self.output_width = output_width
-
-        self.i = self.ispec()
-        self.o = self.ospec()
-
-    def setup(self, m, i):
-        m.submodules.allterms = self
-        m.d.comb += self.i.eq(i)
-
-    def process(self, i):
-        return self.o
+        self.n_inputs = pspec.n_inputs
+        self.n_parts = pspec.n_parts
+        self.output_width = pspec.width
+        super().__init__(pspec, "allterms")
 
     def ispec(self):
         return InputData()
@@ -1236,11 +1222,10 @@ class AllTerms(Elaboratable):
             setattr(m.submodules, "signs%d" % i, s)
             m.d.comb += s.part_ops.eq(self.i.part_ops[i])
 
-        n_levels = len(self.register_levels)+1
-        m.submodules.part_8 = part_8 = Part(eps, 128, 8, n_levels, 8)
-        m.submodules.part_16 = part_16 = Part(eps, 128, 4, n_levels, 8)
-        m.submodules.part_32 = part_32 = Part(eps, 128, 2, n_levels, 8)
-        m.submodules.part_64 = part_64 = Part(eps, 128, 1, n_levels, 8)
+        m.submodules.part_8 = part_8 = Part(eps, 128, 8, 8)
+        m.submodules.part_16 = part_16 = Part(eps, 128, 4, 8)
+        m.submodules.part_32 = part_32 = Part(eps, 128, 2, 8)
+        m.submodules.part_64 = part_64 = Part(eps, 128, 1, 8)
         nat_l, nbt_l, nla_l, nlb_l = [], [], [], []
         for mod in [part_8, part_16, part_32, part_64]:
             m.d.comb += mod.a.eq(self.i.a)
@@ -1393,6 +1378,12 @@ class Mul8_16_32_64(Elaboratable):
             flip-flops are to be inserted.
         """
 
+        self.id_wid = 0 # num_bits(num_rows)
+        self.op_wid = 0
+        self.pspec = PipelineSpec(128, self.id_wid, self.op_wid, n_ops=3)
+        self.pspec.n_inputs = 64 + 4
+        self.pspec.n_parts = 8
+
         # parameter(s)
         self.register_levels = list(register_levels)
 
@@ -1420,9 +1411,10 @@ class Mul8_16_32_64(Elaboratable):
 
         part_pts = self.part_pts
 
-        n_inputs = 64 + 4
-        n_parts = 8
-        t = AllTerms(n_inputs, 128, n_parts, self.register_levels)
+        n_parts = self.pspec.n_parts
+        n_inputs = self.pspec.n_inputs
+        output_width = self.pspec.width
+        t = AllTerms(self.pspec)
         t.setup(m, self.i)
 
         terms = t.o.terms