Connect up pipeline stages
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 1 Apr 2020 15:30:35 +0000 (11:30 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 1 Apr 2020 15:30:35 +0000 (11:30 -0400)
src/ieee754/cordic/pipe_data.py
src/ieee754/cordic/sin_cos_pipe_stage.py
src/ieee754/cordic/sin_cos_pipeline.py [new file with mode: 0644]

index 2ed23d69a96a70d484795b61f3b3eeaaf9d2c0f2..6335244fbd098f5d68f8c6c74c08cb5b42706820 100644 (file)
@@ -1,6 +1,17 @@
-from nmigen import Signal
+from nmigen import Signal, Const
 import math
 
+class CordicInitialData:
+
+    def __init__(self, pspec):
+        ZMAX = pspec.ZMAX
+        self.z0 = Signal(range(-ZMAX, ZMAX), name="z")     # denormed result
+
+    def __iter__(self):
+        yield from self.z
+
+    def eq(self, i):
+        return [self.z.eq(i.z)]
 
 class CordicData:
 
@@ -27,3 +38,5 @@ class CordicPipeSpec:
         self.fracbits = fracbits
         self.M = (1 << fracbits)
         self.ZMAX = int(round(self.M * math.pi/2))
+        zm = Const(-self.ZMAX)
+        self.iterations = zm.width - 1
index 216b01934c60a125df1d0522a6865d4c1b7d37b3..dcf9e4bcbf916ae33377d54ffb507a73bede0965 100644 (file)
@@ -1,8 +1,33 @@
 from nmigen import Module, Signal, Cat, Mux
 from nmutil.pipemodbase import PipeModBase
-from ieee754.cordic.pipe_data import CordicData
+from ieee754.cordic.pipe_data import CordicData, CordicInitialData
 import math
 
+class CordicInitialStage(PipeModBase):
+    def __init__(self, pspec):
+        super().__init__(pspec, "cordicinit")
+
+    def ispec(self):
+        return CordicInitialData(self.pspec, False)
+
+    def ospec(self):
+        return CordicData(self.pspec, False)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        An = 1.0
+        for i in range(self.pspec.iterations):
+            An *= math.sqrt(1 + 2**(-2*i))
+        X0 = int(round(self.pspec.M*1/An))
+
+        comb += self.o.x.eq(X0)
+        comb += self.o.y.eq(0)
+        comb += self.o.z.eq(self.i.z0)
+        
+
+
 
 class CordicStage(PipeModBase):
     def __init__(self, pspec, stagenum):
diff --git a/src/ieee754/cordic/sin_cos_pipeline.py b/src/ieee754/cordic/sin_cos_pipeline.py
new file mode 100644 (file)
index 0000000..463f960
--- /dev/null
@@ -0,0 +1,25 @@
+from nmutil.singlepipe import ControlBase
+from nmutil.concurrentunit import ReservationStations, num_bits
+
+from ieee754.cordic.sin_cos_pipe_stages import (
+    CordicStage, CordicInitialStage)
+from ieee754.cordic.pipe_data import (CordicPipeSpec, CordicData,
+                                      CordicInitalData)
+
+class CordicBasePipe(ControlBase):
+    def __init__(self, pspec):
+        ControlBase.__init__(self)
+        self.init = CordicInitialStage(pspec)
+        self.cordicstages = []
+        for i in range(pspec.iterations):
+            stage = CordicStage(pspec, i)
+            self.cordicstages.append(stage)
+        self._eqs = self.connect([self.init] + self.cordicstages)
+        
+    def elaborate(self, platform):
+        m = ControlBase.elaborate(self, platform)
+        m.submodules.init = self.init
+        for i, stage in enumerate(self.cordicstages):
+            setattr(m.submodules, "stage%d" % i, stage)
+        m.d.comb += self._eqs
+        return m