put in place infrastructure for dropping in INT div unit
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Jun 2019 08:47:38 +0000 (09:47 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Jun 2019 08:47:48 +0000 (09:47 +0100)
number of combinatorial stages specified as an argument to FPDivStages
start mode does initial conversion from pre-normalised format
not-start and not-end mode inputs Q/Rem data and outputs Q/Rem data
end mode converts Q/Rem data to format needed for post-normalisation

src/ieee754/fpdiv/div0.py
src/ieee754/fpdiv/divstages.py
src/ieee754/fpdiv/pipeline.py

index 796e6c29c09bd835dae1f396daa2cd597900fe88..45a5f971fa8bf617dc47084770acc884d90ebcc4 100644 (file)
@@ -6,7 +6,7 @@ Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
 from nmigen import Module, Signal, Cat, Elaboratable
 from nmigen.cli import main, verilog
 
-from ieee754.fpcommon.fpbase import FPNumBaseRecord
+from ieee754.fpcommon.fpbase import (FPNumBaseRecord, Overflow)
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
 
@@ -17,6 +17,7 @@ class FPDivStage0Data:
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
+        self.of = Overflow()
 
         # TODO: here is where Q and R would be put, and passed
         # down to Stage1 processing.
@@ -28,6 +29,7 @@ class FPDivStage0Data:
 
     def eq(self, i):
         return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz),
+                self.of.eq(i.of),
                 self.product.eq(i.product), self.mid.eq(i.mid)]
 
 
index e1f8b113810b9b3bf986dc70fb16a408912574bc..2d0cbe5d0e03c8bfe6fadf07d41b5a2e43642140 100644 (file)
@@ -21,35 +21,53 @@ from .div2 import FPDivStage2Mod
 
 class FPDivStages(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, id_wid, n_stages, begin, end):
         FPState.__init__(self, "align")
         self.width = width
         self.id_wid = id_wid
+        self.n_stages = n_stages # number of combinatorial stages
+        self.begin = begin # "begin" mode
+        self.end = end # "end" mode
         SimpleHandshake.__init__(self, self) # pipeline is its own stage
         self.m1o = self.ospec()
 
     def ispec(self):
-        return FPSCData(self.width, self.id_wid, False)
+        if self.begin:
+            return FPSCData(self.width, self.id_wid, False)
+        return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
 
     def ospec(self):
+        if self.end: # TODO
+            return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
         return FPAddStage1Data(self.width, self.id_wid) # AddStage1 ospec
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
 
-        # TODO.  clearly, this would be a for-loop, here, creating
-        # a huge number of stages (if radix-2 is used).  interestingly
-        # the number of stages will be data-dependent.
-        divstages = [FPDivStage0Mod(self.width, self.id_wid)]
-        for i in range(self.width): # XXX TODO: work out actual number needed
+        # start mode accepts data from the FP normalisation stage
+        # and does a bit of munging of the data.  it will be chained
+        # into the first DIV combinatorial block,
+
+        # end mode takes the DIV pipeline/chain data and munges it
+        # into the format that the normalisation can accept.
+
+        divstages = []
+
+        if self.begin: # XXX check this
+            divstages.append(FPDivStage0Mod(self.width, self.id_wid))
+
+        for count in range(self.n_stages): # number of combinatorial stages
             divstages.append(FPDivStage1Mod(self.width, self.id_wid))
-        divstages.append(FPDivStage2Mod(self.width, self.id_wid))
+
+        if self.end: # XXX check this
+            divstages.append(FPDivStage2Mod(self.width, self.id_wid))
 
         chain = StageChain(divstages)
         chain.setup(m, i)
 
-        self.o = m1mod.o
+        # output is from the last pipe stage
+        self.o = divstages[-1].o
 
     def process(self, i):
         return self.o
index 7c130fae0539a48c235b331f70b8e3f451da0eb6..8bd16908538fac4b57988aa609fb4f227ed140a5 100644 (file)
@@ -18,17 +18,27 @@ from .divstages import FPDivStages
 class FPDIVBasePipe(ControlBase):
     def __init__(self, width, id_wid):
         ControlBase.__init__(self)
-        self.pipe1 = FPDIVSpecialCasesDeNorm(width, id_wid)
-        self.pipe2 = FPDivStages(width, id_wid)
-        self.pipe3 = FPNormToPack(width, id_wid)
+        self.pipestart = FPDIVSpecialCasesDeNorm(width, id_wid)
+        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,
+                                         n_combinatorial_stages,
+                                         begin, end))
+        self.pipechain = pipechain
+        self.pipeend = FPNormToPack(width, id_wid)
 
-        self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
+        self._eqs = self.connect([self.pipestart] + pipechain + [self.pipeend])
 
     def elaborate(self, platform):
         m = ControlBase.elaborate(self, platform)
-        m.submodules.scnorm = self.pipe1
-        m.submodules.divstages = self.pipe2
-        m.submodules.normpack = self.pipe3
+        m.submodules.scnorm = self.pipestart
+        for i, p in enumerate(self.pipechain):
+            setattr(m.submodules, "pipediv%d" % i, p)
+        m.submodules.normpack = self.pipeend
         m.d.comb += self._eqs
         return m