1 # IEEE754 Floating Point Conversion
2 # Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
8 from nmigen
import Module
, Signal
, Cat
, Const
, Mux
, Elaboratable
9 from nmigen
.cli
import main
, verilog
11 from ieee754
.fpcommon
.getop
import FPADDBaseData
12 from ieee754
.fpcommon
.postcalc
import FPAddStage1Data
13 from ieee754
.fpcommon
.fpbase
import FPNumDecode
, FPNumBaseRecord
16 class FPCVTUpConvertMod(Elaboratable
):
17 """ FP up-conversion (lower to higher bitwidth)
19 def __init__(self
, in_pspec
, out_pspec
):
20 self
.in_pspec
= in_pspec
21 self
.out_pspec
= out_pspec
26 return FPADDBaseData(self
.in_pspec
)
29 return FPAddStage1Data(self
.out_pspec
, e_extra
=False)
31 def setup(self
, m
, i
):
32 """ links module to inputs and outputs
34 m
.submodules
.upconvert
= self
35 m
.d
.comb
+= self
.i
.eq(i
)
40 def elaborate(self
, platform
):
44 #m.submodules.sc_out_z = self.o.z
46 # decode: XXX really should move to separate stage
47 print("in_width out", self
.in_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
)
54 print("z1", z1
.width
, z1
.rmw
, z1
.e_width
, z1
.e_start
, z1
.e_end
)
57 ms
= self
.o
.z
.rmw
- a1
.rmw
58 print("ms-me", ms
, me
, self
.o
.z
.rmw
, a1
.rmw
)
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
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])
72 # most special cases active (except tiny-number normalisation, below)
73 comb
+= self
.o
.out_do_z
.eq(1)
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
80 comb
+= self
.o
.z
.inf(a1
.s
) # RISC-V wants signed INF
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
87 # RISC-V zero needs actual zero
88 comb
+= self
.o
.z
.zero(a1
.s
)
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
)