rework add1 to not use out_do_z and use Mux instead of m.If/Else
[ieee754fpu.git] / src / ieee754 / fpadd / add1.py
1 """IEEE754 Floating Point Multiplier Pipeline
2
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
4
5 """
6
7 from nmigen import Module, Signal, Mux, Cat
8 from nmigen.cli import main, verilog
9 from math import log
10
11 from nmutil.pipemodbase import PipeModBase
12 from ieee754.fpcommon.postcalc import FPPostCalcData
13 from ieee754.fpadd.add0 import FPAddStage0Data
14
15
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)
19
20 if sum is too big (MSB is set), the mantissa needs shifting
21 down and the exponent increased by 1.
22
23 we also need to extract the overflow info: sticky "accumulates"
24 the bottom 2 LSBs if the shift occurs.
25 """
26
27 def __init__(self, pspec):
28 super().__init__(pspec, "add1")
29
30 def ispec(self):
31 return FPAddStage0Data(self.pspec)
32
33 def ospec(self):
34 return FPPostCalcData(self.pspec)
35
36 def elaborate(self, platform):
37 m = Module()
38 comb = m.d.comb
39 z = self.i.z
40 tot = self.i.tot
41
42 # intermediaries
43 msb = Signal(reset_less=True)
44 to = Signal.like(self.i.tot, reset_less=True)
45
46 comb += self.o.z.s.eq(z.s) # copy sign
47 comb += msb.eq(self.i.tot[-1]) # get mantissa MSB
48
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)))
52
53 # this works by adding an extra zero LSB if the MSB is *not* set
54 comb += [
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 ]
62
63 comb += self.o.out_do_z.eq(self.i.out_do_z)
64 comb += self.o.oz.eq(self.i.oz)
65 comb += self.o.ctx.eq(self.i.ctx)
66
67 return m