Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[multitop] New bazel rules to describe HW #24791

Closed
wants to merge 50 commits into from

Conversation

pamaury
Copy link
Contributor

@pamaury pamaury commented Oct 15, 2024

The goal of this experiment is to design new rules to better describe the HW and eventually get rid of our current usage of all_files targets. The idea is that each IP contains a new target created by opentitan_ip where the RTL, doc and hjson files are listed. Then, those files targets are collected by an opentitan_top rule that puts together the entire list of doc, RTL and hjson files. One this is done, we start replace all direct usages of HW files by reference to this new top target where we selectively extra only the files we need. Eventually this should apply to:

  • all headers (C, rust, multi-top)
  • fusesoc
  • documentation

More is possible, for example we could point to testplans, we could separate RTL from DV, etc
This change will eventually be needed for multi-top because collecting all files as we currently do will not scale.

Finally, this PR contains another change: instead of pointing to //hw/ip/... for headers, we now collect everything in a new package //hw/top. There are several reasons for that:

  • we can start treating all IPs the same way, whether they are in hw/ip or hw/top_/ip/..., autogenerated or not
  • this moves us closer to a bazel-configuration-based top selection which will be used for multi-top
  • it solves the problem of IPs in hw/top that have top-specifiied parameters but those are not accessible when generating headers the way we currently do.

Since there are many IPs to convert and many files to patch, the approach in this PR is to create a script to automate most of the process. All commits before [util] Add script to convert... are manual. The rest is created automatically by the script to convert IPs and uses one by one, except for the last commit is manual.

Important remark: this does not duplicate any information that fusesoc has, this is completely orthogonal and only use coarse-grained globs to gather all files.

TODO:

  • see if we need to handle the node attribute of previous C/rust headers to select the default register node, or if we need to generate several headers for some IPs (one per node)

TODO in follow-up PRs:

  • cleanup the OTBN python: it's a complete mess, the way data files are handled and the the way it hack sys.path to point to util/ is not great. I couldn't quite get rid of all_files due to that.

@pamaury pamaury force-pushed the multitop_hw branch 4 times, most recently from aa03af3 to 0148575 Compare October 18, 2024 14:37
@pamaury pamaury force-pushed the multitop_hw branch 9 times, most recently from 2a0ca50 to ad3f459 Compare October 29, 2024 13:44
@pamaury pamaury requested review from matutem and Razer6 October 29, 2024 14:47
@pamaury pamaury force-pushed the multitop_hw branch 2 times, most recently from 93278aa to 352da59 Compare October 29, 2024 16:22
@pamaury pamaury marked this pull request as ready for review October 29, 2024 20:18
@pamaury pamaury requested review from a team, msfschaffner and vogelpi as code owners October 29, 2024 20:18
@pamaury pamaury requested review from engdoreis and a-will and removed request for a team October 29, 2024 20:18
@pamaury pamaury changed the title [experiment][multitop] New bazel rules to describe HW [multitop] New bazel rules to describe HW Oct 30, 2024
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/rv_timer/data/rv_timer.hjson --top hw/top_earlgrey hw/ip/rv_timer

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/spi_device/data/spi_device.hjson --top hw/top_earlgrey hw/ip/spi_device

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/spi_host/data/spi_host.hjson --top hw/top_earlgrey hw/ip/spi_host

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/sram_ctrl/data/sram_ctrl.hjson --top hw/top_earlgrey hw/ip/sram_ctrl

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson --top hw/top_earlgrey hw/ip/sysrst_ctrl

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --no-regs --top hw/top_earlgrey hw/ip/tlul

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/uart/data/uart.hjson --top hw/top_earlgrey hw/ip/uart

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/ip/usbdev/data/usbdev.hjson --top hw/top_earlgrey hw/ip/usbdev

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/top_earlgrey/ip/ast/data/ast.hjson --top hw/top_earlgrey hw/top_earlgrey/ip/ast

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --hjson hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson --top hw/top_earlgrey hw/top_earlgrey/ip/sensor_ctrl

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --no-regs --top hw/top_earlgrey hw/top_earlgrey/ip/xbar

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --no-regs --top hw/top_earlgrey hw/top_earlgrey/ip/xbar_main

