Add stage to convert input float to fixed point number
[ieee754fpu.git] / src / ieee754 / cordic / fp_pipe_init_stages.py
1 from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed,
2 unsigned)
3 from nmigen.cli import main, verilog
4
5 from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
6
7 from nmutil.pipemodbase import PipeModBase
8 from ieee754.fpcommon.basedata import FPBaseData
9 from ieee754.fpcommon.denorm import FPSCData
10 from ieee754.cordic.fp_pipe_data import CordicInitialData
11
12
13 class FPCordicInitStage(PipeModBase):
14 def __init__(self, pspec):
15 super().__init__(pspec, "specialcases")
16
17 def ispec(self):
18 return FPBaseData(self.pspec)
19
20 def ospec(self):
21 return FPSCData(self.pspec, False)
22
23 def elaborate(self, platform):
24 m = Module()
25 comb = m.d.comb
26
27 # decode a/b
28 width = self.pspec.width
29 a1 = FPNumBaseRecord(width, False)
30 m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
31 comb += [a1.v.eq(self.i.a),
32 self.o.a.eq(a1)
33 ]
34
35 # pass through context
36 comb += self.o.ctx.eq(self.i.ctx)
37
38 return m
39
40
41 class FPCordicConvertFixed(PipeModBase):
42 def __init__(self, pspec):
43 super().__init__(pspec, "tofixed")
44
45 def ispec(self):
46 return FPSCData(self.pspec, False)
47
48 def ospec(self):
49 return CordicInitialData(self.pspec)
50
51 def elaborate(self, platform):
52 m = Module()
53 comb = m.d.comb
54
55 shifter = Signal(self.i.a.e.width)
56 comb += shifter.eq(-self.i.a.e)
57
58 z_intermed = Signal(unsigned(self.o.z0.width))
59 z_shifted = Signal(signed(self.o.z0.width))
60 comb += z_intermed.eq(Cat(Repl(0, self.pspec.fracbits -
61 self.i.a.rmw),
62 self.i.a.m))
63 comb += z_shifted.eq(z_intermed >> shifter)
64 comb += self.o.z0.eq(Mux(self.i.a.s,
65 ~z_shifted + 1,
66 z_shifted))
67
68 return m
69