1 from nmigen
import Module
, Signal
2 from nmutil
.pipemodbase
import PipeModBase
3 from ieee754
.cordic
.pipe_data
import CordicData
, CordicInitialData
6 from bigfloat
import BigFloat
9 class CordicInitialStage(PipeModBase
):
10 def __init__(self
, pspec
):
11 super().__init
__(pspec
, "cordicinit")
14 return CordicInitialData(self
.pspec
)
17 return CordicData(self
.pspec
)
19 def elaborate(self
, platform
):
24 for i
in range(self
.pspec
.iterations
):
25 An
*= math
.sqrt(1 + 2**(-2*i
))
26 X0
= int(round(self
.pspec
.M
*1/An
))
28 comb
+= self
.o
.x
.eq(X0
)
29 comb
+= self
.o
.y
.eq(0)
30 comb
+= self
.o
.z
.eq(self
.i
.z0
)
32 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)
36 class CordicStage(PipeModBase
):
37 def __init__(self
, pspec
, stagenum
):
38 super().__init
__(pspec
, "cordicstage%d" % stagenum
)
39 self
.stagenum
= stagenum
42 return CordicData(self
.pspec
)
45 return CordicData(self
.pspec
)
47 def elaborate(self
, platform
):
51 dx
= Signal(self
.i
.x
.shape())
52 dy
= Signal(self
.i
.y
.shape())
53 dz
= Signal(self
.i
.z
.shape())
54 with bf
.quadruple_precision
:
55 x
= bf
.atan(BigFloat(2) ** BigFloat(-self
.stagenum
))
56 x
= x
/(bf
.const_pi()/2)
60 comb
+= dx
.eq(self
.i
.y
>> self
.stagenum
)
61 comb
+= dy
.eq(self
.i
.x
>> self
.stagenum
)
64 with m
.If(self
.i
.z
>= 0):
65 comb
+= self
.o
.x
.eq(self
.i
.x
- dx
)
66 comb
+= self
.o
.y
.eq(self
.i
.y
+ dy
)
67 comb
+= self
.o
.z
.eq(self
.i
.z
- dz
)
69 comb
+= self
.o
.x
.eq(self
.i
.x
+ dx
)
70 comb
+= self
.o
.y
.eq(self
.i
.y
- dy
)
71 comb
+= self
.o
.z
.eq(self
.i
.z
+ dz
)
74 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)