Signed-off-by: Amaury Pouly <[email protected]>
This commit was generated by running
/home/pamaury/project/opentitan/util/rewrite_hw.py -v -g --root /home/pamaury/project/opentitan --no-regs --top hw/top_earlgrey hw/top_earlgrey/ip/xbar_peri

Signed-off-by: Amaury Pouly <[email protected]>
This commit switches the HW targets (verilator, bitstream) to use
the target create by `opentitan_top`. This allows to remove many of
the hacky `all_files` targets used everywhere. This commit does keep
a few and even creates some, but tries to adhere to the following
convention: only use `glob()` or `all_files` for sub-directories
that contain no bazel targets and should be passed "as-is" to
fusesoc.

Signed-off-by: Amaury Pouly <[email protected]>
@@ -87,6 +88,99 @@ autogen_hjson_c_header = rule(
},
)

def _opentitan_ip_c_header_impl(ctx):
header = ctx.actions.declare_file("{}_regs.h".format(ctx.attr.ip))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use f-strings: ...._file(f"{ctx.attr.ip}_regs.h")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortuntaley starlark doesn't support f-string

@@ -24,7 +24,7 @@ cc_library(
hdrs = ["aes.h"],
deps = [
":entropy",
"//hw/ip/aes/data:aes_c_regs",
"//hw/top:aes_c_regs",
Copy link
Contributor

@matutem matutem Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad the dep below is top-specific. I think it could be expressed in a top-independent for each driver below. Moreover, the list of units needing drivers could be extracted into a provider, which could help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not entirely sure I understand your comment @matutem . Are you saying that you would prefer that aes_c_regs was not a top-specific dependency?

@@ -37,7 +37,7 @@ cc_library(
],
deps = [
":base",
"//hw/ip/adc_ctrl/data:adc_ctrl_c_regs",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for lib/crypto/drivers. These are very regular rules for dif, drivers, and silicon_creator/drivers (at least).

"//hw/ip/otp_ctrl/data:otp_ctrl_c_regs",
"//hw/ip/spi_device/data:spi_device_c_regs",
"//hw/top_earlgrey/ip_autogen/flash_ctrl:flash_ctrl_c_regs",
"//hw/top:flash_ctrl_c_regs",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we generate the test_rom_libs in a loop over tops?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test_rom situation is a bit of mess: the englishbreakfast test_rom is very hacky and doesn't use the same files as earlgrey (e.g. it stubs out some some functions related to non-existent IPs) which makes this a very manual process. I think we will need to revisit how the test_rom is built and try to avoid having one cc_library per top if possible.

"//hw/top_earlgrey/ip_autogen/pinmux:pinmux_c_regs",
"//hw/top:gpio_c_regs",
"//hw/top:otp_ctrl_c_regs",
"//hw/top:pinmux_c_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this top-specific autogen be selected via //hw/top: ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes in the multi-top SW PR we have an alias //hw/top:top_lib for that. It's just not that in that PR.

"//hw/ip/sysrst_ctrl/data:sysrst_ctrl_rust_regs",
"//hw/ip/uart/data:uart_rust_regs",
"//hw/ip/usbdev/data:usbdev_rust_regs",
"//hw/top:adc_ctrl_rust_regs",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this list of _regs targets be provide by top?

Copy link
Contributor Author

@pamaury pamaury Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could create a single target that collects all rust_regs into one in //hw/top/

import os
import sys
from pathlib import Path

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a doc string for this interesting script, so it can tell what it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add more doc, however this script will disappear once all IPs are converted, it might even be deleted as part of this PR....

parser.add_argument('ip_dir', help='Path to the IP directory')
parser.add_argument('--root', help='Path to the project root (if not specified, assume CWD)')
parser.add_argument('-t', '--top', action='append', default=[],
help='Path to the top to edit (optional,c an be specified several times)')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... optional,c an... -> ... optional, can...

# We may need to go up several level for some ip_templates that don't have
# a BUILD file in data/
while not hjson_build_path.exists() and \
hjson_build_path.parent.parent.is_relative_to(project_root):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe .parent.parent -> parents[2] ?

Copy link
Contributor

@matutem matutem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some suggestions so far, and I hope you can figure out how to remove some of the top-specific dependencies and provide list of ips via top providers.

@pamaury
Copy link
Contributor Author

pamaury commented Dec 10, 2024

Closed in favor of #25580

@pamaury pamaury closed this Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants