1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Mux
7 from nmutil
.pipemodbase
import PipeModBase
8 from ieee754
.fpcommon
.fpbase
import FPFormat
, FPNumBaseRecord
, FPRoundingMode
9 from ieee754
.fpcommon
.getop
import FPPipeContext
10 from ieee754
.fpcommon
.postnormalise
import FPNorm1Data
15 def __init__(self
, pspec
):
17 self
.z
= FPNumBaseRecord(m_extra
=False, name
="z",
18 fpformat
=FPFormat
.from_pspec(pspec
))
19 self
.ctx
= FPPipeContext(pspec
)
20 self
.muxid
= self
.ctx
.muxid
21 # pipeline bypass [data comes from specialcases]
22 self
.out_do_z
= Signal(reset_less
=True)
23 self
.oz
= Signal(width
, reset_less
=True)
25 self
.rm
= Signal(FPRoundingMode
, reset
=FPRoundingMode
.DEFAULT
)
29 ret
= [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
30 self
.ctx
.eq(i
.ctx
), self
.rm
.eq(i
.rm
)]
34 class FPRoundMod(PipeModBase
):
36 def __init__(self
, pspec
):
37 super().__init
__(pspec
, "roundz")
40 return FPNorm1Data(self
.pspec
)
43 return FPRoundData(self
.pspec
)
45 def elaborate(self
, platform
):
49 comb
+= self
.o
.eq(self
.i
) # copies muxid, z, out_do_z
52 msb1s
= Signal(reset_less
=True)
53 comb
+= msb1s
.eq(self
.i
.z
.m
.all()) # all 1s
54 comb
+= self
.o
.z
.m
.eq(Mux(self
.i
.roundz
, im
+1, im
)) # mantissa up
55 comb
+= self
.o
.z
.e
.eq(Mux(msb1s
& self
.i
.roundz
, ie
+ 1, ie
)) # exp up