add SVP64 dststep incrementing in PowerDecoder2, Testissuer and ISACaller
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 17 Mar 2021 21:29:49 +0000 (21:29 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 17 Mar 2021 21:29:49 +0000 (21:29 +0000)
src/soc/decoder/isa/caller.py
src/soc/decoder/power_decoder2.py
src/soc/simple/issuer.py

index dcdded95085052304675e41b520e6b8e7a9bd782..0371f6919f94c820e641d0b79e0baba136a770a1 100644 (file)
@@ -911,10 +911,11 @@ class ISACaller:
         if self.is_svp64_mode:
             vl = self.svstate.vl.asint(msb0=True)
             srcstep = self.svstate.srcstep.asint(msb0=True)
+            dststep = self.svstate.srcstep.asint(msb0=True)
             sv_a_nz = yield self.dec2.sv_a_nz
             in1 = yield self.dec2.e.read_reg1.data
-            print ("SVP64: VL, srcstep, sv_a_nz, in1",
-                    vl, srcstep, sv_a_nz, in1)
+            print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
+                    vl, srcstep, dststep, sv_a_nz, in1)
 
         # get predicate mask
         srcmask = dstmask = 0xffff_ffff_ffff_ffff
@@ -942,14 +943,18 @@ class ISACaller:
             while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
                 print ("      skip", bin(1<<srcstep))
                 srcstep += 1
+                dststep += 1
 
             # update SVSTATE with new srcstep
             self.svstate.srcstep[0:7] = srcstep
+            self.svstate.dststep[0:7] = dststep
             self.namespace['SVSTATE'] = self.svstate.spr
             yield self.dec2.state.svstate.eq(self.svstate.spr.value)
             yield Settle() # let decoder update
             srcstep = self.svstate.srcstep.asint(msb0=True)
+            dststep = self.svstate.dststep.asint(msb0=True)
             print ("    srcstep", srcstep)
+            print ("    dststep", dststep)
 
             # check if end reached (we let srcstep overrun, above)
             # nothing needs doing (TODO zeroing): just do next instruction
@@ -1088,12 +1093,14 @@ class ISACaller:
             vl = self.svstate.vl.asint(msb0=True)
             mvl = self.svstate.maxvl.asint(msb0=True)
             srcstep = self.svstate.srcstep.asint(msb0=True)
+            dststep = self.svstate.srcstep.asint(msb0=True)
             sv_ptype = yield self.dec2.dec.op.SV_Ptype
             no_out_vec = not (yield self.dec2.no_out_vec)
             no_in_vec = not (yield self.dec2.no_in_vec)
             print ("    svstate.vl", vl)
             print ("    svstate.mvl", mvl)
             print ("    svstate.srcstep", srcstep)
