start on SVP64 RM Mode decoder
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Feb 2021 17:19:18 +0000 (17:19 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 28 Feb 2021 17:19:18 +0000 (17:19 +0000)
src/soc/consts.py
src/soc/decoder/power_enums.py
src/soc/sv/svp64.py

index ce13b3e1672d2977c06805837945f931c952b5c2..8d537cd891aca9a1b67cbce5aef410debeef3a63 100644 (file)
@@ -192,6 +192,7 @@ class EXTRA3:
     IDX0 = [0, 1, 2]
     IDX1 = [3, 4, 5]
     IDX2 = [6, 7, 8]
+    MASK = [6, 7, 8]
 
 
 EXTRA3_SIZE = 9
index 10357bd710ce0f0621d162a949cbf236784d0b0f..1254534d41aaa3e5ece31c8f2bafa21229f035f9 100644 (file)
@@ -111,6 +111,7 @@ class Form(Enum):
     EVS = 26
     Z22 = 27
     Z23 = 28
+    SVL = 29 # Simple-V for setvl instruction
 
 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
 
@@ -135,6 +136,12 @@ class SVEXTRA(Enum):
     Idx3 = 4
     Idx_1_2 = 5 # due to weird BA/BB for crops
 
+@unique
+class SVP64PredMode(Enum):
+    ALWAYS = 0
+    INT = 1
+    CR = 2
+
 @unique
 class SVP64PredInt(Enum):
     ALWAYS = 0
@@ -179,6 +186,13 @@ class SVP64subvl(Enum):
     VEC3 = 2
     VEC4 = 3
 
+@unique
+class SVP64sat(Enum):
+    NONE = 0
+    SIGNED = 1
+    UNSIGNED = 2
+
+
 # supported instructions: make sure to keep up-to-date with CSV files
 # just like everything else
 _insns = [
index da9d76273d90c43de3809d2d0d42f284a23be87c..f966533199a15bc511694d421f1b61bc756e3ccf 100644 (file)
@@ -17,7 +17,9 @@ https://libre-soc.org/openpower/sv/svp64/
 """
 
 from nmigen import Record, Elaboratable, Module, Signal
-from soc.decoder.power_enums import SVP64RMMode
+from soc.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
+                                    SVP64PredMode, SVP64sat)
+from soc.consts import EXTRA3
 
 # in nMigen, Record begins at the LSB and fills upwards
 class SVP64Rec(Record):
@@ -56,4 +58,57 @@ Arithmetic:
 """
 
 class SVP64RMMode(Elaboratable):
-    pass
+    def __init__(self, name=None):
+        self.rm_in = SVP64Rec(name=name)
+        self.fn_in = Signal(Function) # LD/ST is different
+        self.ptype_in = Signal(SVPtype)
+        self.mode = Signal(SVP64RMMode)
+        self.predmode = Signal(SVP64PredMode)
+        self.srcpred = Signal(3)
+        self.dstpred = Signal(3)
+        self.saturate = Signal(SVP64sat)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        # decode pieces of mode
+        is_ldst = Signal()
+        mode2 = Signal(2)
+        comb += is_ldst.eq(self.fn_in == Function.LDST)
+        comb += mode2.eq(mode[0:2])
+        with m.Switch(mode2):
+            with m.Case(0): # needs further decoding (LDST no mapreduce)
+                with m.If(is_ldst):
+                    comb += self.mode.eq(SVP64RMMode.NORMAL)
+                with m.Elif(mode[3] == 1):
+                    comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
+                with m.Else():
+                    comb += self.mode.eq(SVP64RMMode.NORMAL)
+            with m.Case(1):
+                comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first
+            with m.Case(2):
+                comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate
+            with m.Case(3):
+                comb += self.mode.eq(SVP64RMMode.PREDRES) # predicate result
+
+        # identify predicate mode
+        with m.If(self.rm_in.mmode == 1):
+            comb += self.predmode.eq(SVP64PredMode.CR) # CR Predicate
+        with m.Elif(self.srcpred == 0):
+            comb += self.predmode.eq(SVP64PredMode.ALWAYS) # No predicate
+        with m.Else():
+            comb += self.predmode.eq(SVP64PredMode.INT) # non-zero src: INT
+
+        # extract src/dest predicate.  use EXTRA3.MASK because EXTRA2.MASK
+        # is in exactly the same bits
+        srcmask = sel(m, self.rm_in.extra, EXTRA3.MASK)
+        dstmask = self.rm_in.mask
+        with m.If(self.ptype_in == SVPtype.P2):
+            comb += self.srcpred.eq(srcmask)
+        comb += self.dstpred.eq(dstmask)
+
+        # TODO: detect zeroing mode, a few more.
+
+        return m
+