remove redundant imports
[ieee754fpu.git] / src / ieee754 / fcvt / upsize.py
1 # IEEE754 Floating Point Conversion
2 # Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3
4
5 import sys
6 import functools
7
8 from nmigen import Module, Signal, Cat, Const, Mux, Elaboratable
9 from nmigen.cli import main, verilog
10
11 from ieee754.fpcommon.getop import FPADDBaseData
12 from ieee754.fpcommon.postcalc import FPAddStage1Data
13 from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
14
15
16 class FPCVTUpConvertMod(Elaboratable):
17 """ FP up-conversion (lower to higher bitwidth)
18 """
19 def __init__(self, in_pspec, out_pspec):
20 self.in_pspec = in_pspec
21 self.out_pspec = out_pspec
22 self.i = self.ispec()
23 self.o = self.ospec()
24
25 def ispec(self):
26 return FPADDBaseData(self.in_pspec)
27
28 def ospec(self):
29 return FPAddStage1Data(self.out_pspec, e_extra=False)
30
31 def setup(self, m, i):
32 """ links module to inputs and outputs
33 """
34 m.submodules.upconvert = self
35 m.d.comb += self.i.eq(i)
36
37 def process(self, i):
38 return self.o
39
40 def elaborate(self, platform):
41 m = Module()
42 comb = m.d.comb
43
44 #m.submodules.sc_out_z = self.o.z
45
46 # decode: XXX really should move to separate stage
47 print("in_width out", self.in_pspec.width,
48 self.out_pspec.width)
49 a1 = FPNumBaseRecord(self.in_pspec.width, False)
50 print("a1", a1.width, a1.rmw, a1.e_width, a1.e_start, a1.e_end)
51 m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
52 comb += a1.v.eq(self.i.a)
53 z1 = self.o.z
54 print("z1", z1.width, z1.rmw, z1.e_width, z1.e_start, z1.e_end)
55
56 me = a1.rmw
57 ms = self.o.z.rmw - a1.rmw
58 print("ms-me", ms, me, self.o.z.rmw, a1.rmw)
59
60 # conversion can mostly be done manually...
61 comb += self.o.z.s.eq(a1.s)
62 comb += self.o.z.e.eq(a1.e)
63 comb += self.o.z.m[ms:].eq(a1.m)
64 comb += self.o.z.create(a1.s, a1.e, self.o.z.m) # ... here
65
66 # initialise rounding to all zeros (deactivate)
67 comb += self.o.of.guard.eq(0)
68 comb += self.o.of.round_bit.eq(0)
69 comb += self.o.of.sticky.eq(0)
70 comb += self.o.of.m0.eq(a1.m[0])
71
72 # most special cases active (except tiny-number normalisation, below)
73 comb += self.o.out_do_z.eq(1)
74
75 # detect NaN/Inf first
76 with m.If(a1.exp_128):
77 with m.If(~a1.m_zero):
78 comb += self.o.z.nan(0) # RISC-V wants normalised NaN
79 with m.Else():
80 comb += self.o.z.inf(a1.s) # RISC-V wants signed INF
81 with m.Else():
82 with m.If(a1.exp_n127):
83 with m.If(~a1.m_zero):
84 comb += self.o.z.m[ms:].eq(Cat(0, a1.m))
85 comb += self.o.out_do_z.eq(0) # activate normalisation
86 with m.Else():
87 # RISC-V zero needs actual zero
88 comb += self.o.z.zero(a1.s)
89
90 # copy the context (muxid, operator)
91 comb += self.o.oz.eq(self.o.z.v)
92 comb += self.o.ctx.eq(self.i.ctx)
93
94 return m