blob: 84e966a4353c681916330dd579a34a5361999eb5 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""Stopgap script to generate some cores for the englishbreakfast toplevel.
All output files are written to $REPO_TOP/build/$TOPNAME-autogen/.
"""
import argparse
import sys
import yaml
import shutil
import subprocess
import os
try:
from yaml import CSafeDumper as YamlDumper
except ImportError:
from yaml import SafeDumper as YamlDumper
def write_core(core_filepath, generated_core):
with open(core_filepath, 'w') as f:
# FuseSoC requires this line to appear first in the YAML file.
# Inserting this line through the YAML serializer requires ordered dicts
# to be used everywhere, which is annoying syntax-wise on Python <3.7,
# where native dicts are not sorted.
f.write('CAPI=2:\n')
yaml.dump(generated_core,
f,
encoding="utf-8",
Dumper=YamlDumper)
print("Core file written to %s" % (core_filepath, ))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--files-root', required=True)
parser.add_argument('--topname', required=True)
args = parser.parse_args()
topname = args.topname
files_root = args.files_root
# Call topgen.
files_data = files_root + "/hw/" + topname + "/data/"
files_out = os.path.abspath(files_root + "/build/" + topname + "-autogen/")
shutil.rmtree(files_out, ignore_errors=True)
os.makedirs(files_out, exist_ok=False)
cmd = [files_root + "/util/topgen.py", # "--verbose",
"-t", files_data + topname + ".hjson",
"-o", files_out]
try:
print("Running topgen.")
subprocess.run(cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
except subprocess.CalledProcessError as e:
print("topgen failed: " + str(e))
print(e.stdout)
sys.exit(1)
# Create core files.
print("Creating core files.")
# For some cores such IP package files, we need a separate dependency for the register file.
# Combining this with the generated topgen core file below leads to cyclic dependencies. For
# example, flash_ctrl depends on topgen but also on pwrmgr_pkg which depends on
# pwrmgr_reg_pkg generated by topgen.
reg_top_suffix = {
'clkmgr': '',
'flash_ctrl': '_core',
'pinmux': '',
'pwrmgr': '',
'rstmgr': '',
}
# reg-only
for ip in ['clkmgr', 'flash_ctrl', 'pinmux', 'pwrmgr', 'rstmgr']:
core_filepath = os.path.abspath(os.path.join(files_out, 'generated-%s.core' % ip))
name = 'lowrisc:ip:%s_reggen' % ip,
files = ['ip/%s/rtl/autogen/%s_reg_pkg.sv' % (ip, ip),
'ip/%s/rtl/autogen/%s_reg_top.sv' % (ip, ip + reg_top_suffix[ip])]
generated_core = {
'name': '%s' % name,
'filesets': {
'files_rtl': {
'depend': [
'lowrisc:ip:tlul',
],
'files': files,
'file_type': 'systemVerilogSource'
},
},
'targets': {
'default': {
'filesets': [
'files_rtl',
],
},
},
}
write_core(core_filepath, generated_core)
# topgen
nameparts = topname.split('_')
if nameparts[0] == 'top' and len(nameparts) > 1:
chipname = 'chip_' + '_'.join(nameparts[1:])
else:
chipname = topname
core_filepath = os.path.abspath(os.path.join(files_out, 'generated-topgen.core'))
generated_core = {
'name': "lowrisc:systems:generated-topgen",
'filesets': {
'files_rtl': {
'depend': [
# Ibex and OTBN constants
'lowrisc:ibex:ibex_pkg',
'lowrisc:ip:otbn_pkg',
# flash_ctrl
'lowrisc:constants:top_pkg',
'lowrisc:prim:util',
'lowrisc:ip:lc_ctrl_pkg',
'lowrisc:ip:pwrmgr_pkg',
# rstmgr
'lowrisc:prim:clock_mux2',
# clkmgr
'lowrisc:prim:all',
'lowrisc:prim:clock_gating',
'lowrisc:prim:clock_buf',
'lowrisc:prim:clock_div',
'lowrisc:ip:clkmgr_components',
# Top
# ast and sensor_ctrl not auto-generated, re-used from top_earlgrey
'lowrisc:systems:sensor_ctrl',
'lowrisc:systems:ast_pkg',
# TODO: absorb this into AST longerm
'lowrisc:systems:clkgen_xil7series',
],
'files': [
# IPs
'ip/clkmgr/rtl/autogen/clkmgr.sv',
'ip/flash_ctrl/rtl/autogen/flash_ctrl_pkg.sv',
'ip/flash_ctrl/rtl/autogen/flash_ctrl.sv',
'ip/flash_ctrl/rtl/autogen/flash_ctrl_region_cfg.sv',
'ip/rstmgr/rtl/autogen/rstmgr_pkg.sv',
'ip/rstmgr/rtl/autogen/rstmgr.sv',
# Top
'rtl/autogen/%s_rnd_cnst_pkg.sv' % topname,
'rtl/autogen/%s_pkg.sv' % topname,
'rtl/autogen/%s.sv' % topname,
# TODO: this is not ideal. we should extract
# this info from the target configuration and
# possibly generate separate core files for this.
'rtl/autogen/%s_cw305.sv' % chipname,
],
'file_type': 'systemVerilogSource'
},
},
'targets': {
'default': {
'filesets': [
'files_rtl',
],
},
},
}
write_core(core_filepath, generated_core)
return 0
if __name__ == "__main__":
main()