switch to exact version of cython
[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
12
13 class FSGNJPipeMod(PipeModBase):
14 """ FP Sign injection - replaces operand A's sign bit with one
15 generated from operand B
16
17 self.ctx.i.op & 0x3 == 0x0 : Copy sign bit from operand B
18 self.ctx.i.op & 0x3 == 0x1 : Copy inverted sign bit from operand B
19 self.ctx.i.op & 0x3 == 0x2 : Sign bit is A's sign XOR B's sign
20 """
21 def __init__(self, in_pspec):
22 self.in_pspec = in_pspec
23 super().__init__(in_pspec, "fsgnj")
24
25 def ispec(self):
26 return FPBaseData(self.in_pspec)
27
28 def ospec(self):
29 return FPPackData(self.in_pspec)
30
31 def elaborate(self, platform):
32 m = Module()
33
34 # useful clarity variables
35 comb = m.d.comb
36 width = self.pspec.width
37 opcode = self.i.ctx.op
38 z1 = self.o.z
39 a = self.i.a
40 b = self.i.b
41
42 # Calculate the sign bit, with a chain of muxes. has to be done
43 # this way due to (planned) use of SimdSignal. decreases
44 # readability slightly, but hey.
45
46 # Handle opcodes 0b00 and 0b01, copying or inverting the sign bit of B
47 sign = opcode[0] ^ b[-1] # op[0]=0, sign unmodified, op[0]=1 inverts.
48
49 # Handle opcodes 0b10 and 0b11, XORing sign bits of a and b together.
50 # opcode 0b11 is not defined in the RISCV spec; it is handled
51 # here as equivalent to opcode 0b10 (i.e. a1.s XOR b1.s)
52 # because this requires slightly less logic than making it the
53 # same as opcode 0b00 (1 less Mux).
54 sign = Mux(opcode[1], a[-1] ^ b[-1], sign)
55
56 # Create the floating point number from the sign bit
57 # calculated earlier and the exponent and mantissa of operand a
58 comb += z1.eq(Cat(a[:width-1], sign))
59
60 # copy the context (muxid, operator)
61 comb += self.o.ctx.eq(self.i.ctx)
62
63 return m