convert fpdiv to pspec
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 2 Jul 2019 08:41:45 +0000 (09:41 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 2 Jul 2019 08:41:45 +0000 (09:41 +0100)
src/ieee754/fpdiv/div0.py
src/ieee754/fpdiv/div1.py
src/ieee754/fpdiv/div2.py
src/ieee754/fpdiv/divstages.py
src/ieee754/fpdiv/pipeline.py
src/ieee754/fpdiv/specialcases.py

index 0667639df479ca18683cdd923cb6a45186b04761..330d5af545a43f88f01637162a8db8fa3f331819 100644 (file)
@@ -9,28 +9,30 @@ from nmigen.cli import main, verilog
 from ieee754.fpcommon.fpbase import (FPNumBaseRecord, Overflow)
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPDivStage0Data:
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.z = FPNumBaseRecord(width, False)
         self.out_do_z = Signal(reset_less=True)
         self.oz = Signal(width, reset_less=True)
         self.of = Overflow()
 
+        self.ctx = FPBaseData(width, pspec) # context: muxid, operator etc.
+        self.mid = self.ctx.mid             # annoying. complicated.
+
         # TODO: here is where Q and R would be put, and passed
         # down to Stage1 processing.
 
         mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
         self.product = Signal(mw, reset_less=True)
 
-        self.mid = Signal(id_wid, reset_less=True)
-
     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)]
+                self.product.eq(i.product), self.ctx.eq(i.ctx)]
 
 
 class FPDivStage0Mod(Elaboratable):
@@ -86,7 +88,7 @@ class FPDivStage0Mod(Elaboratable):
 
         m.d.comb += self.o.oz.eq(self.i.oz)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         return m
 
 
index 9dfb7cd64328936b6ef23d67dd00834a7f6ff4b2..dd2aba48d0d3ebefc0a1c949f4ad63e3045dfabf 100644 (file)
@@ -14,17 +14,17 @@ from .div0 import FPDivStage0Data
 
 class FPDivStage1Mod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPDivStage0Data(self.width, self.id_wid) # Q/Rem (etc) in...
+        return FPDivStage0Data(self.width, self.pspec) # Q/Rem (etc) in...
 
     def ospec(self):
-        return FPDivStage0Data(self.width, self.id_wid) # ... Q/Rem (etc) out
+        return FPDivStage0Data(self.width, self.pspec) # ... Q/Rem (etc) out
 
     def process(self, i):
         return self.o
@@ -64,6 +64,6 @@ class FPDivStage1Mod(Elaboratable):
 
         m.d.comb += self.o.oz.eq(self.i.oz)
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
         return m
 
