convert fpdiv to pspec
[ieee754fpu.git] / src / ieee754 / fpdiv / pipeline.py
index 8bd16908538fac4b57988aa609fb4f227ed140a5..8af7ba83d78ca9cacb540437347b226fa974e1c1 100644 (file)
@@ -1,4 +1,42 @@
-# IEEE Floating Point Divider Pipeline
+"""IEEE Floating Point Divider Pipeline
+
+Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
+
+Stack looks like this:
+
+scnorm   - FPDIVSpecialCasesDeNorm ispec FPADDBaseData  ospec FPSCData
+            StageChain: FPDIVSpecialCasesMod,
+                        FPAddDeNormMod
+
+pipediv0 - FPDivStages(start=true) ispec FPSCData       ospec FPDivStage0Data
+            StageChain: FPDivStage0Mod,
+                        FPDivStage1Mod,
+                        ...
+                        FPDivStage1Mod
+
+pipediv1 - FPDivStages()           ispec FPDivStage0Data ospec FPDivStage0Data
+            StageChain: FPDivStage1Mod,
+                        ...
+                        FPDivStage1Mod
+...
+...
+
+pipediv5 - FPDivStages(end=true    ispec FPDivStage0Data ospec FPAddStage1Data
+            StageChain: FPDivStage1Mod,
+                        ...
+                        FPDivStage1Mod,
+                        FPDivStage2Mod
+
+normpack - FPNormToPack            ispec FPAddStage1Data ospec FPPackData
+            StageChain: Norm1ModSingle,
+                        RoundMod,
+                        CorrectionsMod,
+                        PackMod
+
+the number of combinatorial StageChains (n_combinatorial_stages) in
+FPDivStages is an argument arranged to get the length of the whole
+pipeline down to sane numbers.
+"""
 
 from nmigen import Module
 from nmigen.cli import main, verilog
@@ -16,20 +54,20 @@ from .divstages import FPDivStages
 
 
 class FPDIVBasePipe(ControlBase):
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         ControlBase.__init__(self)
-        self.pipestart = FPDIVSpecialCasesDeNorm(width, id_wid)
+        self.pipestart = FPDIVSpecialCasesDeNorm(width, pspec)
         pipechain = []
         n_stages = 6 # TODO
         n_combinatorial_stages = 2 # TODO
         for i in range(n_stages):
             begin = i == 0 # needs to convert input from pipestart ospec
             end = i == n_stages - 1 # needs to convert output to pipeend ispec
-            pipechain.append(FPDivStages(width, id_wid,
+            pipechain.append(FPDivStages(width, pspec,
                                          n_combinatorial_stages,
                                          begin, end))
         self.pipechain = pipechain
-        self.pipeend = FPNormToPack(width, id_wid)
+        self.pipeend = FPNormToPack(width, pspec)
 
         self._eqs = self.connect([self.pipestart] + pipechain + [self.pipeend])
 
@@ -52,14 +90,15 @@ class FPDIVMuxInOut(ReservationStations):
 
         Fan-in and Fan-out are combinatorial.
     """
-    def __init__(self, width, num_rows):
+    def __init__(self, width, num_rows, op_wid=0):
         self.width = width
         self.id_wid = num_bits(width)
-        self.alu = FPDIVBasePipe(width, self.id_wid)
+        self.pspec = {'id_wid': self.id_wid, 'op_wid': op_wid}
+        self.alu = FPDIVBasePipe(width, self.pspec)
         ReservationStations.__init__(self, num_rows)
 
     def i_specfn(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def o_specfn(self):
-        return FPPackData(self.width, self.id_wid)
+        return FPPackData(self.width, self.pspec)