6aa205616367c9b9f1ea1703d86f00dd7176d97f
1 """IEEE754 Floating Point Multiplier Pipeline
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
7 from nmigen
import Module
, Signal
, Elaboratable
8 from nmigen
.cli
import main
, verilog
10 from ieee754
.fpcommon
.postcalc
import FPAddStage1Data
11 from ieee754
.fpmul
.mul0
import FPMulStage0Data
14 class FPMulStage1Mod(Elaboratable
):
15 """ Second stage of mul: preparation for normalisation.
18 def __init__(self
, pspec
):
24 return FPMulStage0Data(self
.pspec
)
27 return FPAddStage1Data(self
.pspec
)
32 def setup(self
, m
, i
):
33 """ links module to inputs and outputs
35 m
.submodules
.mul1
= self
36 m
.d
.comb
+= self
.i
.eq(i
)
38 def elaborate(self
, platform
):
40 m
.d
.comb
+= self
.o
.z
.eq(self
.i
.z
)
41 with m
.If(~self
.i
.out_do_z
):
42 # results are in the range 0.25 to 0.999999999999
43 # sometimes the MSB will be zero, (0.5 * 0.5 = 0.25 which
44 # in binary is 0b010000) so to compensate for that we have
45 # to shift the mantissa up (and reduce the exponent by 1)
46 p
= Signal(len(self
.i
.product
), reset_less
=True)
47 with m
.If(self
.i
.product
[-1]):
48 m
.d
.comb
+= p
.eq(self
.i
.product
)
50 # get 1 bit of extra accuracy if the mantissa top bit is zero
51 m
.d
.comb
+= p
.eq(self
.i
.product
<<1)
52 m
.d
.comb
+= self
.o
.z
.e
.eq(self
.i
.z
.e
-1)
54 # top bits are mantissa, then guard and round, and the rest of
55 # the product is sticky
58 self
.o
.z
.m
.eq(p
[mw
+2:]), # mantissa
59 self
.o
.of
.m0
.eq(p
[mw
+2]), # copy of LSB
60 self
.o
.of
.guard
.eq(p
[mw
+1]), # guard
61 self
.o
.of
.round_bit
.eq(p
[mw
]), # round
62 self
.o
.of
.sticky
.eq(p
[0:mw
].bool()) # sticky
65 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
66 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
67 m
.d
.comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)