feat(build): Add FPGA toolchain support and enhance binary rules Change-Id: Iede67e519368f5f58ac368cf1d40acc909cd37b0
diff --git a/.bazelrc b/.bazelrc index 46c1a8c..a78752b 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -31,16 +31,19 @@ build --action_env=VC_STATIC_HOME build --action_env=VERDI_HOME build --action_env=LM_LICENSE_FILE +build --action_env=XILINXD_LICENSE_FILE test --build_tag_filters="-vcs,-renode,-verilator,-synthesis" test --test_tag_filters="-vcs,-renode,-verilator,-synthesis" test --action_env=VCS_HOME test --action_env=VC_STATIC_HOME test --action_env=VERDI_HOME test --action_env=LM_LICENSE_FILE +test --action_env=XILINXD_LICENSE_FILE run --action_env=VCS_HOME run --action_env=VC_STATIC_HOME run --action_env=VERDI_HOME run --action_env=LM_LICENSE_FILE +run --action_env=XILINXD_LICENSE_FILE # Add config to enable VCS targets. build:vcs --build_tag_filters="vcs"
diff --git a/WORKSPACE b/WORKSPACE index ec83784..187ab52 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -14,7 +14,7 @@ workspace(name = "kelvin_hw") -load("//rules:repos.bzl", "kelvin_repos", "renode_repos", "cvfpu_repos", "rvvi_repos") +load("//rules:repos.bzl", "kelvin_repos", "renode_repos", "cvfpu_repos", "rvvi_repos", "fpga_repos") kelvin_repos() @@ -88,10 +88,47 @@ python_version = "3.9", ) +fpga_repos() + +load("@lowrisc_opentitan_gh//rules:nonhermetic.bzl", "nonhermetic_repo") + +nonhermetic_repo(name = "nonhermetic") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +load("@rules_python//python:pip.bzl", "pip_parse") + +pip_parse( + name = "ot_python_deps", + requirements_lock = "@lowrisc_opentitan_gh//:python-requirements.txt", + python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python", +) + load("//third_party/python:requirements.bzl", "install_deps") install_deps() -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +# OpenTitan's requirements need this, but for some reason do not provide it. +http_archive( + name = "ot_python_deps_importlib_metadata", + urls = [ + "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", + ], + sha256 = "e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", + type = "zip", + build_file_content = """ +package(default_visibility = ["//visibility:public"]) +py_library( + name = "pkg", + srcs = glob(["**/*.py"]), + data = [] + glob(["**/*"], exclude=["**/* *", "**/*.dist-info/RECORD", "**/*.py", "**/*.pyc"]), + imports = ["."], + tags = ["pypi_name=importlib_metadata","pypi_version=8.7.0"], +) +""", +) + +load("@ot_python_deps//:requirements.bzl", ot_install_deps = "install_deps") +ot_install_deps() http_archive( name = "toolchain_kelvin_v2",
diff --git a/fpga/0001-Export-hw-ip_templates.patch b/fpga/0001-Export-hw-ip_templates.patch new file mode 100644 index 0000000..4620e1b --- /dev/null +++ b/fpga/0001-Export-hw-ip_templates.patch
@@ -0,0 +1,44 @@ +From 626a4c6e202972b7930797cb7a43f8ee6ac6b991 Mon Sep 17 00:00:00 2001 +From: Alex Van Damme <atv@google.com> +Date: Fri, 18 Jul 2025 14:48:57 -0700 +Subject: [PATCH] Export hw/ip_templates + +--- + hw/BUILD | 3 +-- + hw/ip_templates/BUILD | 2 ++ + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/hw/BUILD b/hw/BUILD +index 2fb71c7d81..d7e28a91a8 100644 +--- a/hw/BUILD ++++ b/hw/BUILD +@@ -15,7 +15,7 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_list_flag") + + package(default_visibility = ["//visibility:public"]) + +-exports_files(["tool_requirements.py"]) ++exports_files(["tool_requirements.py"] + glob(["vendor/lowrisc_ibex/**"])) + + filegroup( + name = "doc_files", +@@ -177,7 +177,6 @@ filegroup( + # dv_macros are needed by Ibex, so include this back in. + "//hw/dv/sv:dv_macros", + "//hw/ip:rtl_files", +- "//hw/top_earlgrey:rtl_files", + ], + visibility = ["//visibility:public"], + ) +diff --git a/hw/ip_templates/BUILD b/hw/ip_templates/BUILD +index 3e8bb41965..a9431cda2e 100644 +--- a/hw/ip_templates/BUILD ++++ b/hw/ip_templates/BUILD +@@ -1,3 +1,5 @@ + # Copyright lowRISC contributors (OpenTitan project). + # Licensed under the Apache License, Version 2.0, see LICENSE for details. + # SPDX-License-Identifier: Apache-2.0 ++ ++exports_files(glob(["**"])) +-- +2.50.0.727.gbf7dc18ff4-goog +
diff --git a/fpga/BUILD b/fpga/BUILD new file mode 100644 index 0000000..36a1e8d --- /dev/null +++ b/fpga/BUILD
@@ -0,0 +1,14 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +
diff --git a/rules/kelvin_v2.bzl b/rules/kelvin_v2.bzl index 3a4dc6d..22423da 100644 --- a/rules/kelvin_v2.bzl +++ b/rules/kelvin_v2.bzl
@@ -87,14 +87,23 @@ if CcInfo in dep: compilation_contexts.append(dep[CcInfo].compilation_context) linking_contexts.append(dep[CcInfo].linking_context) + + sources = [] + headers = [] + for src in ctx.files.srcs: + if src.extension in ["h", "hh", "hpp"]: + headers.append(src) + else: + sources.append(src) + (_compilation_context, compilation_outputs) = cc_common.compile( actions = ctx.actions, cc_toolchain = cc_toolchain, feature_configuration = feature_configuration, name = ctx.label.name, - srcs = ctx.files.srcs, + srcs = sources, compilation_contexts = compilation_contexts, - private_hdrs = ctx.files.hdrs, + private_hdrs = headers + ctx.files.hdrs, user_compile_flags = ctx.attr.copts, defines = ctx.attr.defines, ) @@ -112,13 +121,58 @@ output_type = "executable", ) + out_bin = ctx.actions.declare_file("{}.bin".format(ctx.label.name)) + objcopy_tool = cc_toolchain.objcopy_executable + + ctx.actions.run( + outputs = [out_bin], + inputs = [linking_outputs.executable] + cc_toolchain.all_files.to_list(), + executable = objcopy_tool, + arguments = [ + "-O", + "binary", + linking_outputs.executable.path, + out_bin.path, + ], + mnemonic = "ObjCopy", + ) + + out_vmem = ctx.actions.declare_file("{}.vmem".format(ctx.label.name)) + word_size = ctx.attr.word_size + srec_cat_vmem_args = [ + out_bin.path, + "-binary", + "-byte-swap", + str(word_size // 8), + "-fill", + "0xff", + "-within", + out_bin.path, + "-binary", + "-range-pad", + str(word_size // 8), + "-o", + out_vmem.path, + "-vmem", + str(word_size), + ] + ctx.actions.run( + outputs = [out_vmem], + inputs = [out_bin], + executable = "srec_cat", + arguments = srec_cat_vmem_args, + mnemonic = "SrecCat", + ) + return [ DefaultInfo( - files = depset([linking_outputs.executable]), + files = depset([linking_outputs.executable, out_bin, out_vmem]), ), OutputGroupInfo( - all_files = depset([linking_outputs.executable]), + all_files = depset([linking_outputs.executable, out_bin, out_vmem]), elf_file = depset([linking_outputs.executable]), + bin_file = depset([out_bin]), + vmem_file = depset([out_vmem]), ), ] @@ -134,6 +188,7 @@ "linker_script": attr.label(allow_single_file = True), "linker_script_includes": attr.label_list(default = [], allow_files = True), "semihosting": attr.bool(), + "word_size": attr.int(default = 32), "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), }, fragments = ["cpp"], @@ -145,6 +200,8 @@ srcs, tags = [], semihosting = False, + linker_script = "@kelvin_hw//toolchain:kelvin_tcm.ld", + word_size = 32, **kwargs): """A helper macro for generating binary artifacts for the Kelvin V2 core. @@ -156,6 +213,7 @@ srcs: The c source files. tags: build tags. semihosting: Enable htif-style semihosting + linker_script: Linker script to construct the final binary. **kwargs: Additional arguments forward to cc_binary. Emits rules: filegroup named: <name>.bin @@ -171,10 +229,11 @@ _kelvin_v2_binary( name = name, srcs = srcs, - linker_script = "@kelvin_hw//toolchain:kelvin_tcm.ld", + linker_script = linker_script, semihosting = semihosting, tags = tags, deps = deps, + word_size = word_size, **kwargs ) @@ -183,4 +242,18 @@ srcs = [name], output_group = "elf_file", tags = tags, + ) + + native.filegroup( + name = "{}.vmem".format(name), + srcs = [name], + output_group = "vmem_file", + tags = tags, + ) + + native.filegroup( + name = "{}.bin".format(name), + srcs = [name], + output_group = "bin_file", + tags = tags, ) \ No newline at end of file
diff --git a/rules/repos.bzl b/rules/repos.bzl index 64cb1c0..4b18ee6 100644 --- a/rules/repos.bzl +++ b/rules/repos.bzl
@@ -160,3 +160,15 @@ ], patch_args = ["-p1"], ) + +def fpga_repos(): + http_archive( + name = "lowrisc_opentitan_gh", + urls = ["https://github.com/lowRISC/opentitan/archive/1b1945fd76799666156f817e163222725c518c59.zip"], + sha256 = "b881378cdffee2284a88c2032c9fb13e68c889f1cac38cf715b0cff7b40fcf7e", + strip_prefix = "opentitan-1b1945fd76799666156f817e163222725c518c59", + patches = [ + "@kelvin_hw//fpga:0001-Export-hw-ip_templates.patch", + ], + patch_args = ["-p1"], + ) \ No newline at end of file
diff --git a/rules/utils.bzl b/rules/utils.bzl index a877032..be8ec88 100644 --- a/rules/utils.bzl +++ b/rules/utils.bzl
@@ -44,4 +44,34 @@ rule( name = rule_name, **rule_kwargs - ) \ No newline at end of file + ) + +def cc_embed_data( + name, + srcs, + var_name = "data", + testonly = False, + **kwargs): + """A rule to merge binary files into a C include file. + Args: + name: The name of the target. + srcs: The input binary source files. + var_name: The variable name of the array in output C include file. + testonly: The target is built for test only. + **kwargs: Extra arguments forwards to genrule. + """ + xxd_cmd = """ + xxd -i $< > $@; + sed -i -e 's#\\w*_len#{}_len#g' $@; + sed -i -e "s#\\w*\\[\\]#{}\\[\\]#g" $@; + sed -i -e 's/unsigned/const unsigned/g' $@ + """.format(var_name, var_name) + outs = ["{}.{}".format(name, "h")] + native.genrule( + name = name, + srcs = srcs, + outs = outs, + cmd = xxd_cmd, + testonly = testonly, + **kwargs + )
diff --git a/third_party/python/BUILD b/third_party/python/BUILD index 0a2669d..a4c83a0 100644 --- a/third_party/python/BUILD +++ b/third_party/python/BUILD
@@ -11,3 +11,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +package(default_visibility = ["//visibility:public"])
diff --git a/third_party/python/requirements.bzl b/third_party/python/requirements.bzl index 2fedda3..b5fed94 100644 --- a/third_party/python/requirements.bzl +++ b/third_party/python/requirements.bzl
@@ -364,3 +364,40 @@ ], ), ) + + # FPGA + http_archive( + name = "kelvin_pip_deps_mako", + urls = [ + "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", + ], + sha256 = "baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", + type = "zip", + build_file_content = _build_file_content(pypi_name = "mako", pypi_version = "1.3.10"), + ) + + http_archive( + name = "kelvin_pip_deps_hjson", + urls = [ + "https://files.pythonhosted.org/packages/1f/7f/13cd798d180af4bf4c0ceddeefba2b864a63c71645abc0308b768d67bb81/hjson-3.1.0-py3-none-any.whl", + ], + sha256 = "65713cdcf13214fb554eb8b4ef803419733f4f5e551047c9b711098ab7186b89", + type = "zip", + build_file_content = _build_file_content(pypi_name = "hjson", pypi_version = "3.1.0"), + ) + + http_archive( + name = "kelvin_pip_deps_fusesoc", + urls = [ + "https://files.pythonhosted.org/packages/cb/a8/10f62458dda2ca07c49477448e643b10f30825b7741fdb6ec3e6188b6999/fusesoc-2.4.3-py3-none-any.whl", + ], + sha256 = "9ab4a82a5b7d4decbeb8f76049673a1b0806732ab8f807fee285bbc0452b3dc3", + type = "zip", + build_file_content = _build_file_content( + pypi_name = "fusesoc", + pypi_version = "2.4.3", + deps = [ + "@kelvin_pip_deps_hjson//:pkg", + ], + ), + )
diff --git a/toolchain/cc_toolchain_config.bzl b/toolchain/cc_toolchain_config.bzl index 44a5d1b..b86d290 100644 --- a/toolchain/cc_toolchain_config.bzl +++ b/toolchain/cc_toolchain_config.bzl
@@ -76,6 +76,10 @@ path = "/bin/false", ), tool_path( + name = "objcopy", + path = "wrappers/objcopy", + ), + tool_path( name = "strip", path = "/bin/false", ),
diff --git a/toolchain/wrappers/objcpy b/toolchain/wrappers/objcpy deleted file mode 120000 index da2bdd9..0000000 --- a/toolchain/wrappers/objcpy +++ /dev/null
@@ -1 +0,0 @@ -driver.sh \ No newline at end of file