Sorta working FP renormalization in cordic
[ieee754fpu.git] / src / ieee754 / cordic / fp_pipeline.py
1 from nmutil.singlepipe import ControlBase
2 from nmutil.pipemodbase import PipeModBaseChain
3
4 from ieee754.fpcommon.denorm import FPAddDeNormMod
5 from ieee754.cordic.fp_pipe_init_stages import (FPCordicInitStage,
6 FPCordicConvertFixed)
7 from ieee754.cordic.sin_cos_pipe_stage import (CordicStage,
8 CordicInitialStage)
9 from ieee754.cordic.renormalize import CordicRenormalize
10
11
12 class CordicPipeChain(PipeModBaseChain):
13 def __init__(self, pspec, stages):
14 self.stages = stages
15 super().__init__(pspec)
16
17 def get_chain(self):
18 return self.stages
19
20
21 class FPCordicBasePipe(ControlBase):
22 def __init__(self, pspec):
23 ControlBase.__init__(self)
24 self.pspec = pspec
25
26 self.denorm = CordicPipeChain(pspec,
27 [FPCordicInitStage(self.pspec),
28 FPAddDeNormMod(self.pspec, False),
29 FPCordicConvertFixed(self.pspec)])
30
31 self.cordicstages = []
32
33 initstage = CordicInitialStage(pspec)
34 finalstage = CordicRenormalize(pspec)
35 stages = []
36 for i in range(pspec.iterations):
37 stages.append(CordicStage(pspec, i))
38 chunks = self.chunkify(initstage, stages)
39 chunks[-1].append(finalstage)
40 for chunk in chunks:
41 chain = CordicPipeChain(pspec, chunk)
42 self.cordicstages.append(chain)
43
44 self._eqs = self.connect([self.denorm] + self.cordicstages)
45
46 def chunkify(self, initstage, stages):
47 chunks = []
48
49 for i in range(0, len(stages), self.pspec.rounds_per_stage):
50 chunks.append(stages[i:i + self.pspec.rounds_per_stage])
51 chunks[0].insert(0, initstage)
52
53 return chunks
54
55 def elaborate(self, platform):
56 m = ControlBase.elaborate(self, platform)
57 m.submodules.denorm = self.denorm
58 for i, stage in enumerate(self.cordicstages):
59 setattr(m.submodules, "cordic%d" % i,
60 stage)
61 m.d.comb += self._eqs
62 return m