| #!/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 |
| """autogen_testutils.py is a script for auto-generating a portion of the |
| `testutils` libraries from Mako templates. |
| |
| `testutils` libraries are testing libraries that sit a layer above the DIFs |
| that aid in writing chip-level tests by enabling test developers to re-use |
| code that calls a specific collection of DIFs. |
| |
| To render all testutil templates, run the script with: |
| $ util/autogen_testutils.py |
| """ |
| |
| import glob |
| import logging |
| import shutil |
| import subprocess |
| import sys |
| from pathlib import Path |
| |
| from mako.template import Template |
| |
| from autogen_banner import get_autogen_banner |
| from make_new_dif.ip import Ip |
| |
| # This file is $REPO_TOP/util/autogen_testutils.py, so it takes two parent() |
| # calls to get back to the top. |
| REPO_TOP = Path(__file__).resolve().parent.parent |
| |
| |
| def main(): |
| # Check clang-format is installed. |
| assert (shutil.which("clang-format") and |
| "ERROR: clang-format must be installed to format " |
| " autogenerated code to pass OpenTitan CI checks.") |
| |
| # Define input/output directories. |
| autogen_dif_directory = REPO_TOP / "sw/device/lib/dif/autogen" |
| testutils_templates_dir = REPO_TOP / "util/autogen_testutils" |
| autogen_testutils_dir = REPO_TOP / "sw/device/lib/testing/autogen" |
| |
| # Create list of IPs to generate shared testutils code for. This is all IPs |
| # that have a DIF library, that the testutils functions can use. |
| ips_with_difs = [] |
| for autogen_dif_filename in glob.iglob(str(autogen_dif_directory / "*.h")): |
| # 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_dif_filename).stem[4:-8] |
| # NOTE: ip.name_long_* not needed for auto-generated files which |
| # are the only files (re-)generated in batch mode. |
| ips_with_difs.append(Ip(ip_name_snake, "AUTOGEN")) |
| ips_with_difs.sort(key=lambda ip: ip.name_snake) |
| |
| # Create output directories if needed. |
| autogen_testutils_dir.mkdir(exist_ok=True) |
| |
| # Auto-generate testutils files. |
| for suffix in [".h", ".c"]: |
| for testutils_template_path_str in glob.iglob( |
| str(testutils_templates_dir / f"*{suffix}.tpl")): |
| testutils_template_path = Path(testutils_template_path_str) |
| |
| # Read in template, render it, and write it to the output file. |
| testutils_template = Template(testutils_template_path.read_text()) |
| testutils = Path(autogen_testutils_dir / |
| testutils_template_path.stem) |
| testutils.write_text( |
| testutils_template.render(ips_with_difs=ips_with_difs, |
| autogen_banner=get_autogen_banner( |
| "util/autogen_testutils.py", |
| comment="//"))) |
| |
| # Format autogenerated file with clang-format. |
| try: |
| subprocess.check_call(["clang-format", "-i", testutils]) |
| except subprocess.CalledProcessError: |
| logging.error( |
| f"failed to format {testutils} with clang-format.") |
| sys.exit(1) |
| |
| print("testutils \"{}\" successfully written to {}.".format( |
| suffix, str(testutils))) |
| |
| |
| if __name__ == "__main__": |
| main() |