add INT, SPR and CR regfiles
[soc.git] / src / soc / decoder / power_enums.py
index e123a8be22bb81758445675725b7935e89d1b519..05e23f8e8ee1f0bddc412c48f1cc08bf6fe6b6de 100644 (file)
@@ -1,49 +1,60 @@
 from enum import Enum, unique
 import csv
 import os
-import requests
+from os.path import dirname, join
+from collections import namedtuple
 
+def find_wiki_file(name):
+    filedir = os.path.dirname(os.path.abspath(__file__))
+    basedir = dirname(dirname(dirname(filedir)))
+    tabledir = join(basedir, 'libreriscv')
+    tabledir = join(tabledir, 'openpower')
+    tabledir = join(tabledir, 'isatables')
 
-def download_wiki_file(name):
-    file_dir = os.path.dirname(os.path.realpath(__file__))
-    file_path = os.path.join(file_dir, name)
-    if not os.path.isfile(file_path):
-        url = 'https://libre-riscv.org/openpower/isatables/' + name
-        r = requests.get(url, allow_redirects=True)
-        with open(file_path, 'w') as outfile:
-            outfile.write(r.content.decode("utf-8"))
+    file_path = join(tabledir, name)
     return file_path
 
 
 def get_csv(name):
-    file_path = download_wiki_file(name)
+    file_path = find_wiki_file(name)
     with open(file_path, 'r') as csvfile:
         reader = csv.DictReader(csvfile)
         return list(reader)
 
 
 # names of the fields in the tables that don't correspond to an enum
-single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out',
+single_bit_flags = ['inv A', 'inv out',
                     'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b',
                     'sgn', 'lk', 'sgl pipe']
 
 # default values for fields in the table
 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
-                   'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
-                   'ldst len': 'NONE',
-                   'rc' : 'NONE', 'cry in' : 'ZERO', 'form': 'NONE'}
+                  'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
+                  'CR in': 'NONE',
+                  'ldst len': 'NONE',
+                  'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
+
 
 def get_signal_name(name):
     if name[0].isdigit():
         name = "is_" + name
     return name.lower().replace(' ', '_')
 
-
+# this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
+# is to process and guard the operation.  they are roughly divided by having
+# the same register input/output signature (X-Form, etc.)
 @unique
 class Function(Enum):
     NONE = 0
     ALU = 1
     LDST = 2
+    SHIFT_ROT = 3
+    LOGICAL = 4
+    BRANCH = 5
+    CR = 6
+    TRAP = 7
+    MUL = 8
+    DIV = 9
 
 
 @unique
@@ -145,19 +156,20 @@ class InternalOp(Enum):
     OP_SHL = 60
     OP_SHR = 61
     OP_SYNC = 62
-    OP_TD = 63
-    OP_TDI = 64
-    OP_TW = 65
-    OP_TWI = 66
+    OP_TRAP = 63
     OP_XOR = 67
     OP_SIM_CONFIG = 68
+    OP_CROP = 69
+    OP_RFID = 70
+    OP_MFMSR = 71
+    OP_MTMSRD = 72
 
 
 @unique
 class In1Sel(Enum):
-    RA = 0
-    RA_OR_ZERO = 1
-    NONE = 2
+    NONE = 0
+    RA = 1
+    RA_OR_ZERO = 2
     SPR = 3
 
 
@@ -214,24 +226,52 @@ class CryIn(Enum):
     ONE = 1
     CA = 2
 
-
-# SPRs - Special-Purpose Registers.  See V3.0B Figure 18 p971
-
 @unique
-class SPR(Enum):
-    XER    = 1
-    LR     = 8
-    CTR    = 9
-    TB     = 268
-    SRR0   = 26
-    SRR1   = 27
-    HSRR0  = 314
-    HSRR1  = 315
-    SPRG0  = 272
-    SPRG1  = 273
-    SPRG2  = 274
-    SPRG3  = 275
-    SPRG3U = 259
-    HSPRG0 = 304
-    HSPRG1 = 305
+class CRInSel(Enum):
+    NONE = 0
+    CR0 = 1
+    BI = 2
+    BFA = 3
+    BA_BB = 4
+    BC = 5
+    WHOLE_REG = 6
 
+@unique
+class CROutSel(Enum):
+    NONE = 0
+    CR0 = 1
+    BF = 2
+    BT = 3
+    WHOLE_REG = 4
+
+
+# SPRs - Special-Purpose Registers.  See V3.0B Figure 18 p971 and
+# http://libre-riscv.org/openpower/isatables/sprs.csv
+# http://bugs.libre-riscv.org/show_bug.cgi?id=261
+
+spr_csv = get_csv("sprs.csv")
+spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length')
+spr_dict = {}
+for row in spr_csv:
+    info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
+                    priv_mfspr=row['priv_mfspr'], length=int(row['len']))
+    spr_dict[int(row['Idx'])] = info
+fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
+SPR = Enum('SPR', fields)
+
+
+XER_bits = {
+    'SO': 32,
+    'OV': 33,
+    'CA': 34,
+    'OV32': 44,
+    'CA32': 45
+    }
+
+if __name__ == '__main__':
+    # find out what the heck is in SPR enum :)
+    print ("sprs", len(SPR))
+    print (dir(SPR))
+    print (dir(Enum))
+    for x in SPR:
+        print (x, x.value)