switch to exact version of cython
[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 a = self.i.a
32 b = self.i.b
33 assert len(a.m) == len(b.m) # op lengths must be equal
34
35 # store intermediate tests (and zero-extended mantissas)
36 seq = Signal(reset_less=True)
37 mge = Signal(reset_less=True)
38 sm = Signal(reset_less=True)
39 op1 = Signal(len(a.m)+1, reset_less=True)
40 op2 = Signal(len(b.m)+1, reset_less=True)
41
42 # logic is as follows:
43 # * same-sign (both negative or both positive) add mantissas
44 # * opposite sign, subtract b mantissa from a
45 # * a mantissa greater than b, use a
46 # * b mantissa greater than a, use b
47 comb += [seq.eq(a.s == b.s),
48 mge.eq(a.m >= b.m),
49 sm.eq(seq | mge),
50 op1.eq(Cat(Mux(sm, a.m, b.m), 0)), # swap a and b
51 op2.eq(Cat(Mux(sm, b.m, a.m), 0)), # swap b and a
52 ]
53
54 # perform add into output z (s/m/e)
55 comb += self.o.z.e.eq(a.e) # exponent same
56 comb += self.o.z.s.eq(Mux(sm, a.s, b.s)) # sign swap
57 comb += self.o.tot.eq(Mux(seq, op1 + op2, op1 - op2)) # mantissa +/-
58
59 # pass-through context
60 comb += self.o.oz.eq(self.i.oz)
61 comb += self.o.out_do_z.eq(self.i.out_do_z)
62 comb += self.o.ctx.eq(self.i.ctx)
63 comb += self.o.rm.eq(self.i.rm)
64
65 return m