index 1b54db47294a2fe021e62301113a93b3df6e3147..9c77667a604dba1817c62a7ecf922c77bd20889c 100644 (file)
@@ -15,17 +15,17 @@ class FPDivStage2Mod(FPState, Elaboratable):
     """ Second stage of div: preparation for normalisation.
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPDivStage0Data(self.width, self.id_wid) # Q/Rem in...
+        return FPDivStage0Data(self.width, self.pspec) # Q/Rem in...
 
     def ospec(self):
-        return FPAddStage1Data(self.width, self.id_wid) # out to post-process
+        return FPAddStage1Data(self.width, self.pspec) # out to post-process
 
     def process(self, i):
         return self.o
@@ -65,14 +65,14 @@ class FPDivStage2Mod(FPState, Elaboratable):
 
         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)
         m.d.comb += self.o.oz.eq(self.i.oz)
-        m.d.comb += self.o.mid.eq(self.i.mid)
+        m.d.comb += self.o.ctx.eq(self.i.ctx)
 
         return m
 
 
 class FPDivStage2(FPState):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "divider_1")
         self.mod = FPDivStage2Mod(width)
         self.out_z = FPNumBaseRecord(width, False)
index 8e33ba8eebc71a9956ab0df7ef0bb2285a4295e4..2dac2a620a9cbb09961ff2f4c45d093bbe2d8454 100644 (file)
@@ -22,10 +22,10 @@ from .div0 import FPDivStage0Data
 
 class FPDivStages(FPState, SimpleHandshake):
 
-    def __init__(self, width, id_wid, n_stages, begin, end):
+    def __init__(self, width, pspec, n_stages, begin, end):
         FPState.__init__(self, "align")
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.n_stages = n_stages # number of combinatorial stages
         self.begin = begin # "begin" mode
         self.end = end # "end" mode
@@ -34,13 +34,13 @@ class FPDivStages(FPState, SimpleHandshake):
 
     def ispec(self):
         if self.begin:
-            return FPSCData(self.width, self.id_wid, False) # from denorm
-        return FPDivStage0Data(self.width, self.id_wid) # DIV ispec (loop)
+            return FPSCData(self.width, self.pspec, False) # from denorm
+        return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
 
     def ospec(self):
         if self.end: # TODO
-            return FPAddStage1Data(self.width, self.id_wid) # to post-norm
-        return FPDivStage0Data(self.width, self.id_wid) # DIV ospec (loop)
+            return FPAddStage1Data(self.width, self.pspec) # to post-norm
+        return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -59,13 +59,13 @@ class FPDivStages(FPState, SimpleHandshake):
         divstages = []
 
         if self.begin: # XXX check this
-            divstages.append(FPDivStage0Mod(self.width, self.id_wid))
+            divstages.append(FPDivStage0Mod(self.width, self.pspec))
 
         for count in range(self.n_stages): # number of combinatorial stages
-            divstages.append(FPDivStage1Mod(self.width, self.id_wid))
+            divstages.append(FPDivStage1Mod(self.width, self.pspec))
 
         if self.end: # XXX check this
-            divstages.append(FPDivStage2Mod(self.width, self.id_wid))
+            divstages.append(FPDivStage2Mod(self.width, self.pspec))
 
         chain = StageChain(divstages)
         chain.setup(m, i)
index b171db272550a49289c2db6242a10248b9c41538..8af7ba83d78ca9cacb540437347b226fa974e1c1 100644 (file)
@@ -54,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])
 
@@ -90,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)
index 5ec3194902e43da4acef377748a08bcf25143c69..b7a05047acc289bfa78a0f80b1ab14bd755e6c78 100644 (file)
@@ -18,17 +18,17 @@ class FPDIVSpecialCasesMod(Elaboratable):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid)
+        return FPADDBaseData(self.width, self.pspec)
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False)
+        return FPSCData(self.width, self.pspec, False)
 
     def setup(self, m, i):
         """ links module to inputs and outputs
@@ -113,7 +113,7 @@ class FPDIVSpecialCases(FPState):
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "special_cases")
         self.mod = FPDIVSpecialCasesMod(width)
         self.out_z = self.mod.ospec()
@@ -138,24 +138,24 @@ class FPDIVSpecialCasesDeNorm(FPState, SimpleHandshake):
     """ special cases: NaNs, infs, zeros, denormalised
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         FPState.__init__(self, "special_cases")
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         SimpleHandshake.__init__(self, self) # pipe is its own stage
         self.out = self.ospec()
 
     def ispec(self):
-        return FPADDBaseData(self.width, self.id_wid) # SpecialCases ispec
+        return FPADDBaseData(self.width, self.pspec) # SpecialCases ispec
 
     def ospec(self):
-        return FPSCData(self.width, self.id_wid, False) # DeNorm ospec
+        return FPSCData(self.width, self.pspec, False) # DeNorm ospec
 
     def setup(self, m, i):
         """ links module to inputs and outputs
         """
-        smod = FPDIVSpecialCasesMod(self.width, self.id_wid)
-        dmod = FPAddDeNormMod(self.width, self.id_wid, False)
+        smod = FPDIVSpecialCasesMod(self.width, self.pspec)
+        dmod = FPAddDeNormMod(self.width, self.pspec, False)
 
         chain = StageChain([smod, dmod])
         chain.setup(m, i)