1 # This stage is intended to prepare the multiplication operands
3 from nmigen
import (Module
, Signal
, Mux
)
4 from nmutil
.pipemodbase
import PipeModBase
5 from soc
.fu
.div
.pipe_data
import DivInputData
6 from soc
.fu
.mul
.pipe_data
import MulIntermediateData
7 from ieee754
.part
.partsig
import SimdSignal
8 from nmutil
.util
import eq32
10 class MulMainStage1(PipeModBase
):
11 def __init__(self
, pspec
):
12 super().__init
__(pspec
, "mul1")
15 return DivInputData(self
.pspec
) # defines pipeline stage input format
18 return MulIntermediateData(self
.pspec
) # pipeline stage output format
20 def elaborate(self
, platform
):
21 XLEN
= self
.pspec
.XLEN
25 # convenience variables
26 a
, b
, op
= self
.i
.a
, self
.i
.b
, self
.i
.ctx
.op
27 a_o
, b_o
, neg_res_o
= self
.o
.a
, self
.o
.b
, self
.o
.neg_res
28 neg_res_o
, neg_res32_o
= self
.o
.neg_res
, self
.o
.neg_res32
30 # check if op is 32-bit, and get sign bit from operand a
31 is_32bit
= Signal(reset_less
=True)
32 sign_a
= Signal(reset_less
=True)
33 sign_b
= Signal(reset_less
=True)
34 sign32_a
= Signal(reset_less
=True)
35 sign32_b
= Signal(reset_less
=True)
36 comb
+= is_32bit
.eq(op
.is_32bit
)
38 # work out if a/b are negative (check 32-bit / signed)
39 comb
+= sign_a
.eq(Mux(op
.is_32bit
, a
[31], a
[XLEN
-1]) & op
.is_signed
)
40 comb
+= sign_b
.eq(Mux(op
.is_32bit
, b
[31], b
[XLEN
-1]) & op
.is_signed
)
41 comb
+= sign32_a
.eq(a
[31] & op
.is_signed
)
42 comb
+= sign32_b
.eq(b
[31] & op
.is_signed
)
44 # work out if result is negative sign
45 comb
+= neg_res_o
.eq(sign_a ^ sign_b
)
46 comb
+= neg_res32_o
.eq(sign32_a ^ sign32_b
) # pass through for OV32
48 # negation of a 64-bit value produces the same lower 32-bit
49 # result as negation of just the lower 32-bits, so we don't
50 # need to do anything special before negating
51 abs_a
= Signal(XLEN
, reset_less
=True)
52 abs_b
= Signal(XLEN
, reset_less
=True)
53 comb
+= abs_a
.eq(Mux(sign_a
, -a
, a
))
54 comb
+= abs_b
.eq(Mux(sign_b
, -b
, b
))
56 # set up 32/64 bit inputs
57 comb
+= eq32(is_32bit
, a_o
, abs_a
)
58 comb
+= eq32(is_32bit
, b_o
, abs_b
)
60 ###### XER and context, both pass-through #####
62 comb
+= self
.o
.xer_so
.eq(self
.i
.xer_so
)
63 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)