1 """IEEE754 Floating Point Multiplier Pipeline
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
7 from nmigen
import Module
, Signal
, Mux
, Cat
8 from nmigen
.cli
import main
, verilog
11 from nmutil
.pipemodbase
import PipeModBase
12 from ieee754
.fpcommon
.postcalc
import FPPostCalcData
13 from ieee754
.fpadd
.add0
import FPAddStage0Data
16 class FPAddStage1Mod(PipeModBase
):
17 """ Second stage of add: preparation for normalisation.
18 detects when tot sum is too big (tot[27] is kinda a carry bit)
20 if sum is too big (MSB is set), the mantissa needs shifting
21 down and the exponent increased by 1.
23 we also need to extract the overflow info: sticky "accumulates"
24 the bottom 2 LSBs if the shift occurs.
27 def __init__(self
, pspec
):
28 super().__init
__(pspec
, "add1")
31 return FPAddStage0Data(self
.pspec
)
34 return FPPostCalcData(self
.pspec
)
36 def elaborate(self
, platform
):
43 msb
= Signal(reset_less
=True)
44 to
= Signal
.like(self
.i
.tot
, reset_less
=True)
46 comb
+= self
.o
.z
.s
.eq(z
.s
) # copy sign
47 comb
+= msb
.eq(self
.i
.tot
[-1]) # get mantissa MSB
49 # mantissa shifted down, exponent increased - if MSB set
50 comb
+= self
.o
.z
.e
.eq(Mux(msb
, z
.e
+ 1, z
.e
))
51 comb
+= to
.eq(Mux(msb
, Cat(tot
, 0), Cat(0, tot
)))
53 # this works by adding an extra zero LSB if the MSB is *not* set
55 self
.o
.z
.m
.eq(to
[4:]),
56 self
.o
.of
.m0
.eq(to
[4]),
57 self
.o
.of
.guard
.eq(to
[3]),
58 self
.o
.of
.round_bit
.eq(to
[2]),
59 # sticky sourced from LSB and shifted if MSB hi, else unshifted
60 self
.o
.of
.sticky
.eq(Mux(msb
, to
[1] | tot
[0], to
[1])),
61 self
.o
.of
.rm
.eq(self
.i
.rm
),
62 self
.o
.of
.sign
.eq(self
.i
.z
.s
),
65 comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
66 comb
+= self
.o
.oz
.eq(self
.i
.oz
)
67 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)