+            print ("    svstate.dststep", dststep)
             print ("    no_out_vec", no_out_vec)
             print ("    no_in_vec", no_in_vec)
             print ("    sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
@@ -1107,6 +1114,7 @@ class ISACaller:
                 svp64_is_vector = no_out_vec
             if svp64_is_vector and srcstep != vl-1:
                 self.svstate.srcstep += SelectableInt(1, 7)
+                self.svstate.dststep += SelectableInt(1, 7)
                 self.pc.NIA.value = self.pc.CIA.value
                 self.namespace['NIA'] = self.pc.NIA
                 self.namespace['SVSTATE'] = self.svstate.spr
@@ -1128,6 +1136,7 @@ class ISACaller:
 
     def svp64_reset_loop(self):
         self.svstate.srcstep[0:7] = 0
+        self.svstate.dststep[0:7] = 0
         print ("    svstate.srcstep loop end (PC to update)")
         self.pc.update_nia(self.is_svp64_mode)
         self.namespace['NIA'] = self.pc.NIA
index ffb677c13ca78dedd82b8b59fc6c49ef37a703bf..3813295c5142786202bca8c2f220ecd0d246a179 100644 (file)
@@ -1054,27 +1054,30 @@ class PowerDecode2(PowerDecodeSubset):
             comb += crin_svdec_b.idx.eq(cr_b_idx)     # SVP64 CR in B
             comb += crin_svdec_o.idx.eq(op.sv_cr_out) # SVP64 CR out
 
-            # get SVSTATE srcstep (TODO: elwidth, dststep etc.) needed below
+            # get SVSTATE srcstep (TODO: elwidth etc.) needed below
             srcstep = Signal.like(self.state.svstate.srcstep)
+            dststep = Signal.like(self.state.svstate.dststep)
             comb += srcstep.eq(self.state.svstate.srcstep)
+            comb += dststep.eq(self.state.svstate.dststep)
 
             # registers a, b, c and out and out2 (LD/ST EA)
-            for to_reg, fromreg, svdec in (
-                (e.read_reg1, dec_a.reg_out, in1_svdec),
-                (e.read_reg2, dec_b.reg_out, in2_svdec),
-                (e.read_reg3, dec_c.reg_out, in3_svdec),
-                (e.write_reg, dec_o.reg_out, o_svdec),
-                (e.write_ea, dec_o2.reg_out, o2_svdec)):
+            for to_reg, fromreg, svdec, out in (
+                (e.read_reg1, dec_a.reg_out, in1_svdec, False),
+                (e.read_reg2, dec_b.reg_out, in2_svdec, False),
+                (e.read_reg3, dec_c.reg_out, in3_svdec, False),
+                (e.write_reg, dec_o.reg_out, o_svdec, True),
+                (e.write_ea, dec_o2.reg_out, o2_svdec, True)):
                 comb += svdec.extra.eq(extra)        # EXTRA field of SVP64 RM
                 comb += svdec.etype.eq(op.SV_Etype)  # EXTRA2/3 for this insn
                 comb += svdec.reg_in.eq(fromreg.data) # 3-bit (CR0/BC/BFA)
                 comb += to_reg.ok.eq(fromreg.ok)
-                # detect if Vectorised: add srcstep if yes.  TODO: a LOT.
-                # this trick only holds when elwidth=default and in single-pred
+                # detect if Vectorised: add srcstep/dststep if yes.
+                # to_reg is 7-bits, outs get dststep added, ins get srcstep
                 with m.If(svdec.isvec):
-                    comb += to_reg.data.eq(srcstep+svdec.reg_out) # 7-bit output
+                    step = dststep if out else srcstep
+                    comb += to_reg.data.eq(step+svdec.reg_out)
                 with m.Else():
-                    comb += to_reg.data.eq(svdec.reg_out) # 7-bit output
+                    comb += to_reg.data.eq(svdec.reg_out)
 
             comb += in1_svdec.idx.eq(op.sv_in1)  # SVP64 reg #1 (in1_sel)
             comb += in2_svdec.idx.eq(op.sv_in2)  # SVP64 reg #2 (in2_sel)
@@ -1113,11 +1116,11 @@ class PowerDecode2(PowerDecodeSubset):
                     comb += loop.eq(0)
 
             # condition registers (CR)
-            for to_reg, cr, name, svdec in (
-                (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec),
-                (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b),
-                (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o),
-                (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec)):
+            for to_reg, cr, name, svdec, out in (
+                (e.read_cr1, self.dec_cr_in, "cr_bitfield", crin_svdec, 0),
+                (e.read_cr2, self.dec_cr_in, "cr_bitfield_b", crin_svdec_b, 0),
+                (e.read_cr3, self.dec_cr_in, "cr_bitfield_o", crin_svdec_o, 0),
+                (e.write_cr, self.dec_cr_out, "cr_bitfield", crout_svdec, 1)):
                 fromreg = getattr(cr, name)
                 comb += svdec.extra.eq(extra)        # EXTRA field of SVP64 RM
                 comb += svdec.etype.eq(op.SV_Etype)  # EXTRA2/3 for this insn
@@ -1126,14 +1129,15 @@ class PowerDecode2(PowerDecodeSubset):
                     # check if this is CR0 or CR1: treated differently
                     # (does not "listen" to EXTRA2/3 spec for a start)
                     # also: the CRs start from completely different locations
+                    step = dststep if out else srcstep
                     with m.If(cr.sv_override == 1): # CR0
                         offs = SVP64CROffs.CR0
-                        comb += to_reg.data.eq(srcstep+offs)
+                        comb += to_reg.data.eq(step+offs)
                     with m.Elif(cr.sv_override == 2): # CR1
                         offs = SVP64CROffs.CR1
-                        comb += to_reg.data.eq(srcstep+1)
+                        comb += to_reg.data.eq(step+1)
                     with m.Else():
-                        comb += to_reg.data.eq(srcstep+svdec.cr_out) # 7-bit out
+                        comb += to_reg.data.eq(step+svdec.cr_out) # 7-bit out
                 with m.Else():
                     comb += to_reg.data.eq(svdec.cr_out) # 7-bit output
                 comb += to_reg.ok.eq(fromreg.ok)
index a373a8656034906fb5f9aceb1462167118ad727b..73076cb590dea5ff0a3cdbeafbdf4349fa8184f7 100644 (file)
@@ -348,7 +348,9 @@ class TestIssuerInternal(Elaboratable):
                     with m.If(exec_pc_valid_o):
                         # precalculate srcstep+1
                         next_srcstep = Signal.like(cur_state.svstate.srcstep)
+                        next_dststep = Signal.like(cur_state.svstate.dststep)
                         comb += next_srcstep.eq(cur_state.svstate.srcstep+1)
+                        comb += next_dststep.eq(cur_state.svstate.dststep+1)
                         # was this the last loop iteration?
                         is_last = Signal()
                         cur_vl = cur_state.svstate.vl
@@ -374,12 +376,14 @@ class TestIssuerInternal(Elaboratable):
                             # reset SRCSTEP before returning to Fetch
                             with m.If(pdecode2.loop_continue):
                                 comb += new_svstate.srcstep.eq(0)
+                                comb += new_svstate.dststep.eq(0)
                                 comb += update_svstate.eq(1)
                             m.next = "INSN_FETCH"
 
                         # returning to Execute? then, first update SRCSTEP
                         with m.Else():
                             comb += new_svstate.srcstep.eq(next_srcstep)
+                            comb += new_svstate.dststep.eq(next_dststep)
                             comb += update_svstate.eq(1)
                             m.next = "DECODE_SV"