diff --git a/util/make_new_dif.py b/util/make_new_dif.py index 8c4c33e2b1702..8c85202f6f151 100755 --- a/util/make_new_dif.py +++ b/util/make_new_dif.py @@ -7,7 +7,7 @@ To instantiate the files for a new IP named ip_ctrl, run the command: -$ util/make_new_dif.py --ip-name-snake "ip_ctrl" --ip-name-long "IP Controller" +$ util/make_new_dif.py -i /path/to/ip.hjson --ip-name-snake "ip_ctrl" --ip-name-long "IP Controller" where "IP Controller" is a documentation-friendly name for the IP. For example, compare "pwrmgr" and "Power Manager". @@ -15,36 +15,24 @@ It will instantiate: - `util/make_new_dif/templates/dif_template.h.tpl` as the DIF Header boilerplate into `dif_.h`, which should be manually edited/enhanced. -- `util/make_new_dif/templates/dif_autogen.h.tpl` as the autogenerated DIF - Header into `dif__autogen.h`. -- `util/make_new_dif/templates/dif_autogen.c.tpl` as the autogenerated DIF - implementation into `dif__autogen.c`. -- `util/make_new_dif/templates/dif_autogen_unittest.cc.tpl` as the - autogenerated DIF unit tests into `dif__autogen_unittest.cc`. - `doc/project_governance/checklist/sw_checklist.md.tpl` as the DIF Checklist into dif_.md, which should be manually edited. Each one of these templates has comments with more specific information. -You can also use the `--only=header`, `--only=autogen`, `--only=checklist` to +You can also use the `--only=header`, `--only=checklist` to instantiate a subset of the templates. This can be passed multiple times, and including `--only=all` will instantiate every template. -Note: the non-autogenerated files will still need some cleaning up before they -can be used. +Note: the files will still need some cleaning up before they can be used. """ import argparse -import glob import logging import subprocess import sys from pathlib import Path -import hjson -import topgen.lib as lib -from autogen_banner import get_autogen_banner -from autogen_testutils.gen import gen_testutils from make_new_dif.ip import Ip from mako.template import Template @@ -52,7 +40,7 @@ # calls to get back to the top. REPO_TOP = Path(__file__).resolve().parent.parent -ALL_PARTS = ["header", "checklist", "autogen"] +ALL_PARTS = ["header", "checklist"] def main(): @@ -62,20 +50,19 @@ def main(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument( - "--mode", - "-m", - choices=["new", "regen"], - default="new", - required=True, - help="mode to generate DIF code. Use 'new' if no DIF code exists." - "Use 'regen' to regenerate all auto-generated DIFs for all IPs.") - parser.add_argument("--topcfg", "-t", help="path of the top hjson file.") - parser.add_argument("--ip-name-snake", + + parser.add_argument("--ipcfg", "-i", + type=Path, + required=True, + help="`.hjson` file.") + parser.add_argument("--ip-name-snake", + "-s", + required=True, help="the short name of the IP, in snake_case.") parser.add_argument("--ip-name-long", "-l", + required=True, help="the documentation-friendly name of the IP.") parser.add_argument("--only", choices=ALL_PARTS, @@ -84,51 +71,7 @@ def main(): help="only create some files; defaults to all.") args = parser.parse_args() - # Parse CMD line args. - ips = [] - - # Parse toplevel Hjson to get IPs that are generated with IPgen and those - # that are under /ip. - if args.topcfg: - topcfg_path = args.topcfg - else: - topcfg_path = REPO_TOP / "hw/top_earlgrey/data/top_earlgrey.hjson" - try: - with open(topcfg_path, 'r') as ftop: - topcfg = hjson.load(ftop, use_decimal=True) - except FileNotFoundError: - print(f"hjson {topcfg_path} could not be found") - sys.exit(1) - - all_modules = [m['type'] for m in topcfg['module']] - - # Check for regeneration mode (used in CI check: - # ci/scripts/check-generated.sh) - if args.mode == "regen": - if len(args.only) != 1 or args.only[0] != "autogen": - raise RuntimeError( - "can only regenerate DIF code that is auto-generated.") - # Create list of IPs to re-generate DIF code for. - for autogen_src_filename in glob.iglob( - str(REPO_TOP / "sw/device/lib/dif/autogen/*.c")): - # NOTE: the line below takes as input a file path - # (/path/to/dif_uart_autogen.c) and returns the IP name in lower - # case snake mode (i.e., uart). - ip_name_snake = Path(autogen_src_filename).stem[4:-8] - # Only considers IPs for that particular top. - if ip_name_snake not in all_modules: - continue - hjson_file = lib.get_ip_hjson_path(ip_name_snake, topcfg, REPO_TOP) - # NOTE: ip.name_long_* not needed for auto-generated files which - # are the only files (re-)generated in regen mode. - ips.append( - Ip(ip_name_snake, "AUTOGEN", hjson_file)) - else: - assert args.ip_name_snake and args.ip_name_long, \ - "ERROR: pass --ip-name-snake and --ip-name-long when --mode=new." - hjson_file = lib.get_ip_hjson_path(ip_name_snake, topcfg, REPO_TOP) - ips.append( - Ip(args.ip_name_snake, args.ip_name_long, hjson_file)) + ip = Ip(args.ip_name_snake, args.ip_name_long, args.ipcfg) # Default to generating all parts. if len(args.only) == 0: @@ -141,71 +84,40 @@ def main(): # Render DIF templates. template_path = REPO_TOP / "util/make_new_dif/templates" - for ip in ips: - if "header" in args.only: - header_template_file = template_path / "dif_template.h.tpl" - header_out_file = dif_dir / "dif_{}.h".format(ip.name_snake) - if header_out_file.is_file(): - raise FileExistsError( - "DIF header already exists for the IP. To overwrite, " - "delete existing header and try again.") - header_template = Template(header_template_file.read_text()) - header_out_file.write_text(header_template.render(ip=ip)) - print("DIF header successfully written to {}.".format( - str(header_out_file))) - - if "autogen" in args.only: - out_files = [] - # Render all templates - for filetype in [".h", ".c", "_unittest.cc"]: - # Build input/output file names. - template_file = template_path / f"dif_autogen{filetype}.tpl" - out_file = (autogen_dif_dir / - f"dif_{ip.name_snake}_autogen{filetype}") - - # Read in template. - template = Template(template_file.read_text(), - strict_undefined=True) - - # Generate output file. - out_file.write_text( - template.render( - ip=ip, - autogen_banner=get_autogen_banner( - "util/make_new_dif.py --mode=regen --only=autogen", - "//"))) - - # Assemble a list of files to format all at once - out_files += [out_file] + + if "header" in args.only: + header_template_file = template_path / "dif_template.h.tpl" + header_out_file = dif_dir / "dif_{}.h".format(ip.name_snake) + if header_out_file.is_file(): + raise FileExistsError( + "DIF header already exists for the IP. To overwrite, " + "delete existing header and try again.") + header_template = Template(header_template_file.read_text()) + header_out_file.write_text(header_template.render(ip=ip)) + logging.info("DIF header successfully written to {}.".format( + str(header_out_file))) # Format autogenerated file with clang-format. try: subprocess.check_call( - ["./bazelisk.sh", "run", "//quality:clang_format_fix", "--"] + - out_files) + ["./bazelisk.sh", "run", "//quality:clang_format_fix", "--", header_out_file]) except subprocess.CalledProcessError: - logging.error(f"failed to format {out_file} with clang-format.") + logging.error(f"failed to format {header_out_file} with clang-format.") sys.exit(1) - print(f"Autogenerated DIF successfully written to {out_files}.") - - if "checklist" in args.only: - checklist_template_file = ( - REPO_TOP / - "doc/project_governance/checklist/sw_checklist.md.tpl") - checklist_out_file = dif_dir / "dif_{}.md".format(ip.name_snake) - if checklist_out_file.is_file(): - raise FileExistsError( - "DIF checklist already exists for the IP. To " - "overwrite, delete existing checklist and try again.") - markdown_template = Template(checklist_template_file.read_text()) - checklist_out_file.write_text(markdown_template.render(ip=ip)) - print("DIF Checklist successfully written to {}.".format( - str(checklist_out_file))) - - # Render testutils templates. - if args.mode == "regen" or "autogen" in args.only: - gen_testutils(ips) + if "checklist" in args.only: + checklist_template_file = ( + REPO_TOP / + "doc/project_governance/checklist/sw_checklist.md.tpl") + checklist_out_file = dif_dir / "dif_{}.md".format(ip.name_snake) + if checklist_out_file.is_file(): + raise FileExistsError( + "DIF checklist already exists for the IP. To " + "overwrite, delete existing checklist and try again.") + markdown_template = Template(checklist_template_file.read_text()) + checklist_out_file.write_text(markdown_template.render(ip=ip)) + logging.info("DIF Checklist successfully written to {}.".format( + str(checklist_out_file))) if __name__ == "__main__":