5c91976d65a526177eab4a7e9cbca5959be732f8
[ieee754fpu.git] / src / ieee754 / fpmax / fpmax.py
1 # IEEE Floating Point Conversion, FSGNJ
2 # Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
4
5
6 from nmigen import Module, Signal, Cat, Mux
7
8 from nmutil.pipemodbase import PipeModBase
9 from ieee754.fpcommon.basedata import FPBaseData
10 from ieee754.fpcommon.packdata import FPPackData
11 from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
12
13
14 class FPMAXPipeMod(PipeModBase):
15 """ FP Sign injection - replaces operand A's sign bit with one
16 generated from operand B
17
18 self.ctx.i.op & 0x3 == 0x0 : Copy sign bit from operand B
19 self.ctx.i.op & 0x3 == 0x1 : Copy inverted sign bit from operand B
20 self.ctx.i.op & 0x3 == 0x2 : Sign bit is A's sign XOR B's sign
21 """
22 def __init__(self, in_pspec):
23 self.in_pspec = in_pspec
24 super().__init__(in_pspec, "fpmax")
25
26 def ispec(self):
27 return FPBaseData(self.in_pspec)
28
29 def ospec(self):
30 return FPPackData(self.in_pspec)
31
32 def elaborate(self, platform):
33 m = Module()
34
35 # useful clarity variables
36 comb = m.d.comb
37 width = self.pspec.width
38 opcode = self.i.ctx.op
39 z1 = self.o.z
40
41 a1 = FPNumBaseRecord(width, False)
42 b1 = FPNumBaseRecord(width, False)
43 m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
44 m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
45
46 m.d.comb += [a1.v.eq(self.i.a),
47 b1.v.eq(self.i.b)]
48
49 has_nan = Signal()
50 comb += has_nan.eq(a1.is_nan | b1.is_nan)
51 both_nan = Signal()
52 comb += both_nan.eq(a1.is_nan & b1.is_nan)
53 with m.If(has_nan):
54 with m.If(both_nan):
55 comb += z1.eq(a1.fp.nan2(0))
56 with m.Else():
57 comb += z1.eq(Mux(a1.is_nan, self.i.b, self.i.a))
58 with m.Else():
59 with m.If(a1.s != b1.s):
60
61 comb += z1.eq(Mux(a1.s ^ opcode[0], self.i.b, self.i.a))
62 with m.Else():
63 gt = Signal()
64 sign = Signal()
65 comb += sign.eq(a1.s)
66 comb += gt.eq(a1.v > b1.v)
67 comb += z1.eq(Mux(gt ^ sign ^ opcode[0],
68 self.i.a, self.i.b))
69
70
71 # copy the context (muxid, operator)
72 comb += self.o.ctx.eq(self.i.ctx)
73
74 return m