split out SVEXTRA field selection/decoding into separate class SVP64ExtraSpec
[soc.git] / src / soc / decoder / power_decoder2.py
index 71b2b0788d952484d85a4beb180b238533914f41..88121f0eaff0836d3b5b192deb13fd219f282482 100644 (file)
@@ -79,14 +79,10 @@ class SPRMap(Elaboratable):
         return m
 
 
-class SVP64RegExtra(Elaboratable):
-    """SVP64RegExtra - decodes SVP64 Extra fields to determine reg extension
+class SVP64ExtraSpec(Elaboratable):
+    """SVP64ExtraSpec - decodes SVP64 Extra specification.
 
-    incoming 5-bit GPR/FP is turned into a 7-bit and marked as scalar/vector
-    depending on info in one of the positions in the EXTRA field.
-
-    designed so that "no change" to the 5-bit register number occurs if
-    SV either does not apply or the relevant EXTRA2/3 field bits are zero.
+    selects the required EXTRA2/3 field.
 
     see https://libre-soc.org/openpower/sv/svp64/
     """
@@ -94,17 +90,12 @@ class SVP64RegExtra(Elaboratable):
         self.extra   = Signal(10, reset_less=True)
         self.etype   = Signal(SVEtype, reset_less=True) # 2 or 3 bits
         self.idx     = Signal(SVEXTRA, reset_less=True) # which part of extra
-        self.reg_in  = Signal(5) # incoming reg number (5 bits, RA, RB)
-        self.reg_out = Signal(7) # extra-augmented output (7 bits)
-        self.isvec   = Signal(1) # reg is marked as vector if true
+        self.spec  = Signal(3) # EXTRA spec for the register
 
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
-
-        # first get the spec.  if not changed it's "scalar identity behaviour"
-        # which is zero which is ok.
-        spec = Signal(3)
+        spec = self.spec
 
         # back in the LDSTRM-* and RM-* files generated by sv_analysis.py
         # we marked every op with an Etype: EXTRA2 or EXTRA3, and also said
@@ -133,6 +124,34 @@ class SVP64RegExtra(Elaboratable):
                         comb += spec.eq(self.extra[6:9])
                     # cannot fit more than 9 bits so there is no 4th thing
 
+        return m
+
+
+class SVP64RegExtra(SVP64ExtraSpec):
+    """SVP64RegExtra - decodes SVP64 Extra fields to determine reg extension
+
+    incoming 5-bit GPR/FP is turned into a 7-bit and marked as scalar/vector
+    depending on info in one of the positions in the EXTRA field.
+
+    designed so that "no change" to the 5-bit register number occurs if
+    SV either does not apply or the relevant EXTRA2/3 field bits are zero.
+
+    see https://libre-soc.org/openpower/sv/svp64/
+    """
+    def __init__(self):
+        SVP64ExtraSpec.__init__(self)
+        self.reg_in  = Signal(5) # incoming reg number (5 bits, RA, RB)
+        self.reg_out = Signal(7) # extra-augmented output (7 bits)
+        self.isvec   = Signal(1) # reg is marked as vector if true
+
+    def elaborate(self, platform):
+        m = super().elaborate(platform)
+        comb = m.d.comb
+
+        # first get the spec.  if not changed it's "scalar identity behaviour"
+        # which is zero which is ok.
+        spec = self.spec
+
         # now decode it. bit 2 is "scalar/vector".  note that spec could be zero
         #  from above, which (by design) has the effect of "no change", below.
 
@@ -669,7 +688,9 @@ class DecodeCRIn(Elaboratable):
 
         comb += self.cr_bitfield.ok.eq(0)
         comb += self.cr_bitfield_b.ok.eq(0)
+        comb += self.cr_bitfield_o.ok.eq(0)
         comb += self.whole_reg.ok.eq(0)
+
         with m.Switch(self.sel_in):
             with m.Case(CRInSel.NONE):
                 pass  # No bitfield activated