hqjenny-centrifuge/deploy/pkg/util/accelconfig.py

211 lines
8.4 KiB
Python

from __future__ import print_function
import re
import random
import logging
import json
import pathlib
rootLogger = logging.getLogger()
class Accel(object):
"""Base Definition of Accelerator"""
def __init__(self, prefix_id, pgm, func, srcs, hw_accel_dir):
self.prefix_id = prefix_id
self.pgm = pgm
self.func = func
self.srcs = srcs
self.name = """{}_{}_{}""".format(self.prefix_id, self.pgm, self.func)
self.dir = hw_accel_dir / self.name
src_main_path = self.dir / 'src' / 'main'
self.c_dir = src_main_path / 'c'
#self.verilog_dir = src_main_path / 'resources' / 'vsrc'
self.verilog_dir = src_main_path / 'verilog'
self.scala_dir = src_main_path / 'scala'
def info(self):
rootLogger.info(str(self))
def __str__(self):
return """\t\taccel_name: {} srcs: {}""".format(self.name, self.srcs)
class RoCCAccel(Accel):
"""Definition of RoCC Accelerator"""
def __init__(self, prefix_id, pgm, func, rocc_insn_id, src_dir, hw_accel_dir):
super(RoCCAccel, self).__init__(prefix_id, pgm, func, src_dir, hw_accel_dir)
self.rocc_insn_id = rocc_insn_id
def info(self):
rootLogger.info("""\tRoCC Accelerator {}""".format(self.prefix_id))
super(RoCCAccel, self).info()
class TLAccel(Accel):
"""Definition of TL Accelerator"""
def __init__(self, prefix_id, pgm, func, base_addr, src_dir, hw_accel_dir):
super(TLAccel, self).__init__(prefix_id, pgm, func, src_dir, hw_accel_dir)
self.base_addr = base_addr
def info(self):
rootLogger.info("""\tTL Accelerator {} @ {}""".format(self.prefix_id, self.base_addr))
super(TLAccel, self).info()
class AccelConfig:
"""Configuration for all accelerators to be included in the SoC"""
def __init__(self, accel_json_path, chipyard_dir, centrifuge_dir, genhw_dir):
self.accel_json_path = accel_json_path
self.chipyard_dir = chipyard_dir
self.centrifuge_dir = centrifuge_dir
self.sims_dir = self.chipyard_dir / 'sims'
self.chipyard_scala_dir = self.chipyard_dir / 'generators' / 'chipyard' / 'src' / 'main' / 'scala'
self.firechip_scala_dir = self.chipyard_dir / 'generators' / 'firechip' / 'src' / 'main' / 'scala'
self.accel_name = self.accel_json_path.stem
self.accel_json_dir = accel_json_path.parent
self.gensw_dir = self.accel_json_dir / 'centrifuge_wrappers'
self.hw_accel_dir = genhw_dir / self.accel_name
self.hw_accel_scala_dir = self.hw_accel_dir / 'src' / 'main' / 'scala'
self.accel_json = self.parse_json(self.accel_json_path)
self.rocc_accels = []
self.tl_accels = []
self.parse_json_config(self.accel_json)
# NIC
nonic = 'NoNIC'
# Default config string
self.DESIGN= self.accel_name + 'FireSimTopWithHLS' + nonic
self.TARGET_CONFIG = self.accel_name + 'HLSFireSimRocketChipConfig'
self.PLATFORM_CONFIG='BaseF1Config_F90MHz'
self.CONFIG = 'HLSRocketConfig'
self.TOP = 'DigitalTop'
def __str__(self):
s = """Accelerator SoC Definition: \n"""
s += "Generated SoC Directory: {}\n".format(self.hw_accel_dir)
for rocc_accel in self.rocc_accels:
s += str(rocc_accel) + "\n"
for tl_accel in self.tl_accels:
s += str(tl_accel) + "\n"
return s
def info(self):
rootLogger.info(str(self))
def parse_json(self, accel_json_path):
"""Parse the JSON input"""
rootLogger.info("Parsing input JSON file: {}".format(accel_json_path))
with open(accel_json_path, "r") as json_file:
return json.load(json_file)
def check_src_path(self, src_path):
if not (src_path.exists()):
raise Exception("{} does not exist in accel 'srcs' def".format(src_path))
def check_str(self, input_str):
"""Throw exception if str is not valid"""
if (input_str == '' or input_str.isspace() or
bool(re.match('^\s+$', input_str))):
raise Exception("Empty string is used in accelerator def: {}".format(input_str))
def check_addr_str(self, input_str):
"""Throw exception if str is not addr"""
try:
int(input_str)
except ValueError:
try:
int(input_str, 16)
except ValueError:
try:
int(input_str, 2)
except ValueError:
raise Exception("Invalid addr is used in accelerator def: {}".format(input_str))
def update_if_def(self, key, accel_json):
if key in list(accel_json.keys()):
setattr(self, key, accel_json[key])
def parse_json_config(self, accel_json):
"""Parse the JSON config to get accel definitions """
rootLogger.info("Parsing input JSON config")
# Parse Config Strings
self.update_if_def('DESIGN', accel_json);
self.update_if_def('TARGET_CONFIG', accel_json);
self.update_if_def('PLATFORM_CONFIG', accel_json);
self.update_if_def('CONFIG', accel_json);
self.update_if_def('TOP', accel_json);
# Parse RoCC Accelerators
if 'RoCC' in accel_json.keys():
rocc_accel_def = accel_json['RoCC']
idx = 0
for idx in range(3):
try:
if 'custom'+str(idx) in rocc_accel_def.keys():
rocc_accel_dict = rocc_accel_def['custom'+str(idx)]
prefix_id = 'rocc'+str(idx)
pgm = rocc_accel_dict['pgm']
func = rocc_accel_dict['func']
self.check_str(pgm)
self.check_str(func)
srcs = rocc_accel_dict.get('srcs')
if srcs is None:
raise Exception("Please specify the 'srcs' in your accelerator definition for {}!".format(prefix_id))
else:
for i, _ in enumerate(srcs):
srcs[i] = pathlib.Path(srcs[i])
if not srcs[i].is_absolute():
srcs[i] = (self.accel_json_dir / srcs[i]).resolve()
self.check_src_path(srcs[i])
rocc_accel = RoCCAccel(prefix_id, pgm, func, idx, srcs, self.hw_accel_dir)
self.rocc_accels.append(rocc_accel)
except Exception as err:
rootLogger.exception(err)
rootLogger.exception("""Fatal error. RoCC Accelerator definitions in {} is not valid """.format(self.accel_json_path))
assert(False)
if 'custom3' in rocc_accel_def.keys():
rootLogger.exception("""Fatal error. custom3 RoCC Accelerator is reserved for Virtual-to-Physical Address Translator""")
# Parse TL Accelerators
if 'TL' in accel_json.keys():
tl_accel_arr = accel_json['TL']
idx = 0
for tl_accel_dict in tl_accel_arr:
try:
prefix_id = 'tl'+str(idx)
pgm = tl_accel_dict['pgm']
func = tl_accel_dict['func']
base_addr = tl_accel_dict['addr']
self.check_str(pgm)
self.check_str(func)
self.check_addr_str(base_addr)
srcs = tl_accel_dict.get('srcs')
if srcs is None:
raise Exception("Please specify the 'srcs' in your accelerator definition for {}!".format(prefix_id))
else:
for i, _ in enumerate(srcs):
srcs[i] = pathlib.Path(srcs[i])
if not srcs[i].is_absolute():
srcs[i] = (self.accel_json_dir / srcs[i]).resolve()
self.check_src_path(srcs[i])
tl_accel = TLAccel(prefix_id, pgm, func, base_addr, srcs, self.hw_accel_dir)
self.tl_accels.append(tl_accel)
idx += 1
except Exception as err:
rootLogger.exception(err)
rootLogger.exception("""Fatal error. TL Accelerator definitions in {} is not valid """.format(self.accel_json_path))
assert(False)