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 openpower
.decoder
.power_enums
import MicrOp
7 from openpower
.decoder
.power_enums
import CryIn
10 class CommonInputStage(PipeModBase
):
12 def elaborate(self
, platform
):
19 # operand a to be as-is or inverted
20 a
= Signal
.like(self
.i
.a
)
23 if hasattr(self
, "invert_op"):
24 op_to_invert
= self
.invert_op
26 if hasattr(op
, "invert_in") and op_to_invert
== 'ra':
27 with m
.If(op
.invert_in
):
28 comb
+= a
.eq(~self
.i
.a
)
30 comb
+= a
.eq(self
.i
.a
)
32 comb
+= a
.eq(self
.i
.a
)
34 # SV zeroing on predicate source zeros the input
35 with m
.If(~op
.sv_pred_sz
):
36 comb
+= self
.o
.a
.eq(a
)
40 # operand b to be as-is or inverted
41 b
= Signal
.like(self
.i
.b
)
43 if hasattr(op
, "invert_in") and op_to_invert
== 'rb':
44 with m
.If(op
.invert_in
):
45 comb
+= b
.eq(~self
.i
.b
)
47 comb
+= b
.eq(self
.i
.b
)
49 comb
+= b
.eq(self
.i
.b
)
51 # SV zeroing on predicate source zeros the input
52 with m
.If(~op
.sv_pred_sz
):
53 comb
+= self
.o
.b
.eq(b
)
57 # either copy incoming carry or set to 1/0 as defined by op
58 if hasattr(self
.i
, "xer_ca"): # hack (for now - for LogicalInputData)
59 with m
.Switch(op
.input_carry
):
60 with m
.Case(CryIn
.ZERO
):
61 comb
+= self
.o
.xer_ca
.eq(0b00)
62 with m
.Case(CryIn
.ONE
):
63 comb
+= self
.o
.xer_ca
.eq(0b11) # XER CA/CA32
64 with m
.Case(CryIn
.CA
):
65 comb
+= self
.o
.xer_ca
.eq(self
.i
.xer_ca
)
67 #with m.Case(CryIn.OV):
68 # comb += self.o.xer_ca.eq(self.i.xer_ov)
70 ##### sticky overflow and context (both pass-through) #####
72 if hasattr(self
.o
, "xer_so"): # hack (for now - for LogicalInputData)
73 comb
+= self
.o
.xer_so
.eq(self
.i
.xer_so
)
74 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)