Expand FSGNJ module to 16 and 64 bit floats
[ieee754fpu.git] / src / ieee754 / fsgnj / fsgnj.py
1 # IEEE Floating Point Conversion
2 # Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3
4 from nmigen import Module, Signal, Cat
5
6 from nmutil.pipemodbase import PipeModBase
7 from ieee754.fpcommon.basedata import FPBaseData
8 from ieee754.fpcommon.packdata import FPPackData
9
10
11 class FSGNJPipeMod(PipeModBase):
12 """ FP Sign injection - replaces operand A's sign bit with one
13 generated from operand B
14
15 self.ctx.i.op & 0x3 == 0x0 : Copy sign bit from operand B
16 self.ctx.i.op & 0x3 == 0x1 : Copy inverted sign bit from operand B
17 self.ctx.i.op & 0x3 == 0x2 : Sign bit is A's sign XOR B's sign
18 """
19 def __init__(self, in_pspec):
20 self.in_pspec = in_pspec
21 super().__init__(in_pspec, "fsgnj")
22
23 def ispec(self):
24 return FPBaseData(self.in_pspec)
25
26 def ospec(self):
27 return FPPackData(self.in_pspec)
28
29 def elaborate(self, platform):
30 m = Module()
31
32 width = self.pspec.width
33 comb = m.d.comb
34
35 z1 = self.o.z
36 a = self.i.a
37 b = self.i.b
38
39 opcode = self.i.ctx.op
40
41 sign = Signal()
42
43 with m.Switch(opcode):
44 with m.Case(0b00):
45 comb += sign.eq(b[-1])
46 with m.Case(0b01):
47 comb += sign.eq(~b[-1])
48 with m.Case(0b10):
49 comb += sign.eq(a[-1] ^ b[-1])
50 with m.Default():
51 comb += sign.eq(b[-1])
52
53 comb += z1.eq(Cat(a[0:width-1], sign))
54
55 # copy the context (muxid, operator)
56 comb += self.o.ctx.eq(self.i.ctx)
57
58 return m