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
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
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)