Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 1 | # Copyright lowRISC contributors. |
| 2 | # Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | # SPDX-License-Identifier: Apache-2.0 |
| 4 | |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 5 | load("@nonhermetic//:env.bzl", "ENV") |
Alexander Williams | db7e744 | 2022-12-14 14:47:19 -0800 | [diff] [blame] | 6 | load("@ot_python_deps//:requirements.bzl", "entry_point") |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 7 | |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 8 | """Rules for running FuseSoC. |
| 9 | |
| 10 | FuseSoC is a package manager and set of build tools for HDL code. |
| 11 | |
| 12 | Because we want the output of some FuseSoC built resources to be |
| 13 | available to bazel (such as the verilated chip model for running |
| 14 | tests), the `fusesoc_build` rule allows bazel to delegate certain |
| 15 | targets to FuseSoC. |
| 16 | |
| 17 | This rule is not sandboxed, as our current configuration depends |
| 18 | on FuseSoC and its dependencies (verible, verilator, etc) already |
| 19 | having been installed. In the future, we will try to rework our |
| 20 | dependencies so the FuseSoC rules can be sandboxed. |
| 21 | """ |
| 22 | |
Miles Dai | 99f5044 | 2022-05-09 18:44:19 -0400 | [diff] [blame] | 23 | load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") |
| 24 | |
Drew Macrae | 18c77fa | 2022-10-18 10:57:08 -0400 | [diff] [blame] | 25 | def _corefiles2rootarg(core): |
| 26 | return core.dirname |
| 27 | |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 28 | def _fusesoc_build_impl(ctx): |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 29 | dirname = "build.{}".format(ctx.label.name) |
| 30 | out_dir = ctx.actions.declare_directory(dirname) |
| 31 | flags = [ctx.expand_location(f, ctx.attr.srcs) for f in ctx.attr.flags] |
| 32 | outputs = [out_dir] |
| 33 | groups = {} |
Drew Macrae | 18c77fa | 2022-10-18 10:57:08 -0400 | [diff] [blame] | 34 | args = ctx.actions.args() |
Drew Macrae | acfd5d0 | 2022-10-31 22:39:44 -0400 | [diff] [blame] | 35 | |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 36 | for group, files in ctx.attr.output_groups.items(): |
| 37 | deps = [ctx.actions.declare_file("{}/{}".format(dirname, f)) for f in files] |
| 38 | outputs.extend(deps) |
| 39 | groups[group] = depset(deps) |
| 40 | |
Miguel Osorio | 3f0e539 | 2022-06-09 09:26:53 -0700 | [diff] [blame] | 41 | if ctx.attr.verilator_options: |
| 42 | verilator_options = ctx.attr.verilator_options[BuildSettingInfo].value |
| 43 | flags.append("--verilator_options={}".format(" ".join(verilator_options))) |
Miles Dai | 99f5044 | 2022-05-09 18:44:19 -0400 | [diff] [blame] | 44 | |
Drew Macrae | acfd5d0 | 2022-10-31 22:39:44 -0400 | [diff] [blame] | 45 | if ctx.attr.make_options: |
| 46 | make_options = ctx.attr.make_options[BuildSettingInfo].value |
| 47 | flags.append("--make_options={}".format(" ".join(make_options))) |
| 48 | |
Drew Macrae | 18c77fa | 2022-10-18 10:57:08 -0400 | [diff] [blame] | 49 | args.add_all( |
| 50 | ctx.files.cores, |
| 51 | uniquify = True, |
| 52 | map_each = _corefiles2rootarg, |
| 53 | format_each = "--cores-root=%s", |
| 54 | ) |
| 55 | |
| 56 | args.add_all([ |
| 57 | "run", |
| 58 | "--flag=fileset_top", |
| 59 | ]) |
| 60 | args.add(ctx.attr.target, format = "--target=%s") |
| 61 | args.add_all([ |
| 62 | "--setup", |
| 63 | "--build", |
| 64 | ]) |
| 65 | args.add(out_dir.path, format = "--build-root=%s") |
| 66 | |
| 67 | args.add_all(ctx.attr.systems) |
| 68 | args.add_all(flags) |
Drew Macrae | 0e5292a | 2022-10-12 15:20:00 -0400 | [diff] [blame] | 69 | |
Yenkai Wang | d7cf4dc | 2023-03-15 13:13:40 -0700 | [diff] [blame^] | 70 | _inputs = ctx.files.srcs + ctx.files.cores |
| 71 | |
| 72 | # For some reason, the sanboxed fusesoc would call vivado twice. Add an |
| 73 | # option to use the system installed fusesoc. |
| 74 | if ctx.attr.use_system_fusesoc: |
| 75 | _exec = "fusesoc" |
| 76 | else: |
| 77 | _exec = ctx.executable._fusesoc |
| 78 | _inputs += ctx.files._fusesoc |
| 79 | |
Timothy Trippel | aa87069 | 2022-06-09 16:38:23 -0700 | [diff] [blame] | 80 | # Note: the `fileset_top` flag used above is specific to the OpenTitan |
| 81 | # project to select the correct RTL fileset. |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 82 | ctx.actions.run( |
| 83 | mnemonic = "FuseSoC", |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 84 | outputs = outputs, |
Yenkai Wang | d7cf4dc | 2023-03-15 13:13:40 -0700 | [diff] [blame^] | 85 | inputs = _inputs, |
Drew Macrae | 18c77fa | 2022-10-18 10:57:08 -0400 | [diff] [blame] | 86 | arguments = [args], |
Yenkai Wang | d7cf4dc | 2023-03-15 13:13:40 -0700 | [diff] [blame^] | 87 | executable = _exec, |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 88 | use_default_shell_env = False, |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 89 | execution_requirements = { |
| 90 | "no-sandbox": "", |
| 91 | }, |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 92 | env = ENV, |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 93 | ) |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 94 | return [ |
| 95 | DefaultInfo( |
| 96 | files = depset(outputs), |
| 97 | data_runfiles = ctx.runfiles(files = outputs + ctx.files.data), |
| 98 | ), |
| 99 | OutputGroupInfo(**groups), |
| 100 | ] |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 101 | |
| 102 | fusesoc_build = rule( |
| 103 | implementation = _fusesoc_build_impl, |
| 104 | attrs = { |
| 105 | "cores": attr.label_list(allow_files = True, doc = "FuseSoC core specification files"), |
| 106 | "srcs": attr.label_list(allow_files = True, doc = "Source files"), |
Chris Frantz | 9b34e4a | 2021-11-24 17:03:12 -0800 | [diff] [blame] | 107 | "data": attr.label_list(allow_files = True, doc = "Files needed at runtime"), |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 108 | "target": attr.string(mandatory = True, doc = "Target name (e.g. 'sim')"), |
| 109 | "systems": attr.string_list(mandatory = True, doc = "Systems to build"), |
Chris Frantz | 74f9095 | 2022-04-18 20:57:01 -0700 | [diff] [blame] | 110 | "flags": attr.string_list(doc = "Flags controlling the FuseSOC system build"), |
| 111 | "output_groups": attr.string_list_dict( |
| 112 | allow_empty = True, |
| 113 | doc = "Mapping of group name to lists of files in that named group", |
| 114 | ), |
Miles Dai | 99f5044 | 2022-05-09 18:44:19 -0400 | [diff] [blame] | 115 | "verilator_options": attr.label(), |
Drew Macrae | acfd5d0 | 2022-10-31 22:39:44 -0400 | [diff] [blame] | 116 | "make_options": attr.label(), |
Yenkai Wang | d7cf4dc | 2023-03-15 13:13:40 -0700 | [diff] [blame^] | 117 | "use_system_fusesoc": attr.bool( |
| 118 | default = False, |
| 119 | doc = "Use non-sanboxed fusesoc (for FPGA vivado build)", |
| 120 | ), |
Alexander Williams | db7e744 | 2022-12-14 14:47:19 -0800 | [diff] [blame] | 121 | "_fusesoc": attr.label( |
| 122 | default = entry_point("fusesoc"), |
| 123 | executable = True, |
| 124 | cfg = "exec", |
| 125 | ), |
Chris Frantz | 6da32ea | 2021-11-22 13:12:08 -0800 | [diff] [blame] | 126 | }, |
| 127 | ) |