1 """IEEE754 Floating Point Adder Pipeline
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
7 from nmigen
import Module
, Signal
, Cat
, Mux
8 from nmigen
.cli
import main
, verilog
10 from nmutil
.pipemodbase
import PipeModBase
12 from ieee754
.fpcommon
.denorm
import FPSCData
13 from ieee754
.fpcommon
.getop
import FPPipeContext
14 from ieee754
.fpadd
.datastruct
import FPAddStage0Data
17 class FPAddStage0Mod(PipeModBase
):
19 def __init__(self
, pspec
):
20 super().__init
__(pspec
, "add0")
23 return FPSCData(self
.pspec
, True)
26 return FPAddStage0Data(self
.pspec
)
28 def elaborate(self
, platform
):
33 assert len(a
.m
) == len(b
.m
) # op lengths must be equal
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)
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
),
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
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 +/-
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
)