make sure non-svp64-mode works
[soc.git] / src / soc / simple / issuer.py
index 67d06e6899e5965788209f0e47017acd79cbe180..482d364080f9514e6f86ad0ad6c524ed05abb773 100644 (file)
@@ -77,18 +77,23 @@ def get_predint(m, mask, name):
     this is identical to the equivalent function in ISACaller except that
     it doesn't read the INT directly, it just decodes "what needs to be done"
     i.e. which INT reg, whether it is shifted and whether it is bit-inverted.
+
+    * all1s is set to indicate that no mask is to be applied.
+    * regread indicates the GPR register number to be read
+    * invert is set to indicate that the register value is to be inverted
+    * unary indicates that the contents of the register is to be shifted 1<<r3
     """
     comb = m.d.comb
     regread = Signal(5, name=name+"regread")
     invert = Signal(name=name+"invert")
     unary = Signal(name=name+"unary")
+    all1s = Signal(name=name+"all1s")
     with m.Switch(mask):
         with m.Case(SVP64PredInt.ALWAYS.value):
-            comb += regread.eq(0)
-            comb += invert.eq(1)
+            comb += all1s.eq(1)      # use 0b1111 (all ones)
         with m.Case(SVP64PredInt.R3_UNARY.value):
             comb += regread.eq(3)
-            comb += unary.eq(1)
+            comb += unary.eq(1)        # 1<<r3 - shift r3 (single bit)
         with m.Case(SVP64PredInt.R3.value):
             comb += regread.eq(3)
         with m.Case(SVP64PredInt.R3_N.value):
@@ -104,7 +109,7 @@ def get_predint(m, mask, name):
         with m.Case(SVP64PredInt.R30_N.value):
             comb += regread.eq(30)
             comb += invert.eq(1)
-    return regread, invert, unary
+    return regread, invert, unary, all1s
 
 def get_predcr(m, mask, name):
     """decode SVP64 predicate CR to reg number field and invert status
@@ -348,7 +353,8 @@ class TestIssuerInternal(Elaboratable):
                     # here or maybe even in INSN_READ state, if svp64_mode
                     # detected, in order to trigger - and wait for - the
                     # predicate reading.
-                    pmode = pdecode2.rm_dec.predmode
+                    if self.svp64_en:
+                        pmode = pdecode2.rm_dec.predmode
                     """
                     if pmode != SVP64PredMode.ALWAYS.value:
                         fire predicate loading FSM and wait before
@@ -406,8 +412,8 @@ class TestIssuerInternal(Elaboratable):
         #               comd += self.srcmask[cr_idx].eq(inv ^ cr_bit)
 
         # decode predicates
-        sregread, sinvert, sunary = get_predint(m, srcpred, 's')
-        dregread, dinvert, dunary = get_predint(m, dstpred, 'd')
+        sregread, sinvert, sunary, sall1s = get_predint(m, srcpred, 's')
+        dregread, dinvert, dunary, dall1s = get_predint(m, dstpred, 'd')
         sidx, scrinvert = get_predcr(m, srcpred, 's')
         didx, dcrinvert = get_predcr(m, dstpred, 'd')
 
@@ -417,10 +423,20 @@ class TestIssuerInternal(Elaboratable):
                 comb += pred_insn_ready_o.eq(1)
                 with m.If(pred_insn_valid_i):
                     with m.If(predmode == SVP64PredMode.INT):
+                        # skip fetching destination mask register, when zero
+                        with m.If(dall1s):
+                            sync += self.dstmask.eq(-1)
+                            # directly go to fetch source mask register
+                            # guaranteed not to be zero (otherwise predmode
+                            # would be SVP64PredMode.ALWAYS, not INT)
+                            comb += int_pred.addr.eq(sregread)
+                            comb += int_pred.ren.eq(1)
+                            m.next = "INT_SRC_READ"
                         # fetch destination predicate register
-                        comb += int_pred.addr.eq(dregread)
-                        comb += int_pred.ren.eq(1)
-                        m.next = "INT_DST_READ"
+                        with m.Else():
+                            comb += int_pred.addr.eq(dregread)
+                            comb += int_pred.ren.eq(1)
+                            m.next = "INT_DST_READ"
                     with m.Else():
                         sync += self.srcmask.eq(-1)
                         sync += self.dstmask.eq(-1)
@@ -430,10 +446,15 @@ class TestIssuerInternal(Elaboratable):
                 # store destination mask
                 inv = Repl(dinvert, 64)
                 sync += self.dstmask.eq(self.int_pred.data_o ^ inv)
+                # skip fetching source mask register, when zero
+                with m.If(sall1s):
+                    sync += self.srcmask.eq(-1)
+                    m.next = "FETCH_PRED_DONE"
                 # fetch source predicate register
-                comb += int_pred.addr.eq(sregread)
-                comb += int_pred.ren.eq(1)
-                m.next = "INT_SRC_READ"
+                with m.Else():
+                    comb += int_pred.addr.eq(sregread)
+                    comb += int_pred.ren.eq(1)
+                    m.next = "INT_SRC_READ"
 
             with m.State("INT_SRC_READ"):
                 # store source mask
@@ -536,7 +557,10 @@ class TestIssuerInternal(Elaboratable):
                         comb += self.insn_done.eq(1)
                         m.next = "ISSUE_START"
                     with m.Else():
-                        m.next = "PRED_START"  # start fetching the predicate
+                        if self.svp64_en:
+                            m.next = "PRED_START"  # start fetching predicate
+                        else:
+                            m.next = "INSN_EXECUTE" # skip predication
 
             with m.State("PRED_START"):
                 comb += pred_insn_valid_i.eq(1)  # tell fetch_pred to start
@@ -561,8 +585,9 @@ class TestIssuerInternal(Elaboratable):
 
                 with m.If(is_svp64_mode):
 
-                    pred_src_zero = pdecode2.rm_dec.pred_sz
-                    pred_dst_zero = pdecode2.rm_dec.pred_dz
+                    if self.svp64_en:
+                        pred_src_zero = pdecode2.rm_dec.pred_sz
+                        pred_dst_zero = pdecode2.rm_dec.pred_dz
 
                     """
                     if not pred_src_zero:
@@ -880,9 +905,10 @@ class TestIssuerInternal(Elaboratable):
                        exec_insn_valid_i, exec_insn_ready_o,
                        exec_pc_valid_o, exec_pc_ready_i)
 
-        self.fetch_predicate_fsm(m,
-                                 pred_insn_valid_i, pred_insn_ready_o,
-                                 pred_mask_valid_o, pred_mask_ready_i)
+        if self.svp64_en:
+            self.fetch_predicate_fsm(m,
+                                     pred_insn_valid_i, pred_insn_ready_o,
+                                     pred_mask_valid_o, pred_mask_ready_i)
 
         self.execute_fsm(m, core, pc_changed, sv_changed,
                          exec_insn_valid_i, exec_insn_ready_o,