[top_englishbreakfast] Clean up the tree-bodging script
Signed-off-by: Miguel Young de la Sota <mcyoung@google.com>
diff --git a/hw/top_englishbreakfast/util/prepare_sw.py b/hw/top_englishbreakfast/util/prepare_sw.py
index c2891a0..67ad72d 100755
--- a/hw/top_englishbreakfast/util/prepare_sw.py
+++ b/hw/top_englishbreakfast/util/prepare_sw.py
@@ -2,74 +2,99 @@
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-r"""Script to prepare SW for non-earlgrey tops
+
+"""
+Script to patch the OpenTitan tree for building english-breakfast-friendly
+software.
+
+This script and its associated mechanism will eventually be transitioned to
+a pure-Bazel solution.
"""
import argparse
-import sys
+import shutil
import subprocess
-import re
+
from pathlib import Path
+# This file is in /hw/top_.../util
+REPO_TOP = Path(__file__).resolve().parents[3]
+
+BINARIES = [
+ 'sw/device/lib/testing/test_rom/test_rom_export_fpga_nexysvideo',
+ 'sw/device/sca/aes_serial_export_fpga_nexysvideo',
+ 'sw/device/lib/testing/test_rom/test_rom_export_sim_verilator',
+ 'sw/device/tests/aes_smoketest_export_sim_verilator',
+ 'sw/device/examples/hello_world/hello_world_export_sim_verilator',
+]
+
+def find_dirs(root, names):
+ """
+ Finds all directories under `root` with the given name and
+ yields them.
+ """
+ for p in root.iterdir():
+ if not p.is_dir(): continue
+ if p.name in names:
+ yield p
+ else:
+ find_dirs(p, names)
+
+def delete_path(path):
+ """
+ Deletes a path; will delete directories recursively.
+ """
+ print(f'* Deleting: {path}')
+ if not path.exists():
+ return
+ if path.is_dir():
+ shutil.rmtree(str(path))
+ else:
+ path.unlink()
+
+def shell_out(cmd):
+ print(f"Running {cmd}")
+ # Let the resulting exception from `check` propagate out.
+ subprocess.run(cmd, check=True)
def main():
-
parser = argparse.ArgumentParser(
prog="prepare_sw",
description="Script to prepare SW sources for English Breakfast",
formatter_class=argparse.RawDescriptionHelpFormatter)
-
parser.add_argument(
'--build',
'-b',
default=False,
action='store_true',
help='Build ROM based on reduced design')
-
+ parser.add_argument(
+ '--top',
+ '-t',
+ default='englishbreakfast',
+ type=str,
+ help='The alternative top to use')
args = parser.parse_args()
-
- # Config
- name_old = 'earlgrey'
- name = 'englishbreakfast'
-
- topname = 'top_' + name
-
- path_root = str(Path(__file__).resolve().parents[3])
+ name = args.top
+ topname = f'top_{name}'
# We start by removing any previously generated auto-gen files for the
# selected non-earlgrey top. These might be stale and confuse topgen.
- cmd = [path_root + '/hw/' + topname + '/util/remove_autogen_files.sh']
+ print('Purging earlgrey autogen files')
+ for d in find_dirs(REPO_TOP / 'hw', ['autogen', 'ip_autogen']):
+ delete_path(d)
- try:
- print("Removing auto-generated files...")
- subprocess.run(cmd,
- check=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True)
+ delete_path(REPO_TOP / 'hw/ip/ast/rtl')
+ delete_path(REPO_TOP / 'hw/ip/sensor_ctrl/rtl')
+ delete_path(REPO_TOP / 'hw/ip/xbar_main/xbar_main.core')
+ delete_path(REPO_TOP / 'hw/ip/xbar_peri/xbar_peri.core')
- except subprocess.CalledProcessError as e:
- print("Removing auto-generated files failed: " + str(e))
- sys.exit(1)
-
- # Next, we need to run topgen in order to create all auto-generated files.
- path_in = path_root + '/hw/' + topname + '/data/'
- path_out = path_root + '/hw/' + topname
- cmd = [path_root + '/util/topgen.py', # "--verbose",
- "-t", path_in + topname + '.hjson',
- "-o", path_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))
- sys.exit(1)
+ # Next, we need to re-run topgen in order to create all auto-generated files.
+ shell_out([
+ REPO_TOP / 'util/topgen.py',
+ '-t', REPO_TOP / 'hw' / topname / 'data' / f"{topname}.hjson",
+ '-o', REPO_TOP / 'hw' / topname,
+ ])
# We need to patch some files:
# 1. meson.build needs to be pointed to the proper auto-gen files.
@@ -78,76 +103,31 @@
# 3. The build system still uses some sources from the original top level.
# We thus need to replace those with the new sources patched in 2.
- # 1.
- cmd = ['sed', '-i', "s/TOPNAME='top_{}'/TOPNAME='top_{}'/g".format(name_old, name),
- path_root + '/meson.build']
- try:
- print("Adjusting meson.build...")
- subprocess.run(cmd,
- check=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True)
+ print("Rewriting $REPO_TOP/meson.build's TOPNAME")
+ meson_build = (REPO_TOP / 'meson.build').read_text()
+ meson_build = meson_build.replace("TOPNAME='top_earlgrey'", f"TOPNAME='{topname}'")
+ (REPO_TOP / 'meson.build').write_text(meson_build)
- except subprocess.CalledProcessError as e:
- print("Adjustment of meson.build failed: " + str(e))
- sys.exit(1)
+ for suffix in ['.c', '.h', '_memory.h', '_memory.ld']:
+ old = REPO_TOP / 'hw' / topname / 'sw/autogen' / (topname + suffix)
+ new = REPO_TOP / 'hw/top_earlgrey/sw/autogen' / ('top_earlgrey' + suffix)
+ print(f"* {old} -> {new}")
- # 2. and 3.
- print("Adjusting SW files generated by topgen...")
- files = ['top_' + name + '.c',
- 'top_' + name + '.h',
- 'top_' + name + '_memory.h',
- 'top_' + name + '_memory.ld']
- path_in = path_root + '/hw/top_' + name + '/sw/autogen/'
- path_out = path_root + '/hw/top_' + name_old + '/sw/autogen/'
+ text = old.read_text()
+ text = text.replace(name, 'earlgrey')
+ text = text.replace(name.capitalize(), 'Earlgrey')
+ text = text.replace(name.upper(), 'EARLGREY')
- for file_name in files:
+ # The SW build expects to find this file both in the top_earlgrey dir AND
+ # in the top_englishbreakfast dir.
+ new.write_text(text)
+ (old.parent / new.name).write_text(text)
- # Read file produced by topgen.
- with open(path_in + file_name, "r") as file_in:
- text = file_in.read()
+ if not args.build:
+ return;
- text = re.sub(name, name_old, text)
- text = re.sub(name.capitalize(), name_old.capitalize(), text)
- text = re.sub(name.upper(), name_old.upper(), text)
-
- # Write file that SW build can deal with.
- file_name_new = re.sub(name, name_old, file_name)
- with open(path_in + file_name_new, "w") as file_out:
- file_out.write(text)
-
- # Overwrite the files in the tree of the original top level. They are still used by the
- # SW build.
- with open(path_out + file_name_new, "w") as file_out:
- file_out.write(text)
-
- if (args.build):
- # Build the software including test_rom to enable the FPGA build.
- binaries = [
- 'sw/device/lib/testing/test_rom/test_rom_export_fpga_nexysvideo',
- 'sw/device/sca/aes_serial_export_fpga_nexysvideo',
- 'sw/device/lib/testing/test_rom/test_rom_export_sim_verilator',
- 'sw/device/tests/aes_smoketest_export_sim_verilator',
- 'sw/device/examples/hello_world/hello_world_export_sim_verilator',
- ]
- for binary in binaries:
- print("Building " + binary + "...")
- cmd = ['ninja', '-C', path_root + '/build-out',
- binary]
- try:
- subprocess.run(cmd,
- check=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True)
-
- except subprocess.CalledProcessError as e:
- print("Failed to generate boot ROM: " + str(e))
- sys.exit(1)
-
- return 0
-
+ # Build the software including test_rom to enable the FPGA build.
+ shell_out(['ninja', '-C', REPO_TOP / 'build-out'] + BINARIES)
if __name__ == "__main__":
main()
diff --git a/hw/top_englishbreakfast/util/remove_autogen_files.sh b/hw/top_englishbreakfast/util/remove_autogen_files.sh
deleted file mode 100755
index 599a9ce..0000000
--- a/hw/top_englishbreakfast/util/remove_autogen_files.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-# Copyright lowRISC contributors.
-# Licensed under the Apache License, Version 2.0, see LICENSE for details.
-# SPDX-License-Identifier: Apache-2.0
-
-# The purpose of this simple script is to remove all auto-generated files for
-# the current top-level design. Except for top_earlgrey, we anyway don't check
-# these files into the repo. This is also useful for debugging topgen by
-# letting it run on a clean directory.
-
-# Get the path to the top-specific directory.
-top_path=$(dirname $(realpath $0))/../
-
-# Find and delete autogen directories.
-find ${top_path} -depth -type d -name "autogen" -exec rm -rf {} \;
-find ${top_path} -depth -type d -name "ip_autogen" -exec rm -rf {} \;
-
-# Some autogen files are not in autogen folders.
-rm -rf ${top_path}/ip/ast/rtl/*
-rm -rf ${top_path}/ip/sensor_ctrl/rtl/*
-rm -rf ${top_path}/ip/xbar_main/xbar_main.core
-rm -rf ${top_path}/ip/xbar_peri/xbar_peri.core
-
-# Remove topgen files for secondary top levels.
-rm -rf build/top_*-autogen/