From 5fe15467d87ee93520552bdd814a36e34bc1eea3 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Wed, 1 Apr 2020 11:30:35 -0400 Subject: [PATCH] Connect up pipeline stages --- src/ieee754/cordic/pipe_data.py | 15 ++++++++++++- src/ieee754/cordic/sin_cos_pipe_stage.py | 27 +++++++++++++++++++++++- src/ieee754/cordic/sin_cos_pipeline.py | 25 ++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/ieee754/cordic/sin_cos_pipeline.py diff --git a/src/ieee754/cordic/pipe_data.py b/src/ieee754/cordic/pipe_data.py index 2ed23d69..6335244f 100644 --- a/src/ieee754/cordic/pipe_data.py +++ b/src/ieee754/cordic/pipe_data.py @@ -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 diff --git a/src/ieee754/cordic/sin_cos_pipe_stage.py b/src/ieee754/cordic/sin_cos_pipe_stage.py index 216b0193..dcf9e4bc 100644 --- a/src/ieee754/cordic/sin_cos_pipe_stage.py +++ b/src/ieee754/cordic/sin_cos_pipe_stage.py @@ -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 index 00000000..463f9603 --- /dev/null +++ b/src/ieee754/cordic/sin_cos_pipeline.py @@ -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 -- 2.30.2