run tests in parallel
[ieee754fpu.git] / src / ieee754 / cordic / sin_cos_pipe_stage.py
1 from nmigen import Module, Signal
2 from nmutil.pipemodbase import PipeModBase
3 from ieee754.cordic.pipe_data import CordicData, CordicInitialData
4 import math
5
6
7 class CordicInitialStage(PipeModBase):
8 def __init__(self, pspec):
9 super().__init__(pspec, "cordicinit")
10
11 def ispec(self):
12 return CordicInitialData(self.pspec)
13
14 def ospec(self):
15 return CordicData(self.pspec)
16
17 def elaborate(self, platform):
18 m = Module()
19 comb = m.d.comb
20
21 An = 1.0
22 for i in range(self.pspec.iterations):
23 An *= math.sqrt(1 + 2**(-2*i))
24 X0 = int(round(self.pspec.M*1/An))
25
26 comb += self.o.x.eq(X0)
27 comb += self.o.y.eq(0)
28 comb += self.o.z.eq(self.i.z0)
29 return m
30
31
32 class CordicStage(PipeModBase):
33 def __init__(self, pspec, stagenum):
34 super().__init__(pspec, "cordicstage%d" % stagenum)
35 self.stagenum = stagenum
36
37 def ispec(self):
38 return CordicData(self.pspec)
39
40 def ospec(self):
41 return CordicData(self.pspec)
42
43 def elaborate(self, platform):
44 m = Module()
45 comb = m.d.comb
46
47 dx = Signal(self.i.x.shape())
48 dy = Signal(self.i.y.shape())
49 dz = Signal(self.i.z.shape())
50 angle = int(round(self.pspec.M *
51 math.atan(2**(-self.stagenum))))
52
53 comb += dx.eq(self.i.y >> self.stagenum)
54 comb += dy.eq(self.i.x >> self.stagenum)
55 comb += dz.eq(angle)
56
57 with m.If(self.i.z >= 0):
58 comb += self.o.x.eq(self.i.x - dx)
59 comb += self.o.y.eq(self.i.y + dy)
60 comb += self.o.z.eq(self.i.z - dz)
61 with m.Else():
62 comb += self.o.x.eq(self.i.x + dx)
63 comb += self.o.y.eq(self.i.y - dy)
64 comb += self.o.z.eq(self.i.z + dz)
65
66 return m