Fix MSB0 issues for SVP64
authorCesar Strauss <cestrauss@gmail.com>
Tue, 16 Feb 2021 17:48:33 +0000 (14:48 -0300)
committerCesar Strauss <cestrauss@gmail.com>
Tue, 16 Feb 2021 21:45:46 +0000 (18:45 -0300)
Main changes are:
1) Convert indices from MSB0 to LSB0 when extracting fields
2) Convert indices from LSB0 to MSB0 when inserting fields
3) Reorder nMigen Records to start from the LSB

This was verified by inspecting the GTKWave output for
test_issuer_svp64.py, checking the instruction memory against a manually
assembled instruction, and checking that the decoded fields correspond to
the original instruction.

src/soc/decoder/isa/caller.py
src/soc/decoder/power_decoder2.py
src/soc/sv/svp64.py
src/soc/sv/svstate.py
src/soc/sv/trans/svp64.py

index 59b665e23d6e6c519bc0ee95415427860a5cb7d7..b87ddc0e9be250c4d74dbbae1081178b71566429 100644 (file)
@@ -708,7 +708,7 @@ class ISACaller:
         print ("svp64.rm", bin(pfx.rm.asint(msb0=True)))
         print ("    svstate.vl", self.svstate.vl.asint(msb0=True))
         print ("    svstate.mvl", self.svstate.maxvl.asint(msb0=True))
