1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
6 from nmigen
.cli
import main
, verilog
9 from fpbase
import FPNumIn
, FPNumOut
, FPNumBase
10 from fpbase
import FPState
15 def __init__(self
, width
, id_wid
):
16 self
.a
= FPNumBase(width
, True)
17 self
.b
= FPNumBase(width
, True)
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)
24 return [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
25 self
.a
.eq(i
.a
), self
.b
.eq(i
.b
), self
.mid
.eq(i
.mid
)]
28 class FPAddDeNormMod(FPState
):
30 def __init__(self
, width
, id_wid
):
37 return FPSCData(self
.width
, self
.id_wid
)
40 return FPSCData(self
.width
, self
.id_wid
)
45 def setup(self
, m
, i
):
46 """ links module to inputs and outputs
48 m
.submodules
.denormalise
= self
49 m
.d
.comb
+= self
.i
.eq(i
)
51 def elaborate(self
, platform
):
53 m
.submodules
.denorm_in_a
= self
.i
.a
54 m
.submodules
.denorm_in_b
= self
.i
.b
55 m
.submodules
.denorm_out_a
= self
.o
.a
56 m
.submodules
.denorm_out_b
= self
.o
.b
58 with m
.If(~self
.i
.out_do_z
):
59 # XXX hmmm, don't like repeating identical code
60 m
.d
.comb
+= self
.o
.a
.eq(self
.i
.a
)
61 with m
.If(self
.i
.a
.exp_n127
):
62 m
.d
.comb
+= self
.o
.a
.e
.eq(self
.i
.a
.N126
) # limit a exponent
64 m
.d
.comb
+= self
.o
.a
.m
[-1].eq(1) # set top mantissa bit
66 m
.d
.comb
+= self
.o
.b
.eq(self
.i
.b
)
67 with m
.If(self
.i
.b
.exp_n127
):
68 m
.d
.comb
+= self
.o
.b
.e
.eq(self
.i
.b
.N126
) # limit a exponent
70 m
.d
.comb
+= self
.o
.b
.m
[-1].eq(1) # set top mantissa bit
72 m
.d
.comb
+= self
.o
.mid
.eq(self
.i
.mid
)
73 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
74 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
75 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
80 class FPAddDeNorm(FPState
):
82 def __init__(self
, width
, id_wid
):
83 FPState
.__init
__(self
, "denormalise")
84 self
.mod
= FPAddDeNormMod(width
)
85 self
.out_a
= FPNumBase(width
)
86 self
.out_b
= FPNumBase(width
)
88 def setup(self
, m
, i
):
89 """ links module to inputs and outputs
93 m
.d
.sync
+= self
.out_a
.eq(self
.mod
.out_a
)
94 m
.d
.sync
+= self
.out_b
.eq(self
.mod
.out_b
)
97 # Denormalised Number checks