1 # This stage is intended to do most of the work of executing multiply
2 from nmigen
import (Module
, Signal
, Mux
)
3 from nmutil
.pipemodbase
import PipeModBase
4 from soc
.fu
.alu
.pipe_data
import ALUInputData
5 from soc
.fu
.mul
.pipe_data
import MulIntermediateData
6 from ieee754
.part
.partsig
import PartitionedSignal
9 class MulMainStage1(PipeModBase
):
10 def __init__(self
, pspec
):
11 super().__init
__(pspec
, "mul1")
14 return ALUInputData(self
.pspec
) # defines pipeline stage input format
17 return MulIntermediateData(self
.pspec
) # pipeline stage output format
19 def elaborate(self
, platform
):
23 # convenience variables
24 a
, b
= self
.i
.a
, self
.i
.b
25 a_o
, b_o
, neg_res_o
= self
.o
.a
, self
.o
.b
, self
.o
.neg_res
27 # check if op is 32-bit, and get sign bit from operand a
28 is_32bit
= Signal(reset_less
=True)
29 sign_a
= Signal(reset_less
=True)
30 sign_b
= Signal(reset_less
=True)
31 comb
+= is_32bit
.eq(op
.is_32bit
)
33 # work out if a/b are negative (check 32-bit / signed)
34 comb
+= sign_a
.eq(Mux(op
.is_32bit
, a
[31], a
[63]) & op
.is_signed
)
35 comb
+= sign_b
.eq(Mux(op
.is_32bit
, b
[31], b
[63]) & op
.is_signed
)
37 # work out if result is negative sign
38 comb
+= neg_res_o
.eq(sign_a ^ sign_b
)
40 # negation of a 64-bit value produces the same lower 32-bit
41 # result as negation of just the lower 32-bits, so we don't
42 # need to do anything special before negating
43 comb
+= a_o
.eq(Mux(sign_a
, -a
, a
))
44 comb
+= b_o
.eq(Mux(sign_b
, -b
, b
))
46 ###### XER and context, both pass-through #####
48 comb
+= self
.o
.xer_ca
.data
.eq(self
.i
.xer_ca
)
49 comb
+= self
.o
.xer_so
.data
.eq(self
.i
.xer_so
)
50 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)