FSGNJ: Replace use of Switch() with explicit muxes
[ieee754fpu.git] / src / ieee754 / fsgnj / fsgnj.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 FSGNJPipeMod(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, "fsgnj")
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 width = self.pspec.width
36 comb = m.d.comb
37
38 z1 = self.o.z
39 a = self.i.a
40 b = self.i.b
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 comb += [a1.v.eq(self.i.a),
46 b1.v.eq(self.i.b)]
47
48 opcode = self.i.ctx.op
49
50 sign = Signal()
51
52 sign = Mux(opcode[0], ~b1.s, b1.s)
53 sign = Mux(opcode[1], sign ^ a1.s, sign)
54
55
56 comb += z1.eq(a1.fp.create2(sign, a1.e, a1.m))
57
58 # copy the context (muxid, operator)
59 comb += self.o.ctx.eq(self.i.ctx)
60
61 return m