From df777db8148501ee918f0f125b44ce1068472b23 Mon Sep 17 00:00:00 2001 From: Guillermo Maturana Date: Wed, 17 Jan 2024 06:39:57 +0000 Subject: [PATCH] [topgen] Pass topname key/value pair to ipgen This pair is uniformly added to all ipgen modules. Change topgen.py to adopt the convention that, for example, the variable topname is just earlgrey for example, while top_name is top_earlgrey. Signed-off-by: Guillermo Maturana --- .../data/alert_handler.tpldesc.hjson | 6 ++ hw/ip_templates/pwrmgr/README.md.tpl | 2 +- .../pwrmgr/data/pwrmgr.tpldesc.hjson | 2 +- hw/ip_templates/pwrmgr/doc/interfaces.md.tpl | 2 +- hw/ip_templates/pwrmgr/doc/registers.md.tpl | 2 +- hw/ip_templates/pwrmgr/dv/README.md.tpl | 22 ++--- .../seq_lib/pwrmgr_wakeup_reset_vseq.sv.tpl | 2 +- .../rv_plic/data/rv_plic.tpldesc.hjson | 6 ++ .../top_earlgrey_alert_handler.ipconfig.hjson | 1 + .../data/top_earlgrey_pwrmgr.ipconfig.hjson | 2 +- .../data/top_earlgrey_rv_plic.ipconfig.hjson | 1 + util/ipgen/lib.py | 1 - util/topgen.py | 85 ++++++++++--------- 13 files changed, 75 insertions(+), 59 deletions(-) diff --git a/hw/ip_templates/alert_handler/data/alert_handler.tpldesc.hjson b/hw/ip_templates/alert_handler/data/alert_handler.tpldesc.hjson index fc0b08906ac334..6266633d01848f 100644 --- a/hw/ip_templates/alert_handler/data/alert_handler.tpldesc.hjson +++ b/hw/ip_templates/alert_handler/data/alert_handler.tpldesc.hjson @@ -3,6 +3,12 @@ // SPDX-License-Identifier: Apache-2.0 { template_param_list: [ + { + name: "topname" + desc: "Name of top-level design, e.g., 'darjeeling' or 'earlgrey'" + type: "string" + default: "" + } { name: "n_alerts" desc: "Number of alert sources" diff --git a/hw/ip_templates/pwrmgr/README.md.tpl b/hw/ip_templates/pwrmgr/README.md.tpl index fa8cc5e12f807d..e3882098c6a15a 100644 --- a/hw/ip_templates/pwrmgr/README.md.tpl +++ b/hw/ip_templates/pwrmgr/README.md.tpl @@ -1,5 +1,5 @@ # Power Manager HWIP Technical Specification -[`pwrmgr`](https://reports.opentitan.org/hw/top_${top_name}/ip_autogen/pwrmgr/dv/latest/report.html): +[`pwrmgr`](https://reports.opentitan.org/hw/top_${topname}/ip_autogen/pwrmgr/dv/latest/report.html): ![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/test.svg) ![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/passing.svg) ![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/functional.svg) diff --git a/hw/ip_templates/pwrmgr/data/pwrmgr.tpldesc.hjson b/hw/ip_templates/pwrmgr/data/pwrmgr.tpldesc.hjson index a1ea7906727ff7..7ae94a16ae2f0a 100644 --- a/hw/ip_templates/pwrmgr/data/pwrmgr.tpldesc.hjson +++ b/hw/ip_templates/pwrmgr/data/pwrmgr.tpldesc.hjson @@ -4,7 +4,7 @@ { template_param_list: [ { - name: "top_name" + name: "topname" desc: "Name of top-level design, e.g., 'darjeeling' or 'earlgrey'" type: "string" default: "" diff --git a/hw/ip_templates/pwrmgr/doc/interfaces.md.tpl b/hw/ip_templates/pwrmgr/doc/interfaces.md.tpl index c3de8cc7c37860..34a228c54563e0 100644 --- a/hw/ip_templates/pwrmgr/doc/interfaces.md.tpl +++ b/hw/ip_templates/pwrmgr/doc/interfaces.md.tpl @@ -1,6 +1,6 @@ # Hardware Interfaces - + Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`pwrmgr`** has the following hardware interfaces defined - Primary Clock: **`clk_i`** - Other Clocks: **`clk_slow_i`**, **`clk_lc_i`**, **`clk_esc_i`** diff --git a/hw/ip_templates/pwrmgr/doc/registers.md.tpl b/hw/ip_templates/pwrmgr/doc/registers.md.tpl index 1bda7a75f7b5e6..3b252c7dffdaa0 100644 --- a/hw/ip_templates/pwrmgr/doc/registers.md.tpl +++ b/hw/ip_templates/pwrmgr/doc/registers.md.tpl @@ -1,6 +1,6 @@ # Registers - + ${"##"} Summary | Name | Offset | Length | Description | diff --git a/hw/ip_templates/pwrmgr/dv/README.md.tpl b/hw/ip_templates/pwrmgr/dv/README.md.tpl index 08014bb9c4d553..17638fa1c3036f 100644 --- a/hw/ip_templates/pwrmgr/dv/README.md.tpl +++ b/hw/ip_templates/pwrmgr/dv/README.md.tpl @@ -1,5 +1,5 @@ # PWRMGR DV document - +<% top_name = f"top_{topname}" %> ${"##"} Goals * **DV** * Verify all PWRMGR IP features by running dynamic simulations with a SV/UVM based testbench. @@ -10,7 +10,7 @@ ${"##"} Goals ${"##"} Current status * [Design & verification stage](../doc/checklist.md) * [HW development stages](../../../../../doc/project_governance/development_stages.md) -* [Simulation results](https://reports.opentitan.org/hw/top_${top_name}/ip_autogen/pwrmgr/dv/latest/report.html) +* [Simulation results](https://reports.opentitan.org/hw/${top_name}/ip_autogen/pwrmgr/dv/latest/report.html) ${"##"} Design features For detailed information on PWRMGR design features, please see the [PWRMGR HWIP technical specification](../README.md). @@ -22,12 +22,12 @@ ${"###"} Block diagram ![Block diagram](./doc/tb.svg) ${"###"} Top level testbench -Top level testbench is located at [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/tb.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/tb.sv). -It instantiates the PWRMGR DUT module [`hw/top_${top_name}/ip_autogen/pwrmgr/rtl/pwrmgr.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/rtl/pwrmgr.sv). +Top level testbench is located at [`hw/${top_name}/ip_autogen/pwrmgr/dv/tb.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/tb.sv). +It instantiates the PWRMGR DUT module [`hw/${top_name}/ip_autogen/pwrmgr/rtl/pwrmgr.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/rtl/pwrmgr.sv). In addition, it instantiates the following interfaces, connects them to the DUT and sets their handle into `uvm_config_db`: * [Clock and reset interface](../../../../dv/sv/common_ifs/README.md) * [TileLink host interface](../../../../dv/sv/tl_agent/README.md) -* PWRMGR interface [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv). +* PWRMGR interface [`hw/${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv). * Interrupts ([`pins_if`](../../../../dv/sv/common_ifs/README.md)) * Alerts ([`alert_esc_if`](../../../../dv/sv/alert_esc_agent/README.md)) @@ -38,7 +38,7 @@ The following utilities provide generic helper tasks and functions to perform ac ${"###"} Global types & methods All common types and methods defined at the package level can be found in -[`pwrmgr_env_pkg`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv). +[`pwrmgr_env_pkg`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv). Some of them in use are: ```systemverilog typedef enum int { @@ -75,7 +75,7 @@ It can be created manually by invoking [`regtool`](../../../../../util/reggen/do ${"###"} Stimulus strategy The sequences are closely related to the testplan's testpoints. Testpoints and coverage are described in more detail in the [testplan](#testplan). -All test sequences reside in [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/env/seq_lib`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/env/seq_lib), and extend `pwrmgr_base_vseq`. +All test sequences reside in [`hw/${top_name}/ip_autogen/pwrmgr/dv/env/seq_lib`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/env/seq_lib), and extend `pwrmgr_base_vseq`. The `pwrmgr_base_vseq` virtual sequence is extended from `cip_base_vseq` and serves as a starting point. It provides commonly used handles, variables, functions and tasks used by the test sequences. Some of the most commonly used tasks and functions are as follows: @@ -153,7 +153,7 @@ ${"#####"} AST - Outputs `core_clk_en`, `io_clk_en`, and `usb_clk_en` reset low, and go high prior to the slow fsm requesting the fast fsm to wakeup. Notice the usb clock can be programmed to stay low on wakeup via the `control` CSR. These clock enables are cleared on reset, and should match their corresponding enables in the `control` CSR on low power transitions. - These clock enables are checked via SVAs in [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv). + These clock enables are checked via SVAs in [`hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv). When slow fsm transitions to `SlowPwrStateReqPwrUp` the clock enables should be on (except usb should match `control.usb_clk_en_active`). When slow fsm transitions to `SlowPwrStatePwrClampOn` the clock enables should match their bits in the `control` CSR. - Inputs `core_clk_val`, `io_clk_val`, and `usb_clk_val` track the corresponding enables. @@ -161,7 +161,7 @@ ${"#####"} AST Slow fsm waits for them to go high prior to requesting fast fsm wakeup. Lack of a high transition when needed is detected via timeout. Such timeout would be due to the corresponding enables being set incorrectly. - These inputs are checked via SVAs in [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv). + These inputs are checked via SVAs in [`hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv). - Output `main_pd_n` should go high when slow fsm transitions to `SlowPwrStateMainPowerOn`, and should match `control.main_pd_n` CSR when slow fsm transitions to `SlowPwrStateMainPowerOff`. - Input `main_pok` should turn on for the slow fsm to start power up sequence. This is also driven by `slow_responder`, which turn this off in response to `main_pd_n` going low, and turn it back on after a few random slow clock cycles from `main_pd_n` going high. @@ -226,7 +226,7 @@ There are a number of wakeup and reset requests. They are driven by sequences as they need to. ${"####"} Assertions -The [`hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv) module binds a few modules containing assertions to the IP as follows: +The [`hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/${top_name}/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv) module binds a few modules containing assertions to the IP as follows: * TLUL assertions: the `tlul_assert` [assertions](../../../../ip/tlul/doc/TlulProtocolChecker.md) ensures TileLink interface protocol compliance. * Clock enables assertions: The `pwrmgr_clock_enables_sva_if` module contains assertions checking that the various clk_en outputs correspond to the settings in the `control` CSR. @@ -248,7 +248,7 @@ We are using our in-house developed [regression tool](../../../../../util/dvsim/ Please take a look at the link for detailed information on the usage, capabilities, features and known issues. Here's how to run a smoke test: ```console -$ $REPO_TOP/util/dvsim/dvsim.py $REPO_TOP/hw/top_${top_name}/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson -i pwrmgr_smoke +$ $REPO_TOP/util/dvsim/dvsim.py $REPO_TOP/hw/${top_name}/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson -i pwrmgr_smoke ``` ${"##"} Testplan diff --git a/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv.tpl b/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv.tpl index af599b0b95c927..9b4c361fbe16c2 100644 --- a/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv.tpl +++ b/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv.tpl @@ -27,7 +27,7 @@ class pwrmgr_wakeup_reset_vseq extends pwrmgr_base_vseq; // transition to active state. // ICEBOX(lowrisc/opentitan#18236) Consider adding checks to monitor fast state transitions are // compliant with "ROM Integrity Checks" at - // https://opentitan.org/book/hw/top_${top_name}/ip_autogen/pwrmgr/doc/theory_of_operation.html#rom-integrity-checks + // https://opentitan.org/book/hw/top_${topname}/ip_autogen/pwrmgr/doc/theory_of_operation.html#rom-integrity-checks virtual task twirl_rom_response(); cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4False; cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4False; diff --git a/hw/ip_templates/rv_plic/data/rv_plic.tpldesc.hjson b/hw/ip_templates/rv_plic/data/rv_plic.tpldesc.hjson index 72de4b7ffe90b1..15a72c2a30b2e5 100644 --- a/hw/ip_templates/rv_plic/data/rv_plic.tpldesc.hjson +++ b/hw/ip_templates/rv_plic/data/rv_plic.tpldesc.hjson @@ -3,6 +3,12 @@ // SPDX-License-Identifier: Apache-2.0 { template_param_list: [ + { + name: "topname" + desc: "Name of top-level design, e.g., 'darjeeling' or 'earlgrey'" + type: "string" + default: "" + } { name: "src" desc: "Number of interrupt sources" diff --git a/hw/top_earlgrey/ip_autogen/alert_handler/data/top_earlgrey_alert_handler.ipconfig.hjson b/hw/top_earlgrey/ip_autogen/alert_handler/data/top_earlgrey_alert_handler.ipconfig.hjson index 625058c06b70db..af5299672cfe50 100644 --- a/hw/top_earlgrey/ip_autogen/alert_handler/data/top_earlgrey_alert_handler.ipconfig.hjson +++ b/hw/top_earlgrey/ip_autogen/alert_handler/data/top_earlgrey_alert_handler.ipconfig.hjson @@ -146,5 +146,6 @@ 5'd17 5'd17 ] + topname: earlgrey } } diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/data/top_earlgrey_pwrmgr.ipconfig.hjson b/hw/top_earlgrey/ip_autogen/pwrmgr/data/top_earlgrey_pwrmgr.ipconfig.hjson index 31d2caeddf7d51..ebc6021bb1459e 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/data/top_earlgrey_pwrmgr.ipconfig.hjson +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/data/top_earlgrey_pwrmgr.ipconfig.hjson @@ -5,7 +5,6 @@ instance_name: top_earlgrey_pwrmgr param_values: { - top_name: earlgrey NumWkups: 6 Wkups: [ @@ -80,5 +79,6 @@ ] } NumRstReqs: 2 + topname: earlgrey } } diff --git a/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson b/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson index a522eb49154eb3..e7abdec8a5258d 100644 --- a/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson +++ b/hw/top_earlgrey/ip_autogen/rv_plic/data/top_earlgrey_rv_plic.ipconfig.hjson @@ -8,5 +8,6 @@ src: 185 target: 1 prio: 3 + topname: earlgrey } } diff --git a/util/ipgen/lib.py b/util/ipgen/lib.py index 4abf2703c03f8d..866d78bf7c64d0 100644 --- a/util/ipgen/lib.py +++ b/util/ipgen/lib.py @@ -191,7 +191,6 @@ def _check_object(obj: object, what: str) -> object: """Check that obj is a Hjson-serializable object. If not, raise a ValueError; the what argument names the object. - """ try: # Round-trip objects through the JSON encoder to get the diff --git a/util/topgen.py b/util/topgen.py index 4fbefe691d21ac..c458cf70e85630 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -51,8 +51,8 @@ // SPDX-License-Identifier: Apache-2.0 """ + warnhdr -GENCMD = ("// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson\n" - "// -o hw/top_{topname}") +GENCMD = ("// util/topgen.py -t hw/{top_name}/data/{top_name}.hjson\n" + "// -o hw/{top_name}") SRCTREE_TOP = Path(__file__).parents[1].resolve() @@ -69,10 +69,12 @@ def ipgen_render(template_name: str, topname: str, params: Dict[str, object], Aborts the program execution in case of an error. """ module_name = params.get("module_instance_name", template_name) - instance_name = f"top_{topname}_{module_name}" + top_name = f"top_{topname}" + instance_name = f"{top_name}_{module_name}" ip_template = IpTemplate.from_template_path(SRCTREE_TOP / "hw" / "ip_templates" / template_name) + params.update({"topname": topname}) try: ip_config = IpConfig(ip_template.params, instance_name, params) except ValueError as e: @@ -100,16 +102,16 @@ def generate_top(top: Dict[str, object], name_to_block: Dict[str, IpBlock], def generate_xbars(top: Dict[str, object], out_path: Path) -> None: - topname = top["name"] - gencmd = ("// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson " - "-o hw/top_{topname}/\n\n".format(topname=topname)) + top_name = "top_" + top["name"] + gencmd = (f"// util/topgen.py -t hw/{top_name}/data/{top_name}.hjson " + f"-o hw/{top_name}/\n\n") for obj in top["xbar"]: objname = obj["name"] xbar_path = out_path / "ip" / f"xbar_{objname}" / "data" / "autogen" xbar_path.mkdir(parents=True, exist_ok=True) xbar = tlgen.validate(obj) - xbar.ip_path = "/".join(["hw", f"top_{topname}", "ip", "{dut}"]) + xbar.ip_path = "/".join(["hw", top_name, "ip", "{dut}"]) # Generate output of crossbar with complete fields xbar_hjson_path = xbar_path / f"xbar_{xbar.name}.gen.hjson" @@ -120,7 +122,7 @@ def generate_xbars(top: Dict[str, object], out_path: Path) -> None: log.error("Elaboration failed." + repr(xbar)) try: - results = tlgen.generate(xbar, f"top_{topname}") + results = tlgen.generate(xbar, top_name) except: # noqa: E722 log.error(exceptions.text_error_template().render()) @@ -136,7 +138,7 @@ def generate_xbars(top: Dict[str, object], out_path: Path) -> None: dv_path.mkdir(parents=True, exist_ok=True) # generate testbench for xbar - tlgen.generate_tb(xbar, dv_path, f"top_{topname}") + tlgen.generate_tb(xbar, dv_path, top_name) # Read back the comportable IP and amend to Xbar xbar_ipfile = ip_path / "data" / "autogen" / f"xbar_{objname}.hjson" @@ -331,9 +333,10 @@ def generate_pinmux(top: Dict[str, object], out_path: Path) -> None: original_rtl_path = orig_ip_path / "rtl" # Generate register package and RTLs + top_name = f"top_{topname}" gencmd = ( - f"// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson " - f"-o hw/top_{topname}/\n\n") + f"// util/topgen.py -t hw/{top_name}/data/{top_name}.hjson " + f"-o hw/{top_name}/\n\n") hjson_gen_path = data_path / "pinmux.hjson" @@ -447,7 +450,6 @@ def generate_pwrmgr(top: Dict[str, object], out_path: Path) -> None: "Reset requests are not supported.") params = { - "top_name": topname, "NumWkups": n_wkups, "Wkups": top["wakeups"], "rst_reqs": top["reset_requests"], @@ -616,7 +618,7 @@ def generate_flash(topcfg: Dict[str, object], out_path: Path) -> None: def generate_top_only(top_only_dict: Dict[str, bool], out_path: Path, - topname: str, alt_hjson_path: str) -> None: + top_name: str, alt_hjson_path: str) -> None: log.info("Generating top only modules") for ip, reggen_only in top_only_dict.items(): @@ -624,7 +626,7 @@ def generate_top_only(top_only_dict: Dict[str, bool], out_path: Path, if reggen_only and alt_hjson_path is not None: hjson_dir = Path(alt_hjson_path) else: - hjson_dir = (SRCTREE_TOP / "hw" / f"top_{topname}" / "ip" / ip / + hjson_dir = (SRCTREE_TOP / "hw" / top_name / "ip" / ip / "data") hjson_path = hjson_dir / f"{ip}.hjson" @@ -795,13 +797,13 @@ def _process_top(topcfg: Dict[str, object], args: argparse.Namespace, } log.info("Filtered dict is {}".format(top_only_dict)) - topname = topcfg["name"] + top_name = f"top_{topcfg['name']}" # Sweep the IP directory and gather the config files ip_dir = Path(__file__).parents[1] / "hw/ip" ips = search_ips(ip_dir) - # exclude filtered IPs (to use top_${topname} one) and + # exclude filtered IPs (to use ${top_name} one) and exclude_list = generated_list + list(top_only_dict.keys()) ips = [x for x in ips if not x.parents[1].name in exclude_list] @@ -877,7 +879,7 @@ def _process_top(topcfg: Dict[str, object], args: argparse.Namespace, tpl_path = SRCTREE_TOP / "hw/ip_templates" / ip_name ip_template = IpTemplate.from_template_path(tpl_path) ip_config = IpConfig(ip_template.params, - f"top_{topname}_{ip_name}") + f"{top_name}_{ip_name}") try: ip_desc = IpDescriptionOnlyRenderer( @@ -974,7 +976,7 @@ def _process_top(topcfg: Dict[str, object], args: argparse.Namespace, # Generate top only modules # These modules are not templated, but are not in hw/ip - generate_top_only(top_only_dict, out_path, topname, args.hjson_path) + generate_top_only(top_only_dict, out_path, top_name, args.hjson_path) return completecfg, name_to_block @@ -1199,6 +1201,7 @@ def main(): out_path_gen, pass_idx) topname = topcfg["name"] + top_name = f"top_{topname}" # Create the chip-level RAL only if args.top_ral: @@ -1228,14 +1231,14 @@ def main(): # Generate top.gen.hjson right before rendering genhjson_dir = out_path / "data/autogen" genhjson_dir.mkdir(parents=True, exist_ok=True) - genhjson_path = genhjson_dir / ("top_%s.gen.hjson" % completecfg["name"]) + genhjson_path = genhjson_dir / f"{top_name}.gen.hjson" # Header for HJSON gencmd = """// -// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson \\ -// -o hw/top_{topname}/ \\ +// util/topgen.py -t hw/{top_name}/data/{top_name}.hjson \\ +// -o hw/{top_name}/ \\ // --rnd_cnst_seed {seed} -""".format(topname=topname, seed=completecfg["rnd_cnst_seed"]) +""".format(top_name=top_name, seed=completecfg["rnd_cnst_seed"]) genhjson_path.write_text(genhdr + gencmd + hjson.dumps(completecfg, for_json=True) + '\n') @@ -1260,16 +1263,16 @@ def render_template(template_path: str, rendered_path: Path, # Header for SV files gencmd = warnhdr + """// -// util/topgen.py -t hw/top_{topname}/data/top_{topname}.hjson \\ -// -o hw/top_{topname}/ \\ +// util/topgen.py -t hw/{top_name}/data/{top_name}.hjson \\ +// -o hw/{top_name}/ \\ // --rnd_cnst_seed \\ // {seed} -""".format(topname=topname, seed=completecfg["rnd_cnst_seed"]) +""".format(top_name=top_name, seed=completecfg["rnd_cnst_seed"]) # SystemVerilog Top: - # "toplevel.sv.tpl" -> "rtl/autogen/top_{topname}.sv" + # "toplevel.sv.tpl" -> "rtl/autogen/{top_name}.sv" render_template(TOPGEN_TEMPLATE_PATH / "toplevel.sv.tpl", - out_path / f"rtl/autogen/top_{topname}.sv", + out_path / "rtl" / "autogen" / f"{top_name}.sv", gencmd=gencmd) # Multiple chip-levels (ASIC, FPGA, Verilator, etc) @@ -1285,16 +1288,16 @@ def render_template(template_path: str, rendered_path: Path, # object to store it. c_helper = TopGenCTest(completecfg, name_to_block) - # "toplevel_pkg.sv.tpl" -> "rtl/autogen/top_{topname}_pkg.sv" + # "toplevel_pkg.sv.tpl" -> "rtl/autogen/{top_name}_pkg.sv" render_template(TOPGEN_TEMPLATE_PATH / "toplevel_pkg.sv.tpl", - out_path / f"rtl/autogen/top_{topname}_pkg.sv", + out_path / "rtl" / "autogen" / f"{top_name}_pkg.sv", helper=c_helper, gencmd=gencmd) # compile-time random netlist constants render_template(TOPGEN_TEMPLATE_PATH / "toplevel_rnd_cnst_pkg.sv.tpl", out_path / - f"rtl/autogen/top_{topname}_rnd_cnst_pkg.sv", + f"rtl/autogen/{top_name}_rnd_cnst_pkg.sv", gencmd=gencmd) # Since SW does not use FuseSoC and instead expects those files always @@ -1305,14 +1308,14 @@ def render_template(template_path: str, rendered_path: Path, root_paths = [out_path.resolve(), SRCTREE_TOP] out_paths = [ out_path.resolve(), - (SRCTREE_TOP / "hw/top_{}/".format(topname)).resolve() + (SRCTREE_TOP / "hw" / top_name).resolve() ] for idx, path in enumerate(out_paths): # C Header + C File + Clang-format file # "clang-format" -> "sw/autogen/.clang-format" cformat_tplpath = TOPGEN_TEMPLATE_PATH / "clang-format" - cformat_dir = path / "sw/autogen" + cformat_dir = path / "sw" / "autogen" cformat_dir.mkdir(parents=True, exist_ok=True) cformat_path = cformat_dir / ".clang-format" cformat_path.write_text(cformat_tplpath.read_text()) @@ -1322,8 +1325,8 @@ def render_template(template_path: str, rendered_path: Path, c_helper.header_macro_prefix = ( "OPENTITAN_" + str(rel_header_dir).replace("/", "_").upper()) - # "top_{topname}.h.tpl" -> "sw/autogen/top_{topname}.h" - cheader_path = cformat_dir / f"top_{topname}.h" + # "{top_name}.h.tpl" -> "sw/autogen/{top_name}.h" + cheader_path = cformat_dir / f"{top_name}.h" render_template(TOPGEN_TEMPLATE_PATH / "toplevel.h.tpl", cheader_path, helper=c_helper) @@ -1332,17 +1335,17 @@ def render_template(template_path: str, rendered_path: Path, rel_header_path = cheader_path.relative_to(root_paths[idx]) c_helper.header_path = str(rel_header_path) - # "toplevel.c.tpl" -> "sw/autogen/top_{topname}.c" + # "toplevel.c.tpl" -> "sw/autogen/{top_name}.c" render_template(TOPGEN_TEMPLATE_PATH / "toplevel.c.tpl", - cformat_dir / f"top_{topname}.c", + cformat_dir / f"{top_name}.c", helper=c_helper) - # "toplevel_memory.ld.tpl" -> "sw/autogen/top_{topname}_memory.ld" + # "toplevel_memory.ld.tpl" -> "sw/autogen/{top_name}_memory.ld" render_template(TOPGEN_TEMPLATE_PATH / "toplevel_memory.ld.tpl", - cformat_dir / f"top_{topname}_memory.ld") + cformat_dir / f"{top_name}_memory.ld") - # "toplevel_memory.h.tpl" -> "sw/autogen/top_{topname}_memory.h" - memory_cheader_path = cformat_dir / f"top_{topname}_memory.h" + # "toplevel_memory.h.tpl" -> "sw/autogen/{top_name}_memory.h" + memory_cheader_path = cformat_dir / f"{top_name}_memory.h" render_template(TOPGEN_TEMPLATE_PATH / "toplevel_memory.h.tpl", memory_cheader_path, helper=c_helper) @@ -1385,7 +1388,7 @@ def render_template(template_path: str, rendered_path: Path, gen_top_docs(completecfg, c_helper, out_path) # Auto-generate tests in "sw/device/tests/autogen" area. - gencmd = warnhdr + GENCMD.format(topname=topname) + gencmd = warnhdr + GENCMD.format(top_name=top_name) for fname in ["plic_all_irqs_test.c", "alert_test.c", "BUILD"]: outfile = SRCTREE_TOP / "sw/device/tests/autogen" / fname render_template(TOPGEN_TEMPLATE_PATH / f"{fname}.tpl",