set up DivPipeCoreConfig back in FPDIVMuxInOut, syntax errors
[ieee754fpu.git] / src / ieee754 / fpdiv / pipeline.py
index 1b58b091960ea90a92db5d4bfa14b0b3d4b21532..9600e72b53889993d0146ddf82d1c3f1b2aeaff8 100644 (file)
@@ -7,42 +7,43 @@ Stack looks like this:
 scnorm   - FPDIVSpecialCasesDeNorm ispec FPADDBaseData
 ------                             ospec FPSCData
 
-            StageChain: FPDIVSpecialCasesMod,
-                        FPAddDeNormMod
+                StageChain: FPDIVSpecialCasesMod,
+                            FPAddDeNormMod
 
 pipediv0 - FPDivStagesSetup        ispec FPSCData
 --------                           ospec DivPipeCoreInterstageData
 
-            StageChain: FPDivStage0Mod,
-                        DivPipeCalculateStage,
-                        ...
-                        DivPipeCalculateStage
+                StageChain: FPDivStage0Mod,
+                            DivPipeSetupStage,
+                            DivPipeCalculateStage,
+                            ...
+                            DivPipeCalculateStage
 
 pipediv1 - FPDivStagesIntermediate ispec DivPipeCoreInterstageData
 --------                           ospec DivPipeCoreInterstageData
 
-            StageChain: DivPipeCalculateStage,
-                        ...
-                        DivPipeCalculateStage
+                StageChain: DivPipeCalculateStage,
+                            ...
+                            DivPipeCalculateStage
 ...
 ...
 
 pipediv5 - FPDivStageFinal         ispec FPDivStage0Data
 --------                           ospec FPAddStage1Data
 
-            StageChain: DivPipeCalculateStage,
-                        ...
-                        DivPipeCalculateStage,
-                        DivPipeFinalStage,
-                        FPDivStage2Mod
+                StageChain: DivPipeCalculateStage,
+                            ...
+                            DivPipeCalculateStage,
+                            DivPipeFinalStage,
+                            FPDivStage2Mod
 
 normpack - FPNormToPack            ispec FPAddStage1Data
 --------                           ospec FPPackData
 
-            StageChain: Norm1ModSingle,
-                        RoundMod,
-                        CorrectionsMod,
-                        PackMod
+                StageChain: Norm1ModSingle,
+                            RoundMod,
+                            CorrectionsMod,
+                            PackMod
 
 the number of combinatorial StageChains (n_comb_stages) in
 FPDivStages is an argument arranged to get the length of the whole
@@ -63,52 +64,69 @@ from nmutil.concurrentunit import ReservationStations, num_bits
 
 from ieee754.fpcommon.getop import FPADDBaseData
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.fpbase import FPFormat
 from ieee754.fpcommon.pack import FPPackData
 from ieee754.fpcommon.normtopack import FPNormToPack
-from .specialcases import FPDIVSpecialCasesDeNorm
-from .divstages import (FPDivStagesSetup,
-                        FPDivStagesIntermediate,
-                        FPDivStagesFinal)
-
+from ieee754.fpdiv.specialcases import FPDIVSpecialCasesDeNorm
+from ieee754.fpdiv.divstages import (FPDivStagesSetup,
+                                     FPDivStagesIntermediate,
+                                     FPDivStagesFinal)
+from ieee754.pipeline import PipelineSpec
+from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreConfig
 
 
 class FPDIVBasePipe(ControlBase):
-    def __init__(self, width, pspec):
-        ControlBase.__init__(self)
-        self.width = width
+    def __init__(self, pspec):
         self.pspec = pspec
+        ControlBase.__init__(self)
 
-    def elaborate(self, platform):
-        m = ControlBase.elaborate(self, platform)
-
-        pipestart = FPDIVSpecialCasesDeNorm(self.width, self.pspec)
         pipechain = []
         n_stages = 6      # TODO (depends on width)
