1 # This stage is intended to adjust the input data before sending it to
2 # the acutal ALU. Things like handling inverting the input, carry_in
3 # generation for subtraction, should happen here
4 from nmigen
import (Module
, Signal
)
5 from nmutil
.pipemodbase
import PipeModBase
6 from soc
.decoder
.power_enums
import InternalOp
7 from soc
.decoder
.power_enums
import CryIn
10 class CommonInputStage(PipeModBase
):
12 def elaborate(self
, platform
):
18 # operand a to be as-is or inverted
19 a
= Signal
.like(self
.i
.a
)
21 with m
.If(self
.i
.ctx
.op
.invert_a
):
22 comb
+= a
.eq(~self
.i
.a
)
24 comb
+= a
.eq(self
.i
.a
)
26 comb
+= self
.o
.a
.eq(a
)
30 # either copy incoming carry or set to 1/0 as defined by op
31 with m
.Switch(self
.i
.ctx
.op
.input_carry
):
32 with m
.Case(CryIn
.ZERO
):
33 comb
+= self
.o
.xer_ca
.eq(0b00)
34 with m
.Case(CryIn
.ONE
):
35 comb
+= self
.o
.xer_ca
.eq(0b11) # XER CA/CA32
36 with m
.Case(CryIn
.CA
):
37 comb
+= self
.o
.xer_ca
.eq(self
.i
.xer_ca
)
39 ##### sticky overflow and context (both pass-through) #####
41 if hasattr(self
.o
, "xer_so"): # hack (for now - for LogicalInputData)
42 comb
+= self
.o
.xer_so
.eq(self
.i
.xer_so
)
43 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)