1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Elaboratable
6 from nmigen
.cli
import main
, verilog
9 from ieee754
.fpcommon
.fpbase
import FPNumIn
, FPNumOut
, FPNumBaseRecord
10 from ieee754
.fpcommon
.fpbase
import FPState
, FPNumBase
15 def __init__(self
, width
, id_wid
, m_extra
=True):
16 self
.a
= FPNumBase(width
, m_extra
)
17 self
.b
= FPNumBase(width
, m_extra
)
18 self
.z
= FPNumOut(width
, False)
19 self
.oz
= Signal(width
, reset_less
=True)
20 self
.out_do_z
= Signal(reset_less
=True)
21 self
.mid
= Signal(id_wid
, reset_less
=True)
32 return [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
33 self
.a
.eq(i
.a
), self
.b
.eq(i
.b
), self
.mid
.eq(i
.mid
)]
36 class FPAddDeNormMod(FPState
, Elaboratable
):
38 def __init__(self
, width
, id_wid
, m_extra
=True):
41 self
.m_extra
= m_extra
46 return FPSCData(self
.width
, self
.id_wid
, self
.m_extra
)
49 return FPSCData(self
.width
, self
.id_wid
, self
.m_extra
)
54 def setup(self
, m
, i
):
55 """ links module to inputs and outputs
57 m
.submodules
.denormalise
= self
58 m
.d
.comb
+= self
.i
.eq(i
)
60 def elaborate(self
, platform
):
62 m
.submodules
.denorm_in_a
= self
.i
.a
63 m
.submodules
.denorm_in_b
= self
.i
.b
64 m
.submodules
.denorm_in_z
= self
.i
.z
65 m
.submodules
.denorm_out_a
= self
.o
.a
66 m
.submodules
.denorm_out_b
= self
.o
.b
67 m
.submodules
.denorm_out_z
= self
.o
.z
69 with m
.If(~self
.i
.out_do_z
):
70 # XXX hmmm, don't like repeating identical code
71 m
.d
.comb
+= self
.o
.a
.eq(self
.i
.a
)
72 with m
.If(self
.i
.a
.exp_n127
):
73 m
.d
.comb
+= self
.o
.a
.e
.eq(self
.i
.a
.N126
) # limit a exponent
75 m
.d
.comb
+= self
.o
.a
.m
[-1].eq(1) # set top mantissa bit
77 m
.d
.comb
+= self
.o
.b
.eq(self
.i
.b
)
78 with m
.If(self
.i
.b
.exp_n127
):
79 m
.d
.comb
+= self
.o
.b
.e
.eq(self
.i
.b
.N126
) # limit a exponent
81 m
.d
.comb
+= self
.o
.b
.m
[-1].eq(1) # set top mantissa bit
83 m
.d
.comb
+= self
.o
.mid
.eq(self
.i
.mid
)
84 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
85 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
86 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
91 class FPAddDeNorm(FPState
):
93 def __init__(self
, width
, id_wid
):
94 FPState
.__init
__(self
, "denormalise")
95 self
.mod
= FPAddDeNormMod(width
)
96 self
.out_a
= FPNumBase(width
)
97 self
.out_b
= FPNumBase(width
)
99 def setup(self
, m
, i
):
100 """ links module to inputs and outputs
104 m
.d
.sync
+= self
.out_a
.eq(self
.mod
.out_a
)
105 m
.d
.sync
+= self
.out_b
.eq(self
.mod
.out_b
)
108 # Denormalised Number checks