-        n_comb_stages = 3 # TODO (depends on how many RS's we want)
-                          # to which the answer: "as few as possible"
-                          # is required.  too many ReservationStations
-                          # means "big problems".
+        n_comb_stages = 3  # TODO (depends on how many RS's we want)
+        stage_idx = 0
+        # to which the answer: "as few as possible"
+        # is required.  too many ReservationStations
+        # means "big problems".
+
         for i in range(n_stages):
-            if i == 0: # needs to convert input from pipestart ospec
+
+            # needs to convert input from pipestart ospec
+            if i == 0:
                 kls = FPDivStagesSetup
-                n_comb_stages -= 1 # reduce due to work done at start
-            elif i == n_stages - 1: # needs to convert output to pipeend ispec
+                n_comb_stages -= 1  # reduce due to work done at start
+
+            # needs to convert output to pipeend ispec
+            elif i == n_stages - 1:
                 kls = FPDivStagesFinal
-                n_comb_stages -= 1 # reduce due to work done at end?
+                n_comb_stages -= 1  # FIXME - reduce due to work done at end?
+
+            # intermediary stage
             else:
                 kls = FPDivStagesIntermediate
-            pipechain.append(kls(self.width, self.pspec, n_comb_stages))
 
-        pipeend = FPNormToPack(self.width, self.pspec)
+            pipechain.append(kls(self.pspec, n_comb_stages, stage_idx))
+            stage_idx += n_comb_stages # increment so that each CalcStage
+                                       # gets a (correct) unique index
+
+        self.pipechain = pipechain
+
+        # start and end: unpack/specialcases then normalisation/packing
+        self.pipestart = pipestart = FPDIVSpecialCasesDeNorm(self.pspec)
+        self.pipeend = pipeend = FPNormToPack(self.pspec)
+
+        self._eqs = self.connect([pipestart] + pipechain + [pipeend])
+
+    def elaborate(self, platform):
+        m = ControlBase.elaborate(self, platform)
 
         # add submodules
-        m.submodules.scnorm = pipestart
-        for i, p in enumerate(pipechain):
+        m.submodules.scnorm = self.pipestart
+        for i, p in enumerate(self.pipechain):
             setattr(m.submodules, "pipediv%d" % i, p)
-        m.submodules.normpack = pipeend
+        m.submodules.normpack = self.pipeend
 
-        # ControlBase.connect creates (returns) the "eqs" needed
-        m.d.comb += self.connect([pipestart] + pipechain + [pipeend])
+        # ControlBase.connect creates the "eqs" needed to connect each pipe
+        m.d.comb += self._eqs
 
         return m
 
@@ -125,15 +143,29 @@ class FPDIVMuxInOut(ReservationStations):
         :op_wid: - set this to the width of an operator which can
                    then be used to change the behaviour of the pipeline.
     """
+
     def __init__(self, width, num_rows, op_wid=0):
-        self.width = width
         self.id_wid = num_bits(width)
-        self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
-        self.alu = FPDIVBasePipe(width, self.pspec)
+        self.pspec = PipelineSpec(width, self.id_wid, op_wid)
+        # get the standard mantissa width, store in the pspec
+        # (used in DivPipeBaseStage.get_core_config)
+        fpformat = FPFormat.standard(width)
+        log2_radix = 2
+        cfg = DivPipeCoreConfig(width, fpformat.fraction_width, log2_radix)
+        self.pspec.fpformat = fpformat
+        self.pspec.log2_radix = log2_radix
+        self.pspec.core_config = cfg
+
+        # XXX TODO - a class (or function?) that takes the pspec (right here)
+        # and creates... "something".  that "something" MUST have an eq function
+        # new_pspec = deepcopy(self.pspec)
+        # new_pspec.opkls = DivPipeCoreOperation
+        # self.alu = FPDIVBasePipe(new_pspec)
+        self.alu = FPDIVBasePipe(self.pspec)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.pspec)
+        return FPADDBaseData(self.pspec)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.pspec)
+        return FPPackData(self.pspec)