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.fpbase import (FPNumBaseRecord, Overflow)
 from ieee754.fpcommon.fpbase import FPState
 from ieee754.fpcommon.denorm import FPSCData
+from ieee754.fpcommon.getop import FPBaseData
 
 
 class FPDivStage0Data:
 
 
 
 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.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)
 
         # 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),
     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):
 
 
 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.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
 
 
         return m
 
 
index 9dfb7cd64328936b6ef23d67dd00834a7f6ff4b2..dd2aba48d0d3ebefc0a1c949f4ad63e3045dfabf 100644 (file)
@@ -14,17 +14,17 @@ from .div0 import FPDivStage0Data
 
 class FPDivStage1Mod(Elaboratable):
 
 
 class FPDivStage1Mod(Elaboratable):
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
         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):
 
     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
 
     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.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
 
         return m
 
index 1b54db47294a2fe021e62301113a93b3df6e3147..9c77667a604dba1817c62a7ecf922c77bd20889c 100644 (file)
@@ -15,17 +15,17 @@ class FPDivStage2Mod(FPState, Elaboratable):
     """ Second stage of div: preparation for normalisation.
     """
 
     """ Second stage of div: preparation for normalisation.
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
         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):
 
     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
 
     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.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):
 
 
         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)
         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):
 
 
 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
         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
         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:
 
     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
 
     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
 
     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 = []
 
         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
 
         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
 
         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)
 
         chain = StageChain(divstages)
         chain.setup(m, i)
index b171db272550a49289c2db6242a10248b9c41538..8af7ba83d78ca9cacb540437347b226fa974e1c1 100644 (file)
@@ -54,20 +54,20 @@ from .divstages import FPDivStages
 
 
 class FPDIVBasePipe(ControlBase):
 
 
 class FPDIVBasePipe(ControlBase):
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         ControlBase.__init__(self)
         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 = []
         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
                                          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])
 
 
         self._eqs = self.connect([self.pipestart] + pipechain + [self.pipeend])
 
@@ -90,14 +90,15 @@ class FPDIVMuxInOut(ReservationStations):
 
         Fan-in and Fan-out are combinatorial.
     """
 
         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.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):
         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):
 
     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
     """
 
         https://steve.hollasch.net/cgindex/coding/ieeefloat.html
     """
 
-    def __init__(self, width, id_wid):
+    def __init__(self, width, pspec):
         self.width = width
         self.width = width
-        self.id_wid = id_wid
+        self.pspec = pspec
         self.i = self.ispec()
         self.o = self.ospec()
 
     def ispec(self):
         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):
 
     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
 
     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
     """
 
         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()
         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
     """
 
     """ 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
         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):
         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):
 
     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
         """
 
     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)
 
         chain = StageChain([smod, dmod])
         chain.setup(m, i)