TFMicro integration into KelvinV2 ecosystem. Successful integration necessitated modifications across the repository. Revisions to the build system encompass: * Workspace has been reconfigured to facilitate the download of the tflite_micro repository and its associated dependencies. * rules/repos.bzl file now incorporates new repositories for download. * rules/utils.bzl file has been updated to include the generate_cc_arrays tool. The tflite_micro patch incorporates: * Patches designed to disable -pthreads within ruy and gemmlowp. * Adjustments to the visibility of the generate_cc_array and hello_world models. Regarding the toolchain, the following changes have been implemented: * Removal of freestanding attributes. * Addition of no-exceptions and no-rtti flags. * Introduction of a new tcm.ld file to facilitate high-memory kelvin_binaries. Validation was conducted using tests/cocotb/tutorial/tflite_micro_test.cc. Toolchain Validation bazel test tests/cocotb/... Change-Id: I3cc05b9ad6a23d4c20c1b9c074b1b8a6b18dae5d
diff --git a/.bazelrc b/.bazelrc index a78752b..2f0134a 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -59,6 +59,14 @@ run:synthesis --build_tag_filters="synthesis" run:synthesis --test_tag_filters="synthesis" +# Set preprocessor defines for tflite-micro. +build --copt=-DTF_LITE_USE_GLOBAL_CMATH_FUNCTIONS +build --copt=-DTF_LITE_USE_GLOBAL_MIN +build --copt=-DTF_LITE_USE_GLOBAL_MAX +build --copt=-DTF_LITE_MCU_DEBUG_LOG +build:opt --copt=-DTF_LITE_STRIP_ERROR_STRINGS + + # Selecting kelvin platform with custom toolchain. build:kelvin_v2 --platforms=//platforms:kelvin_v2
diff --git a/WORKSPACE b/WORKSPACE index eb26098..8ff5140 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -14,7 +14,15 @@ workspace(name = "kelvin_hw") -load("//rules:repos.bzl", "kelvin_repos", "renode_repos", "cvfpu_repos", "rvvi_repos", "fpga_repos") +load( + "//rules:repos.bzl", + "cvfpu_repos", + "fpga_repos", + "kelvin_repos", + "renode_repos", + "rvvi_repos", + "tflite_repos", +) kelvin_repos() @@ -95,26 +103,21 @@ 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", + name = "ot_python_deps", + python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python", + requirements_lock = "@lowrisc_opentitan_gh//:python-requirements.txt", ) load("//third_party/python:requirements.bzl", "install_deps") + install_deps() # 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( @@ -125,9 +128,15 @@ tags = ["pypi_name=importlib_metadata","pypi_version=8.7.0"], ) """, + sha256 = "e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", + type = "zip", + urls = [ + "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", + ], ) load("@ot_python_deps//:requirements.bzl", ot_install_deps = "install_deps") + ot_install_deps() http_archive( @@ -142,13 +151,29 @@ ) """, sha256 = "c9c85f8361e9d02d64474c51e3b3730ba09807cf4610d6d002c49a270458b49c", + strip_prefix = "toolchain_kelvin_v2", urls = [ "https://storage.googleapis.com/shodan-public-artifacts/toolchain_kelvin_tar_files/toolchain_kelvin_v2-2025-09-11.tar.gz", ], - strip_prefix = "toolchain_kelvin_v2", ) register_toolchains( "//toolchain:cc_kelvin_v2_toolchain", "//toolchain:cc_kelvin_v2_semihosting_toolchain", ) + +tflite_repos() + +load("@tflite_micro//tensorflow:workspace.bzl", tf_micro_workspace = "workspace") + +tf_micro_workspace() + +pip_parse( + name = "tflm_pip_deps", + python_interpreter_target = "@python39_x86_64-unknown-linux-gnu//:python", + requirements_lock = "@tflite_micro//third_party:python_requirements.txt", +) + +load("@tflm_pip_deps//:requirements.bzl", "install_deps") + +install_deps()
diff --git a/rules/kelvin_v2.bzl b/rules/kelvin_v2.bzl index 22423da..a8dd49d 100644 --- a/rules/kelvin_v2.bzl +++ b/rules/kelvin_v2.bzl
@@ -256,4 +256,4 @@ 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 803b891..ef28c55 100644 --- a/rules/repos.bzl +++ b/rules/repos.bzl
@@ -17,6 +17,7 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") def kelvin_repos(): http_archive( @@ -190,3 +191,39 @@ ], patch_args = ["-p1"], ) + +def tflite_repos(): + http_archive( + name = "tflite_micro", + url = "https://github.com/tensorflow/tflite-micro/archive/b75c6ff4e2270047f2b48fa01f833c8101c31f43.zip", + sha256 = "ac3e675b71c55529a32d19a8cf0912413c1d1b9a551512e2665883a1666fb0ba", + strip_prefix = "tflite-micro-b75c6ff4e2270047f2b48fa01f833c8101c31f43", + patches = [ + "@kelvin_hw//third_party/tflite-micro:Tflite-Micro-Kelvin-integration.patch", + "@kelvin_hw//third_party/tflite-micro:0001-Remove-xtensa-and-hifi-kernels.patch", + ], + patch_args = ["-p1"], + ) + + http_archive( + name = "hedron_compile_commands", + sha256 = "bacabfe758676fdc19e4bea7c4a3ac99c7e7378d259a9f1054d341c6a6b44ff6", + strip_prefix = "bazel-compile-commands-extractor-1266d6a25314d165ca78d0061d3399e909b7920e", + url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/1266d6a25314d165ca78d0061d3399e909b7920e.tar.gz", + ) + + maybe( + http_archive, + name = "rules_python", + sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b", + strip_prefix = "rules_python-0.26.0", + url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.26.0.tar.gz", + ) + + maybe( + http_archive, + name = "pybind11_bazel", + strip_prefix = "pybind11_bazel-faf56fb3df11287f26dbc66fdedf60a2fc2c6631", + urls = ["https://github.com/pybind/pybind11_bazel/archive/faf56fb3df11287f26dbc66fdedf60a2fc2c6631.zip"], + sha256 = "a185aa68c93b9f62c80fcb3aadc3c83c763854750dc3f38be1dadcb7be223837", + )
diff --git a/rules/utils.bzl b/rules/utils.bzl index be8ec88..9a13b86 100644 --- a/rules/utils.bzl +++ b/rules/utils.bzl
@@ -13,39 +13,39 @@ # limitations under the License. def template_rule(rule, name_map, **kwargs): - """ Macro for creating multiple instances of a rule template. + """ Macro for creating multiple instances of a rule template. - Usage: - template_rule( - example_rule, - { - "foo": { - "varying_param1": 42, - "varying_param2": [ "//some/source:file" ], - }, - "bar": { - "varying_param1": 9001, - "varying_param2": [ "//different/source:file" ], - }, - }, - common_param1: "same_for_both_rules" - common_param2: [ "//also:same", "//for/both:rules" ] + Usage: + template_rule( + example_rule, + { + "foo": { + "varying_param1": 42, + "varying_param2": [ "//some/source:file" ], + }, + "bar": { + "varying_param1": 9001, + "varying_param2": [ "//different/source:file" ], + }, + }, + common_param1: "same_for_both_rules" + common_param2: [ "//also:same", "//for/both:rules" ] + ) + + Args: + rule: The base rule for the template + name_map: A map of rule name -> (map of parameter name -> argument) + **kwargs: Arguments that remain the same for each instance of the rule. + """ + for rule_name, argmap in name_map.items(): + rule_kwargs = argmap + for k, v in kwargs.items(): + rule_kwargs.update([(k, v)]) + rule( + name = rule_name, + **rule_kwargs ) - Args: - rule: The base rule for the template - name_map: A map of rule name -> (map of parameter name -> argument) - **kwargs: Arguments that remain the same for each instance of the rule. - """ - for rule_name, argmap in name_map.items(): - rule_kwargs = argmap - for k, v in kwargs.items(): - rule_kwargs.update([(k, v)]) - rule( - name = rule_name, - **rule_kwargs - ) - def cc_embed_data( name, srcs, @@ -75,3 +75,20 @@ testonly = testonly, **kwargs ) + +# From @tflite_micro//tensorflow/lite/micro/build_def.bzl, and paths. +# Modified to point to the external repo as visibility of the package is restricted +# TODO upstream changes to tflite-micro to fix this. +def generate_cc_arrays(name, src, out, tags = []): + native.genrule( + name = name, + srcs = [ + src, + ], + outs = [ + out, + ], + tags = tags, + cmd = "$(location @tflite_micro//tensorflow/lite/micro/tools:generate_cc_arrays) $@ $<", + tools = ["@tflite_micro//tensorflow/lite/micro/tools:generate_cc_arrays"], + )
diff --git a/tests/cocotb/tutorial/BUILD b/tests/cocotb/tutorial/BUILD index ed9660d..7e79acf 100644 --- a/tests/cocotb/tutorial/BUILD +++ b/tests/cocotb/tutorial/BUILD
@@ -14,6 +14,7 @@ load("//rules:coco_tb.bzl", "cocotb_test_suite") load("//rules:kelvin_v2.bzl", "kelvin_v2_binary") +load("//rules:utils.bzl", "generate_cc_arrays") load( "//tests/cocotb:build_defs.bzl", "VCS_BUILD_ARGS", @@ -52,12 +53,12 @@ ], "data": glob(["**/*.elf"]), }, + vcs_build_args = VCS_BUILD_ARGS, vcs_data = glob(["**/*.elf"]) + [ "//tests/cocotb:coverage_exclude.cfg", ], - vcs_build_args = VCS_BUILD_ARGS, - vcs_test_args = VCS_TEST_ARGS, vcs_defines = VCS_DEFINES, + vcs_test_args = VCS_TEST_ARGS, vcs_verilog_sources = ["//hdl/chisel/src/kelvin:core_mini_axi_cc_library_verilog"], verilator_model = "//tests/cocotb:core_mini_axi_model", ) @@ -81,13 +82,13 @@ ], "data": ["//examples:kelvin_v2_hello_world_add_floats.elf"], }, + vcs_build_args = VCS_BUILD_ARGS, vcs_data = [ "//examples:kelvin_v2_hello_world_add_floats.elf", "//tests/cocotb:coverage_exclude.cfg", ], - vcs_build_args = VCS_BUILD_ARGS, - vcs_test_args = VCS_TEST_ARGS, vcs_defines = VCS_DEFINES, + vcs_test_args = VCS_TEST_ARGS, vcs_verilog_sources = ["//hdl/chisel/src/kelvin:core_mini_axi_cc_library_verilog"], verilator_model = "//tests/cocotb:core_mini_axi_model", ) @@ -96,3 +97,32 @@ name = "kelvin_v2_program", srcs = ["program.cc"], ) + +kelvin_v2_binary( + name = "tflite_micro_test", + srcs = [ + "hello_world_tflite_cc", + "tflite_micro_test.cc", + ], + hdrs = ["hello_world_tflite.h"], + linker_script = "@kelvin_hw//toolchain:kelvin_tcm_highmem.ld", + deps = [ + "@tflite_micro//tensorflow/lite/micro:micro_framework", + "@tflite_micro//tensorflow/lite/micro:micro_log", + "@tflite_micro//tensorflow/lite/micro:micro_profiler", + "@tflite_micro//tensorflow/lite/micro:op_resolvers", + "@tflite_micro//tensorflow/lite/micro:system_setup", + ], +) + +generate_cc_arrays( + name = "hello_world_tflite_cc", + src = "@tflite_micro//tensorflow/lite/micro/examples/hello_world/models:hello_world_int8.tflite", + out = "hello_world_tflite.cc", +) + +generate_cc_arrays( + name = "hello_world_tflite_h", + src = "@tflite_micro//tensorflow/lite/micro/examples/hello_world/models:hello_world_int8.tflite", + out = "hello_world_tflite.h", +)
diff --git a/tests/cocotb/tutorial/tflite_micro_test.cc b/tests/cocotb/tutorial/tflite_micro_test.cc new file mode 100644 index 0000000..79c5886 --- /dev/null +++ b/tests/cocotb/tutorial/tflite_micro_test.cc
@@ -0,0 +1,53 @@ +// 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 +// +// https://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. + +#include <math.h> +#include <stdint.h> +#include <stdio.h> + +#include "tensorflow/lite/core/c/common.h" +#include "tensorflow/lite/micro/micro_interpreter.h" +#include "tensorflow/lite/micro/micro_mutable_op_resolver.h" +#include "tensorflow/lite/micro/system_setup.h" +#include "tests/cocotb/tutorial/hello_world_tflite.h" + +namespace { +using HelloWorldOpResolver = tflite::MicroMutableOpResolver<1>; + +TfLiteStatus RegisterOps(HelloWorldOpResolver& op_resolver) { + TF_LITE_ENSURE_STATUS(op_resolver.AddFullyConnected()); + return kTfLiteOk; +} +} // namespace + +int main(int argc, char** argv) { + const tflite::Model* model = tflite::GetModel(g_hello_world_int8_model_data); + HelloWorldOpResolver op_resolver; + + constexpr size_t kTensorArenaSize = 3000; + uint8_t tensor_arena[kTensorArenaSize]; + + tflite::MicroInterpreter interpreter(model, op_resolver, tensor_arena, + kTensorArenaSize); + + if (interpreter.AllocateTensors() != kTfLiteOk) { + return -1; + } + TfLiteTensor* input = interpreter.input(0); + memset(tflite::GetTensorData<uint8_t>(input), 0, input->bytes); + if (interpreter.Invoke() != kTfLiteOk) { + return -2; + } + return 0; +}
diff --git a/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch b/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch new file mode 100644 index 0000000..f4d6f58 --- /dev/null +++ b/third_party/tflite-micro/0001-Remove-xtensa-and-hifi-kernels.patch
@@ -0,0 +1,141 @@ +From 9ceb5fda8112ab23d3410f6bfe3adbc364f26ff8 Mon Sep 17 00:00:00 2001 +From: Naveen Dodda <ndodda@google.com> +Date: Wed, 24 Sep 2025 19:51:04 +0000 +Subject: [PATCH] Remove xtensa and hifi kernels + +--- + tensorflow/lite/micro/kernels/BUILD | 88 +---------------------------- + 1 file changed, 1 insertion(+), 87 deletions(-) + +diff --git a/tensorflow/lite/micro/kernels/BUILD b/tensorflow/lite/micro/kernels/BUILD +index 1bb25088..9671c204 100644 +--- a/tensorflow/lite/micro/kernels/BUILD ++++ b/tensorflow/lite/micro/kernels/BUILD +@@ -9,11 +9,6 @@ load( + load( + "//tensorflow:extra_rules.bzl", + "tflm_kernel_friends", +- "xtensa_fusion_f1_config", +- "xtensa_hifi_3_config", +- "xtensa_hifi_3z_config", +- "xtensa_hifi_5_config", +- "xtensa_vision_p6_config", + ) + + package( +@@ -191,26 +186,6 @@ tflm_cc_library( + ], + ) + +-HIFI3_COPTS = [ +- "-DXTENSA=1", +- "-DHIFI3=1", +-] +- +-HIFI4_COPTS = [ +- "-DXTENSA=1", +- "-DHIFI4=1", +-] +- +-HIFI5_COPTS = [ +- "-DXTENSA=1", +- "-DHIFI5=1", +-] +- +-VP6_COPTS = [ +- "-DXTENSA=1", +- "-DVISION_P6=1", +-] +- + tflm_kernel_cc_library( + name = "micro_ops", + srcs = [ +@@ -354,26 +329,10 @@ tflm_kernel_cc_library( + "transpose_conv.h", + "unidirectional_sequence_lstm.h", + ] + select({ +- xtensa_fusion_f1_config(): glob(["xtensa/**/*.h"]), +- xtensa_hifi_3_config(): glob(["xtensa/**/*.h"]), +- xtensa_hifi_3z_config(): glob(["xtensa/**/*.h"]), +- xtensa_hifi_5_config(): glob(["xtensa/**/*.h"]), +- xtensa_vision_p6_config(): glob(["xtensa/**/*.h"]), + "//conditions:default": [], + }), +- accelerated_srcs = { +- xtensa_fusion_f1_config(): glob(["xtensa/**/*.cc"]), +- xtensa_hifi_3_config(): glob(["xtensa/**/*.cc"]), +- xtensa_hifi_3z_config(): glob(["xtensa/**/*.cc"]), +- xtensa_hifi_5_config(): glob(["xtensa/**/*.cc"]), +- xtensa_vision_p6_config(): glob(["xtensa/**/*.cc"]), +- }, ++ accelerated_srcs = {}, + copts = tflm_copts() + select({ +- xtensa_fusion_f1_config(): HIFI4_COPTS, +- xtensa_hifi_3_config(): HIFI3_COPTS, +- xtensa_hifi_3z_config(): HIFI4_COPTS, +- xtensa_hifi_5_config(): HIFI5_COPTS, +- xtensa_vision_p6_config(): VP6_COPTS, + "//conditions:default": [], + }), + visibility = [ +@@ -405,11 +364,6 @@ tflm_kernel_cc_library( + "//tensorflow/lite/schema:schema_fbs", + "@flatbuffers//:runtime_cc", + ] + select({ +- xtensa_fusion_f1_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"], +- xtensa_hifi_3_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"], +- xtensa_hifi_3z_config(): ["//third_party/xtensa/nnlib_hifi4:nnlib_hifi4_lib"], +- xtensa_hifi_5_config(): ["//third_party/xtensa/nnlib_hifi5:nnlib_hifi5_lib"], +- xtensa_vision_p6_config(): ["//third_party/xtensa/xi_tflmlib_vision_p6:xi_tflmlib_vision_p6_lib"], + "//conditions:default": [], + }), + ) +@@ -1538,45 +1492,5 @@ string_flag( + build_setting_default = "", + values = [ + "", +- "xtensa_fusion_f1", +- "xtensa_hifi_3", +- "xtensa_hifi_3z", +- "xtensa_hifi_5", +- "xtensa_vision_p6", + ], + ) +- +-config_setting( +- name = "xtensa_fusion_f1_default", +- flag_values = { +- ":optimized_kernels": "xtensa_fusion_f1", +- }, +-) +- +-config_setting( +- name = "xtensa_hifi_3_default", +- flag_values = { +- ":optimized_kernels": "xtensa_hifi_3", +- }, +-) +- +-config_setting( +- name = "xtensa_hifi_3z_default", +- flag_values = { +- ":optimized_kernels": "xtensa_hifi_3z", +- }, +-) +- +-config_setting( +- name = "xtensa_hifi_5_default", +- flag_values = { +- ":optimized_kernels": "xtensa_hifi_5", +- }, +-) +- +-config_setting( +- name = "xtensa_vision_p6_default", +- flag_values = { +- ":optimized_kernels": "xtensa_vision_p6", +- }, +-) +-- +2.51.0.536.g15c5d4f767-goog +
diff --git a/third_party/tflite-micro/BUILD.bazel b/third_party/tflite-micro/BUILD.bazel new file mode 100644 index 0000000..9ba09c9 --- /dev/null +++ b/third_party/tflite-micro/BUILD.bazel
@@ -0,0 +1,24 @@ +# 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. + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "all_srcs", + srcs = glob(["*.patch"]), +) + +exports_files( + srcs = glob(["*.patch"]), +)
diff --git a/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch b/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch new file mode 100644 index 0000000..df82766 --- /dev/null +++ b/third_party/tflite-micro/Tflite-Micro-Kelvin-integration.patch
@@ -0,0 +1,158 @@ +From 8bc9af42f6f20e6a2a3e83d512e918c6f85239c8 Mon Sep 17 00:00:00 2001 +From: Naveen Dodda <ndodda@google.com> +Date: Fri, 12 Sep 2025 23:04:51 +0000 +Subject: [PATCH] TFmicro Kelvin integration + +--- + .../micro/examples/hello_world/models/BUILD | 5 +--- + tensorflow/lite/micro/tools/BUILD | 2 +- + tensorflow/workspace.bzl | 1 + + third_party/gemmlowp/BUILD | 6 +++++ + .../gemmlowp/remove-pthreads-as-default.patch | 25 +++++++++++++++++++ + third_party/ruy/BUILD | 2 ++ + .../ruy/remove-pthreads-as-default.patch | 23 +++++++++++++++++ + third_party/ruy/workspace.bzl | 2 ++ + 8 files changed, 61 insertions(+), 5 deletions(-) + create mode 100644 third_party/gemmlowp/BUILD + create mode 100644 third_party/gemmlowp/remove-pthreads-as-default.patch + create mode 100644 third_party/ruy/remove-pthreads-as-default.patch + +diff --git a/tensorflow/lite/micro/examples/hello_world/models/BUILD b/tensorflow/lite/micro/examples/hello_world/models/BUILD +index 4c9441b8..457cf190 100644 +--- a/tensorflow/lite/micro/examples/hello_world/models/BUILD ++++ b/tensorflow/lite/micro/examples/hello_world/models/BUILD +@@ -9,10 +9,7 @@ exports_files( + "hello_world_float.tflite", + "hello_world_int8.tflite", + ], +- visibility = [ +- "//codegen/examples/hello_world:__subpackages__", +- "//tensorflow/lite/micro/examples/hello_world:__subpackages__", +- ], ++ visibility = ["//visibility:public"] , + ) + + generate_cc_arrays( +diff --git a/tensorflow/lite/micro/tools/BUILD b/tensorflow/lite/micro/tools/BUILD +index c3b2f981..8e10f866 100644 +--- a/tensorflow/lite/micro/tools/BUILD ++++ b/tensorflow/lite/micro/tools/BUILD +@@ -5,7 +5,7 @@ load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") + load("//tensorflow:extra_rules.bzl", "tflm_application_friends") + + package( +- default_visibility = ["//:__subpackages__"], ++ default_visibility = ["//visibility:public"], + licenses = ["notice"], + ) + +diff --git a/tensorflow/workspace.bzl b/tensorflow/workspace.bzl +index b799523b..4aed7b03 100644 +--- a/tensorflow/workspace.bzl ++++ b/tensorflow/workspace.bzl +@@ -35,6 +35,7 @@ def tf_repositories(path_prefix = "", tf_repo_name = ""): + "https://storage.googleapis.com/mirror.tensorflow.org/github.com/google/gemmlowp/archive/fda83bdc38b118cc6b56753bd540caa49e570745.zip", + "https://github.com/google/gemmlowp/archive/fda83bdc38b118cc6b56753bd540caa49e570745.zip", + ], ++ patch_file = "@tflite_micro//third_party/gemmlowp:remove-pthreads-as-default.patch", + ) + + tf_http_archive( +diff --git a/third_party/gemmlowp/BUILD b/third_party/gemmlowp/BUILD +new file mode 100644 +index 00000000..b4ea97ae +--- /dev/null ++++ b/third_party/gemmlowp/BUILD +@@ -0,0 +1,6 @@ ++ackage( ++ default_visibility = ["//visibility:public"], ++ licenses = ["notice"], ++) ++ ++exports_files(glob(["*.patch"])) +\ No newline at end of file +diff --git a/third_party/gemmlowp/remove-pthreads-as-default.patch b/third_party/gemmlowp/remove-pthreads-as-default.patch +new file mode 100644 +index 00000000..e32ac209 +--- /dev/null ++++ b/third_party/gemmlowp/remove-pthreads-as-default.patch +@@ -0,0 +1,25 @@ ++From 6f094c09fe6ae26306f1b376ceeed02f3af52d01 Mon Sep 17 00:00:00 2001 ++From: Naveen Dodda <ndodda@google.com> ++Date: Mon, 8 Sep 2025 21:30:52 +0000 ++Subject: [PATCH] Changes to turn off default threads option ++ ++--- ++ flags.bzl | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++diff --git a/flags.bzl b/flags.bzl ++index e35fe9e..e26a448 100644 ++--- a/flags.bzl +++++ b/flags.bzl ++@@ -4,7 +4,7 @@ LIB_COPTS = [] ++ LIB_LINKOPTS = select({ ++ ":android": [], ++ ":windows": [], ++- "//conditions:default": ["-lpthread"], +++ "//conditions:default": [], ++ }) ++ ++ BIN_LINKOPTS = LIB_LINKOPTS ++-- ++2.51.0.384.g4c02a37b29-goog ++ +diff --git a/third_party/ruy/BUILD b/third_party/ruy/BUILD +index 518fea8f..f4ab327d 100644 +--- a/third_party/ruy/BUILD ++++ b/third_party/ruy/BUILD +@@ -4,3 +4,5 @@ package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], + ) ++ ++exports_files(glob(["*.patch"]) + ["LICENSE"]) +\ No newline at end of file +diff --git a/third_party/ruy/remove-pthreads-as-default.patch b/third_party/ruy/remove-pthreads-as-default.patch +new file mode 100644 +index 00000000..5c834007 +--- /dev/null ++++ b/third_party/ruy/remove-pthreads-as-default.patch +@@ -0,0 +1,23 @@ ++From 621a1914d61159f2b4461aaf87a5a0e35156180f Mon Sep 17 00:00:00 2001 ++From: Naveen Dodda <ndodda@google.com> ++Date: Fri, 12 Sep 2025 22:13:17 +0000 ++Subject: [PATCH] remove pthreads as default ++ ++--- ++ ruy/build_defs.oss.bzl | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++diff --git a/ruy/build_defs.oss.bzl b/ruy/build_defs.oss.bzl ++index e405b41..83097b7 100644 ++--- a/ruy/build_defs.oss.bzl +++++ b/ruy/build_defs.oss.bzl ++@@ -11,5 +11,5 @@ def ruy_linkopts_thread_standard_library(): ++ # https://github.com/abseil/abseil-cpp/blob/1112609635037a32435de7aa70a9188dcb591458/absl/base/BUILD.bazel#L155 ++ return select({ ++ "@bazel_tools//src/conditions:windows": [], ++- "//conditions:default": ["-pthread"], +++ "//conditions:default": [""], ++ }) ++-- ++2.51.0.384.g4c02a37b29-goog ++ +diff --git a/third_party/ruy/workspace.bzl b/third_party/ruy/workspace.bzl +index 50769621..b5274df9 100644 +--- a/third_party/ruy/workspace.bzl ++++ b/third_party/ruy/workspace.bzl +@@ -12,4 +12,6 @@ def repo(): + "https://github.com/google/ruy/archive/54774a7a2cf85963777289193629d4bd42de4a59.zip", + ], + build_file = "//third_party/ruy:BUILD", ++ patch_file = "@tflite_micro//third_party/ruy:remove-pthreads-as-default.patch", ++ + ) +-- +2.51.0.534.gc79095c0ca-goog +
diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel index bc00348..c6d1cc6 100644 --- a/toolchain/BUILD.bazel +++ b/toolchain/BUILD.bazel
@@ -21,6 +21,7 @@ srcs = [ "//toolchain/wrappers:all", "//toolchain:kelvin_tcm.ld", + "//toolchain:kelvin_tcm_highmem.ld", "@toolchain_kelvin_v2//:all_files", ], )
diff --git a/toolchain/build_scripts/README.md b/toolchain/build_scripts/README.md index eae25c2..d12b09f 100644 --- a/toolchain/build_scripts/README.md +++ b/toolchain/build_scripts/README.md
@@ -12,4 +12,4 @@ $ docker run -v `pwd`:/toolchain/build_scripts -w /toolchain/build_scripts toolchain_test bash kelvin_v2_toolchain_build.sh ``` -The toolchain artifacts will be located at rv32_out +Output toolchain artifacts will be exported to rv32_out \ No newline at end of file
diff --git a/toolchain/cc_toolchain_config.bzl b/toolchain/cc_toolchain_config.bzl index b55194b..5e3c7c7 100644 --- a/toolchain/cc_toolchain_config.bzl +++ b/toolchain/cc_toolchain_config.bzl
@@ -28,19 +28,24 @@ ACTION_NAMES.cpp_link_nodeps_dynamic_library, ] -all_compile_actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, +cpp_compile_actions = [ ACTION_NAMES.cpp_compile, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, +] + +other_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, ACTION_NAMES.lto_backend, ACTION_NAMES.clif_match, ] +all_compile_actions = cpp_compile_actions + other_compile_actions + def _impl(ctx): tool_paths = [ tool_path( @@ -150,8 +155,8 @@ ], ) - optimization_compile_flag_set = flag_set( - actions = all_compile_actions, + optimization_cpp_compile_flag_set = flag_set( + actions = cpp_compile_actions, flag_groups = [ flag_group( flags = [ @@ -159,7 +164,22 @@ "-Os", "-ffunction-sections", "-fdata-sections", - "-ffreestanding", + "-fno-exceptions", + "-fno-rtti", + ], + ), + ], + ) + + optimization_other_compile_flag_set = flag_set( + actions = other_compile_actions, + flag_groups = [ + flag_group( + flags = [ + "-g3", + "-Os", + "-ffunction-sections", + "-fdata-sections", ], ), ], @@ -256,7 +276,8 @@ name = "fastbuild", enabled = False, flag_sets = [ - optimization_compile_flag_set, + optimization_cpp_compile_flag_set, + optimization_other_compile_flag_set, optimization_link_flag_set, ], provides = ["compilation_mode"], @@ -266,7 +287,8 @@ name = "opt", enabled = False, flag_sets = [ - optimization_compile_flag_set, + optimization_cpp_compile_flag_set, + optimization_other_compile_flag_set, optimization_link_flag_set, ], provides = ["compilation_mode"],
diff --git a/toolchain/kelvin_tcm_highmem.ld b/toolchain/kelvin_tcm_highmem.ld new file mode 100644 index 0000000..117bb17 --- /dev/null +++ b/toolchain/kelvin_tcm_highmem.ld
@@ -0,0 +1,120 @@ +/* Copyright 2025 Google LLC. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +MEMORY { + ITCM(rx): ORIGIN = 0x00000000, LENGTH = 1024K + DTCM(rw): ORIGIN = 0x00100000, LENGTH = 1024K +} + +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x80; +__stack_size = STACK_SIZE; +__stack_shift = 7; +__boot_hart = 0; +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x80; + +ENTRY(_start) + +SECTIONS { + /* ITCM data here */ + . = ORIGIN(ITCM); + .text : ALIGN(16) { + *(._init) + *(.text) + *(.text.*) + . = ALIGN(16); + } > ITCM + + .init.array : ALIGN(16) { + __init_array_start = .; + __init_array_start__ = .; + *(.init_array) + *(.init_array.*) + . = ALIGN(16); + __init_array_end = .; + __init_array_end__ = .; + } > ITCM + + .rodata : ALIGN(16) { + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(16); + } > ITCM + + /* Static Thread Local Storage template */ + .tdata : { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.*) + *(.gnu.linkonce.td.*) + PROVIDE_HIDDEN (__tdata_end = .); + } > DTCM + PROVIDE (__tdata_size = SIZEOF (.tdata)); + + .tbss (NOLOAD) : { + PROVIDE_HIDDEN (__tbss_start = .); + PROVIDE_HIDDEN (__tbss_offset = ABSOLUTE (__tbss_start - __tdata_start)); + *(.tbss .tbss.*) + *(.gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE_HIDDEN (__tbss_end = .); + } > DTCM + PROVIDE (__tbss_size = SIZEOF (.tbss)); + + .data : ALIGN(16) { + __data_start__ = .; + /** + * This will get loaded into `gp`, and the linker will use that register for + * accessing data within [-2048,2047] of `__global_pointer$`. + * + * This is much cheaper (for small data) than materializing the + * address and loading from that (which will take one extra instruction). + */ + _global_pointer = . + 0x800; + __global_pointer$ = . + 0x800; + *(.sdata) + *(.sdata.*) + *(.data) + *(.data.*) + /** + * Memory location for the return value from main, + * which could be inspected by another core in the system. + **/ + . = ALIGN(4); + _ret = .; + . += 4; + . = ALIGN(16); + __data_end__ = .; + _edata = .; + } > DTCM + + /* DTCM data here */ + . = ORIGIN(DTCM); + .bss : ALIGN(16) { + __bss_start__ = .; + __bss_start = .; + *(.sbss) + *(.sbss.*) + *(.bss) + *(.bss.*) + __bss_end__ = .; + __bss_end = .; + _end = .; + } > DTCM + + .heap : ALIGN(16) { + __heap_start__ = .; + _heap_ptr = .; + . += HEAP_SIZE; + __heap_end__ = .; + __heap_end = .; + } > DTCM + + .stack : ALIGN(16) { + __stack_start__ = .; + __stack_start = .; + . += STACK_SIZE; + __stack_end__ = .; + } > DTCM +} \ No newline at end of file