use Mux instead of m.If/Elif on add sign
[ieee754fpu.git] / src / ieee754 / fpadd / add0.py
1 """IEEE754 Floating Point Adder Pipeline
2
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
4
5 """
6
7 from nmigen import Module, Signal, Cat, Mux
8 from nmigen.cli import main, verilog
9
10 from nmutil.pipemodbase import PipeModBase
11
12 from ieee754.fpcommon.denorm import FPSCData
13 from ieee754.fpcommon.getop import FPPipeContext
14 from ieee754.fpadd.datastruct import FPAddStage0Data
15
16
17 class FPAddStage0Mod(PipeModBase):
18
19 def __init__(self, pspec):
20 super().__init__(pspec, "add0")
21
22 def ispec(self):
23 return FPSCData(self.pspec, True)
24
25 def ospec(self):
26 return FPAddStage0Data(self.pspec)
27
28 def elaborate(self, platform):
29 m = Module()
30 comb = m.d.comb
31
32 # store intermediate tests (and zero-extended mantissas)
33 seq = Signal(reset_less=True)
34 mge = Signal(reset_less=True)
35 am0 = Signal(len(self.i.a.m)+1, reset_less=True)
36 bm0 = Signal(len(self.i.b.m)+1, reset_less=True)
37 # same-sign (both negative or both positive) add mantissas
38 comb += [seq.eq(self.i.a.s == self.i.b.s),
39 mge.eq(self.i.a.m >= self.i.b.m),
40 am0.eq(Cat(self.i.a.m, 0)),
41 bm0.eq(Cat(self.i.b.m, 0))
42 ]
43 comb += self.o.z.e.eq(self.i.a.e)
44 comb += self.o.z.s.eq(Mux(seq | mge, self.i.a.s, self.i.b.s))
45 with m.If(seq):
46 comb += [
47 self.o.tot.eq(am0 + bm0),
48 ]
49 # a mantissa greater than b, use a
50 with m.Elif(mge):
51 comb += [
52 self.o.tot.eq(am0 - bm0),
53 ]
54 # b mantissa greater than a, use b
55 with m.Else():
56 comb += [
57 self.o.tot.eq(bm0 - am0),
58 ]
59
60 # pass-through context
61 comb += self.o.oz.eq(self.i.oz)
62 comb += self.o.out_do_z.eq(self.i.out_do_z)
63 comb += self.o.ctx.eq(self.i.ctx)
64
65 return m