Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / fu / common_input_stage.py
index 2f399b49e39b37b4bdf6e517e0850e8abe15ef85..53e023ad6bb68d289bacccc9f5f627936961753e 100644 (file)
@@ -3,8 +3,8 @@
 # generation for subtraction, should happen here
 from nmigen import (Module, Signal)
 from nmutil.pipemodbase import PipeModBase
-from soc.decoder.power_enums import InternalOp
-from soc.decoder.power_enums import CryIn
+from openpower.decoder.power_enums import MicrOp
+from openpower.decoder.power_enums import CryIn
 
 
 class CommonInputStage(PipeModBase):
@@ -12,29 +12,60 @@ class CommonInputStage(PipeModBase):
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
+        op = self.i.ctx.op
 
         ##### operand A #####
 
         # operand a to be as-is or inverted
         a = Signal.like(self.i.a)
 
-        with m.If(self.i.ctx.op.invert_a):
-            comb += a.eq(~self.i.a)
-        with m.Else():
+        op_to_invert = 'ra'
+        if hasattr(self, "invert_op"):
+            op_to_invert = self.invert_op
+
+        if hasattr(op, "invert_in") and op_to_invert == 'ra':
+            with m.If(op.invert_in):
+                comb += a.eq(~self.i.a)
+            with m.Else():
+                comb += a.eq(self.i.a)
+        else:
             comb += a.eq(self.i.a)
 
-        comb += self.o.a.eq(a)
+        # SV zeroing on predicate source zeros the input
+        with m.If(~op.sv_pred_sz):
+            comb += self.o.a.eq(a)
+
+        ##### operand B #####
+
+        # operand b to be as-is or inverted
+        b = Signal.like(self.i.b)
+
+        if hasattr(op, "invert_in") and op_to_invert == 'rb':
+            with m.If(op.invert_in):
+                comb += b.eq(~self.i.b)
+            with m.Else():
+                comb += b.eq(self.i.b)
+        else:
+            comb += b.eq(self.i.b)
+
+        # SV zeroing on predicate source zeros the input
+        with m.If(~op.sv_pred_sz):
+            comb += self.o.b.eq(b)
 
         ##### carry-in #####
 
         # either copy incoming carry or set to 1/0 as defined by op
-        with m.Switch(self.i.ctx.op.input_carry):
-            with m.Case(CryIn.ZERO):
-                comb += self.o.xer_ca.eq(0b00)
-            with m.Case(CryIn.ONE):
-                comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
-            with m.Case(CryIn.CA):
-                comb += self.o.xer_ca.eq(self.i.xer_ca)
+        if hasattr(self.i, "xer_ca"): # hack (for now - for LogicalInputData)
+            with m.Switch(op.input_carry):
+                with m.Case(CryIn.ZERO):
+                    comb += self.o.xer_ca.eq(0b00)
+                with m.Case(CryIn.ONE):
+                    comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
+                with m.Case(CryIn.CA):
+                    comb += self.o.xer_ca.eq(self.i.xer_ca)
+                # XXX TODO
+                #with m.Case(CryIn.OV):
+                #    comb += self.o.xer_ca.eq(self.i.xer_ov)
 
         ##### sticky overflow and context (both pass-through) #####