switch to exact version of cython
[ieee754fpu.git] / src / ieee754 / cordic / renormalize.py
1 from nmigen import Module, Signal, Mux, Elaboratable, unsigned
2 from nmutil.pipemodbase import PipeModBase
3 from nmutil.clz import CLZ
4 from ieee754.cordic.pipe_data import CordicData, CordicOutputData
5 from ieee754.fpcommon.fpbase import FPNumBaseRecord
6
7
8 class Norm(Elaboratable):
9 def __init__(self, pspec):
10 self.sig_in = Signal(range(-pspec.M, pspec.M+1))
11
12 self.sig_out = Signal(pspec.width)
13 self.width = pspec.width
14
15 def elaborate(self, platform):
16 m = Module()
17 comb = m.d.comb
18
19 numrec = FPNumBaseRecord(self.width, False)
20
21 sign = Signal(1)
22 comb += sign.eq(self.sig_in[-1])
23
24 absv = Signal.like(self.sig_in)
25 comb += absv.eq(Mux(sign, -self.sig_in, self.sig_in))
26
27 m.submodules.clzx = clz = CLZ(self.sig_in.width)
28
29 count = Signal.like(clz.lz)
30
31 comb += clz.sig_in.eq(absv)
32 comb += count.eq(clz.lz)
33
34 normalized = Signal(unsigned(self.sig_in.width))
35
36 comb += normalized.eq(absv << (count-1))
37
38 comb += numrec.m.eq(normalized[-(numrec.m_width+1):-1])
39 comb += numrec.s.eq(sign)
40 comb += numrec.e.eq(-count+1)
41
42 comb += self.sig_out.eq(numrec.create2(numrec.s, numrec.e, numrec.m))
43 return m
44
45 class CordicRenormalize(PipeModBase):
46 def __init__(self, pspec):
47 super().__init__(pspec, "cordicrenorm")
48
49 def ispec(self):
50 return CordicData(self.pspec)
51
52 def ospec(self):
53 return CordicOutputData(self.pspec)
54
55 def elaborate(self, platform):
56 m = Module()
57 comb = m.d.comb
58
59 m.submodules.normx = normx = Norm(self.pspec)
60 m.submodules.normy = normy = Norm(self.pspec)
61
62 comb += [
63 normx.sig_in.eq(self.i.x),
64 normy.sig_in.eq(self.i.y),
65 ]
66
67 comb += self.o.x.eq(normx.sig_out)
68 comb += self.o.y.eq(normy.sig_out)
69
70 comb += self.o.ctx.eq(self.i.ctx)
71 return m