-        sv_rm = pfx.rm.asint()
+        sv_rm = pfx.rm.asint(msb0=True)
         ins = self.imem.ld(pc+4, 4, False, True)
         print("     svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
         yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
index e2e4e8af36120b74f8f7b60fd8a5abb31e1558e6..fbfd364043428f95df6a5c20ccd90fc9fa0441d8 100644 (file)
@@ -104,23 +104,23 @@ class SVP64ExtraSpec(Elaboratable):
             # 2-bit index selection mode
             with m.Case(SVEtype.EXTRA2):
                 with m.Switch(self.idx):
-                    with m.Case(SVEXTRA.Idx0): # 1st 2 bits
-                        comb += spec[1:3].eq(self.extra[0:2])
-                    with m.Case(SVEXTRA.Idx1): # 2nd 2 bits
-                        comb += spec[1:3].eq(self.extra[2:4])
-                    with m.Case(SVEXTRA.Idx2): # 3rd 2 bits
-                        comb += spec[1:3].eq(self.extra[4:6])
-                    with m.Case(SVEXTRA.Idx3): # 4th 2 bits
-                        comb += spec[1:3].eq(self.extra[6:8])
+                    with m.Case(SVEXTRA.Idx0):  # 1st 2 bits [0:1]
+                        comb += spec[1:3].eq(self.extra[8-1:9])
+                    with m.Case(SVEXTRA.Idx1):  # 2nd 2 bits [2:3]
+                        comb += spec[1:3].eq(self.extra[8-3:8-1])
+                    with m.Case(SVEXTRA.Idx2):  # 3rd 2 bits [4:5]
+                        comb += spec[1:3].eq(self.extra[8-5:8-3])
+                    with m.Case(SVEXTRA.Idx3):  # 4th 2 bits [6:7]
+                        comb += spec[1:3].eq(self.extra[8-7:8-5])
             # 3-bit index selection mode
             with m.Case(SVEtype.EXTRA3):
                 with m.Switch(self.idx):
-                    with m.Case(SVEXTRA.Idx0): # 1st 3 bits
-                        comb += spec.eq(self.extra[0:3])
-                    with m.Case(SVEXTRA.Idx1): # 2nd 3 bits
-                        comb += spec.eq(self.extra[3:6])
-                    with m.Case(SVEXTRA.Idx2): # 3rd 3 bits
-                        comb += spec.eq(self.extra[6:9])
+                    with m.Case(SVEXTRA.Idx0):  # 1st 3 bits [0:2]
+                        comb += spec.eq(self.extra[8-2:9])
+                    with m.Case(SVEXTRA.Idx1):  # 2nd 3 bits [3:5]
+                        comb += spec.eq(self.extra[8-5:8-2])
+                    with m.Case(SVEXTRA.Idx2):  # 3rd 3 bits [6:8]
+                        comb += spec.eq(self.extra[8-8:8-5])
                     # cannot fit more than 9 bits so there is no 4th thing
 
         return m
@@ -1331,6 +1331,8 @@ class SVP64PrefixDecoder(Elaboratable):
         l = []
         for idx in rmfields:
             l.append(self.opcode_in[31-idx])
+        # in nMigen, Cat begins at the LSB and proceeds upwards
+        l.reverse()  # put the LSB at the start of the list
         with m.If(self.is_svp64_mode):
             comb += self.svp64_rm.eq(Cat(*l))
 
index 5a8be91f072c4191a5b1b10f488548f67eee0c51..3911fb4c0f4ce3d89200ad894573ad49a4cebcae 100644 (file)
@@ -18,15 +18,17 @@ https://libre-soc.org/openpower/sv/svp64/
 
 from nmigen import Record
 
+
+# in nMigen, Record begins at the LSB and fills upwards
 class SVP64Rec(Record):
     def __init__(self, name=None):
-        Record.__init__(self, layout=[("mmode"   , 1),
-                                      ("mask"    , 3),
-                                      ("elwidth" , 2),
-                                      ("ewsrc"   , 2),
-                                      ("subvl"   , 2),
+        Record.__init__(self, layout=[("mode"    , 5),
                                       ("extra"   , 9),
-                                      ("mode"    , 5)], name=name)
+                                      ("subvl"   , 2),
+                                      ("ewsrc"   , 2),
+                                      ("elwidth" , 2),
+                                      ("mask"    , 3),
+                                      ("mmode"   , 1)], name=name)
 
     def ports(self):
         return [self.mmode, self.mask, self.elwidth, self.ewsrc,
index c97efa4833da1b856a0b33b0c4c7beed41210b99..6052a8f17f7ece3e5ce05ccafdee526ae069d450 100644 (file)
@@ -19,13 +19,13 @@ from nmutil.iocontrol import RecordObject
 from nmigen import Signal
 
 
+# In nMigen, Record order is from LSB to MSB
 class SVSTATERec(RecordObject):
     def __init__(self, name=None):
         super().__init__(name=name)
-        self.maxvl = Signal(7)
-        self.vl = Signal(7)
-        self.srcstep = Signal(7)
-        self.dststep = Signal(7)
-        self.subvl = Signal(2)
         self.svstep = Signal(2)
-
+        self.subvl = Signal(2)
+        self.dststep = Signal(7)
+        self.srcstep = Signal(7)
+        self.vl = Signal(7)
+        self.maxvl = Signal(7)
index a2427fd686004a926789ddf285496700c887fe6c..5702deb84fb5e6fcfdbd9106ebf426b6c893d6a1 100644 (file)
@@ -336,7 +336,7 @@ class SVP64Asm:
                 if idx is None: continue
                 # start at bit 10, work up 2/3 times EXTRA idx
                 offs = 2 if etype == 'EXTRA2' else 3 # 2 or 3 bits
-                svp64_rm |= sv_extra << (10+idx*offs)
+                svp64_rm |= sv_extra << (24-offs-(10+idx*offs))
 
             # parts of svp64_rm
             mmode = 0  # bit 0
@@ -503,20 +503,20 @@ class SVP64Asm:
             # whewww.... modes all done :)
             # now put into svp64_rm
             mode |= sv_mode
-            svp64_rm |= (mode << 19) # mode: bits 19-23
+            svp64_rm |= (mode << 23-23)       # mode: bits 19-23
 
             # put in predicate masks into svp64_rm
             if ptype == '2P':
-                svp64_rm |= (smask << 16) # source pred: bits 16-18
-            svp64_rm |= (mmode)           # mask mode: bit 0
-            svp64_rm |= (pmask << 1)      # 1-pred: bits 1-3
+                svp64_rm |= (smask << 23-18)  # source pred: bits 16-18
+            svp64_rm |= (mmode << 23-0)       # mask mode: bit 0
+            svp64_rm |= (pmask << 23-3)       # 1-pred: bits 1-3
 
             # and subvl
-            svp64_rm += (subvl << 8)      # subvl: bits 8-9
+            svp64_rm += (subvl << 23-9)       # subvl: bits 8-9
 
             # put in elwidths
-            svp64_rm += (srcwid << 6)      # srcwid: bits 6-7
-            svp64_rm += (destwid << 4)     # destwid: bits 4-5
+            svp64_rm += (srcwid << 23-7)      # srcwid: bits 6-7
+            svp64_rm += (destwid << 23-5)     # destwid: bits 4-5
 
             # nice debug printout. (and now for something completely different)
             # https://youtu.be/u0WOIwlXE9g?t=146
@@ -544,7 +544,7 @@ class SVP64Asm:
             svp64_prefix |= 0x1 << (31-9) # SVP64 marker 2
             rmfields = [6, 8] + list(range(10,32)) # SVP64 24-bit RM
             for i, x in enumerate(rmfields):
-                svp64_prefix |= ((svp64_rm>>i)&0b1) << (31-x)
+                svp64_prefix |= ((svp64_rm>>(23-i))&0b1) << (31-x)
 
             # fiinally yield the svp64 prefix and the thingy.  v3.0b opcode
             yield ".long 0x%x" % svp64_prefix