split out concurrentunit ReservationStations to separate module
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 Mar 2019 22:00:37 +0000 (22:00 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 Mar 2019 22:00:37 +0000 (22:00 +0000)
src/add/concurrentunit.py [new file with mode: 0644]
src/add/fpadd/pipeline.py
src/add/test_fpadd_pipe.py

diff --git a/src/add/concurrentunit.py b/src/add/concurrentunit.py
new file mode 100644 (file)
index 0000000..907cb68
--- /dev/null
@@ -0,0 +1,74 @@
+# IEEE Floating Point Adder (Single Precision)
+# Copyright (C) Jonathan P Dawson 2013
+# 2013-12-12
+
+from math import log
+from nmigen import Module
+from nmigen.cli import main, verilog
+
+from singlepipe import (ControlBase, UnbufferedPipeline, PassThroughStage)
+from multipipe import CombMuxOutPipe
+from multipipe import PriorityCombMuxInPipe
+
+from fpcommon.getop import FPADDBaseData
+from fpcommon.denorm import FPSCData
+from fpcommon.pack import FPPackData
+from fpcommon.normtopack import FPNormToPack
+from fpadd.specialcases import FPAddSpecialCasesDeNorm
+from fpadd.addstages import FPAddAlignSingleAdd
+
+
+def num_bits(n):
+    return int(log(n) / log(2))
+
+class FPADDInMuxPipe(PriorityCombMuxInPipe):
+    def __init__(self, num_rows, iospecfn):
+        self.num_rows = num_rows
+        stage = PassThroughStage(iospecfn)
+        PriorityCombMuxInPipe.__init__(self, stage, p_len=self.num_rows)
+
+
+class FPADDMuxOutPipe(CombMuxOutPipe):
+    def __init__(self, num_rows, iospecfn):
+        self.num_rows = num_rows
+        stage = PassThroughStage(iospecfn)
+        CombMuxOutPipe.__init__(self, stage, n_len=self.num_rows)
+
+
+class ReservationStations:
+    """ Reservation-Station pipeline
+
+        Input: num_rows - number of input and output Reservation Stations
+
+        Requires: the addition of an "alu" object, an i_specfn and an o_specfn
+
+        * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
+        * ALU pipeline
+        * fan-out on outputs (an array of FPPackData: z,mid)
+
+        Fan-in and Fan-out are combinatorial.
+    """
+    def __init__(self, num_rows):
+        self.num_rows = num_rows
+        self.inpipe = FPADDInMuxPipe(num_rows, self.i_specfn)   # fan-in
+        self.outpipe = FPADDMuxOutPipe(num_rows, self.o_specfn) # fan-out
+
+        self.p = self.inpipe.p  # kinda annoying,
+        self.n = self.outpipe.n # use pipe in/out as this class in/out
+        self._ports = self.inpipe.ports() + self.outpipe.ports()
+
+    def elaborate(self, platform):
+        m = Module()
+        m.submodules.inpipe = self.inpipe
+        m.submodules.alu = self.alu
+        m.submodules.outpipe = self.outpipe
+
+        m.d.comb += self.inpipe.n.connect_to_next(self.alu.p)
+        m.d.comb += self.alu.connect_to_next(self.outpipe)
+
+        return m
+
+    def ports(self):
+        return self._ports
+
+
index 22eed7e0dfd9b3ec27f21152bac67e01f4b8c66d..45b943eaa12641a496e8787b4ee16d7df5b43b8c 100644 (file)
@@ -16,6 +16,8 @@ from fpcommon.normtopack import FPNormToPack
 from fpadd.specialcases import FPAddSpecialCasesDeNorm
 from fpadd.addstages import FPAddAlignSingleAdd
 
+from concurrentunit import ReservationStations, num_bits
+
 
 class FPADDBasePipe(ControlBase):
     def __init__(self, width, id_wid):
@@ -35,23 +37,7 @@ class FPADDBasePipe(ControlBase):
         return m
 
 
-class FPADDInMuxPipe(PriorityCombMuxInPipe):
-    def __init__(self, width, id_wid, num_rows):
-        self.num_rows = num_rows
-        def iospec(): return FPADDBaseData(width, id_wid)
-        stage = PassThroughStage(iospec)
-        PriorityCombMuxInPipe.__init__(self, stage, p_len=self.num_rows)
-
-
-class FPADDMuxOutPipe(CombMuxOutPipe):
-    def __init__(self, width, id_wid, num_rows):
-        self.num_rows = num_rows
-        def iospec(): return FPPackData(width, id_wid)
-        stage = PassThroughStage(iospec)
-        CombMuxOutPipe.__init__(self, stage, n_len=self.num_rows)
-
-
-class FPADDMuxInOut:
+class FPADDMuxInOut(ReservationStations):
     """ Reservation-Station version of FPADD pipeline.
 
         * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
@@ -60,28 +46,14 @@ class FPADDMuxInOut:
 
         Fan-in and Fan-out are combinatorial.
     """
-    def __init__(self, width, id_wid, num_rows):
-        self.num_rows = num_rows
-        self.inpipe = FPADDInMuxPipe(width, id_wid, num_rows)   # fan-in
-        self.fpadd = FPADDBasePipe(width, id_wid)               # add stage
-        self.outpipe = FPADDMuxOutPipe(width, id_wid, num_rows) # fan-out
-
-        self.p = self.inpipe.p  # kinda annoying,
-        self.n = self.outpipe.n # use pipe in/out as this class in/out
-        self._ports = self.inpipe.ports() + self.outpipe.ports()
-
-    def elaborate(self, platform):
-        m = Module()
-        m.submodules.inpipe = self.inpipe
-        m.submodules.fpadd = self.fpadd
-        m.submodules.outpipe = self.outpipe
-
-        m.d.comb += self.inpipe.n.connect_to_next(self.fpadd.p)
-        m.d.comb += self.fpadd.connect_to_next(self.outpipe)
-
-        return m
-
-    def ports(self):
-        return self._ports
+    def __init__(self, width, num_rows):
+        self.width = width
+        self.id_wid = num_bits(width)
+        self.alu = FPADDBasePipe(width, self.id_wid)
+        ReservationStations.__init__(self, num_rows)
 
+    def i_specfn(self):
+        return FPADDBaseData(self.width, self.id_wid)
 
+    def o_specfn(self):
+        return FPPackData(self.width, self.id_wid)
index 4bac9279b5512366eb51dcfafb9ff661f34c5207..ccba331ad06c165875256cb65360a92150322e0f 100644 (file)
@@ -110,7 +110,7 @@ class InputTest:
 
 
 if __name__ == '__main__':
-    dut = FPADDMuxInOut(32, 2, 4)
+    dut = FPADDMuxInOut(32, 4)
     vl = rtlil.convert(dut, ports=dut.ports())
     with open("test_fpadd_pipe.il", "w") as f:
         f.write(vl)