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, op_wid
=None):
17 # NOTE: difference between z and oz is that oz is created by
18 # special-cases module(s) and will propagate, along with its
19 # "bypass" signal out_do_z, through the pipeline, *disabling*
20 # all processing of all subsequent stages.
21 self
.a
= FPNumBaseRecord(width
, m_extra
) # operand a
22 self
.b
= FPNumBaseRecord(width
, m_extra
) # operand b
23 self
.z
= FPNumBaseRecord(width
, False) # denormed result
24 self
.oz
= Signal(width
, reset_less
=True) # "finished" (bypass) result
25 self
.out_do_z
= Signal(reset_less
=True) # "bypass" enabled
26 self
.mid
= Signal(id_wid
, reset_less
=True) # multiplexer ID
29 self
.op
= Signal(op_wid
, reset_less
=True) # operand
43 ret
= [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
44 self
.a
.eq(i
.a
), self
.b
.eq(i
.b
), self
.mid
.eq(i
.mid
)]
46 ret
.append(self
.op
.eq(i
.op
))
50 class FPAddDeNormMod(FPState
, Elaboratable
):
52 def __init__(self
, width
, id_wid
, m_extra
=True, op_wid
=None):
55 self
.m_extra
= m_extra
61 return FPSCData(self
.width
, self
.id_wid
, self
.m_extra
, self
.op_wid
)
64 return FPSCData(self
.width
, self
.id_wid
, self
.m_extra
, self
.op_wid
)
69 def setup(self
, m
, i
):
70 """ links module to inputs and outputs
72 m
.submodules
.denormalise
= self
73 m
.d
.comb
+= self
.i
.eq(i
)
75 def elaborate(self
, platform
):
77 m
.submodules
.denorm_in_a
= in_a
= FPNumBase(self
.i
.a
)
78 m
.submodules
.denorm_in_b
= in_b
= FPNumBase(self
.i
.b
)
79 #m.submodules.denorm_out_a = self.o.a
80 #m.submodules.denorm_out_b = self.o.b
81 #m.submodules.denorm_out_z = self.o.z
83 with m
.If(~self
.i
.out_do_z
):
84 # XXX hmmm, don't like repeating identical code
85 m
.d
.comb
+= self
.o
.a
.eq(self
.i
.a
)
86 with m
.If(in_a
.exp_n127
):
87 m
.d
.comb
+= self
.o
.a
.e
.eq(self
.i
.a
.N126
) # limit a exponent
89 m
.d
.comb
+= self
.o
.a
.m
[-1].eq(1) # set top mantissa bit
91 m
.d
.comb
+= self
.o
.b
.eq(self
.i
.b
)
92 with m
.If(in_b
.exp_n127
):
93 m
.d
.comb
+= self
.o
.b
.e
.eq(self
.i
.b
.N126
) # limit a exponent
95 m
.d
.comb
+= self
.o
.b
.m
[-1].eq(1) # set top mantissa bit
97 m
.d
.comb
+= self
.o
.mid
.eq(self
.i
.mid
)
98 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
99 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
100 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
105 class FPAddDeNorm(FPState
):
107 def __init__(self
, width
, id_wid
):
108 FPState
.__init
__(self
, "denormalise")
109 self
.mod
= FPAddDeNormMod(width
)
110 self
.out_a
= FPNumBaseRecord(width
)
111 self
.out_b
= FPNumBaseRecord(width
)
113 def setup(self
, m
, i
):
114 """ links module to inputs and outputs
118 m
.d
.sync
+= self
.out_a
.eq(self
.mod
.out_a
)
119 m
.d
.sync
+= self
.out_b
.eq(self
.mod
.out_b
)
122 # Denormalised Number checks