Merge "Add ml top model test into dv regression"
diff --git a/.bazelrc b/.bazelrc
index 43d1234..a4341dc 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -28,6 +28,9 @@
 build:kelvin --platforms=//platforms/riscv32:kelvin
 build:sparrow --platforms=@matcha//platforms/riscv32:sparrow
 
+# Support airgapped build environment
+build:airgapped_env --//rules:build_env='airgapped'
+
 # Shared configuration for clang's source-based coverage instrumentation.
 # Bazel seems to support this only partially, thus we have to perform some
 # additional processing. See
diff --git a/BUILD.bazel b/BUILD.bazel
index 0f0a46b..b131709 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -11,13 +11,20 @@
         # Add a file from each directory and let fusesoc to pick the directory.
         "@lowrisc_opentitan//hw/dv:BUILD",
         "@lowrisc_opentitan//hw/ip:BUILD",
-        "@kelvin_hw//hdl/chisel:kelvin.core",
-        "//hw/top_matcha/ip/dma/chisel:fastvdma.core",
         "@lowrisc_opentitan//hw/lint:BUILD",
         "@lowrisc_opentitan//hw/vendor:BUILD",
         # Place the following file to make compilation works
         "//hw:check_tool_requirements.core",
         "@axi2sramcrs//:BUILD",
         "@isp_yocto//:BUILD",
-    ],
+    ] + select({
+        "//rules:airgapped_env": [
+            "@fastvdma_core//:fastvdma.core",
+            "@kelvin_core//:kelvin.core",
+        ],
+        "//conditions:default": [
+            "//hw/top_matcha/ip/dma/chisel:fastvdma.core",
+            "@kelvin_hw//hdl/chisel:kelvin.core",
+        ],
+    }),
 )
diff --git a/WORKSPACE b/WORKSPACE
index e805e27..84eff09 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -38,6 +38,35 @@
     path = "../../out/kelvin/sw/bazel_out",
 )
 
+# Used by airgapped environment
+new_local_repository(
+    name = "kelvin_core",
+    build_file_content = """
+exports_files(glob(["**"]))
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["*.*"]),
+    visibility = ["//visibility:public"],
+)
+    """,
+    path = "../../out/kelvin/hw/kelvin_core",
+)
+
+# Used by airgapped environment
+new_local_repository(
+    name = "fastvdma_core",
+    build_file_content = """
+exports_files(glob(["**"]))
+filegroup(
+    name = "all_files",
+    srcs = glob(["*.*"]),
+    visibility = ["//visibility:public"],
+)
+    """,
+    path = "../../out/matcha/hw/fastvdma_core",
+)
+
 # CRT is the Compiler Repository Toolkit.  It contains the configuration for
 # the windows compiler.
 load("@lowrisc_opentitan//third_party/crt:repos.bzl", "crt_repos")
diff --git a/hw/BUILD b/hw/BUILD
index e763510..ec4c0d3 100644
--- a/hw/BUILD
+++ b/hw/BUILD
@@ -3,8 +3,8 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-load("@lowrisc_opentitan//rules:fusesoc.bzl", "fusesoc_build")
 load("@bazel_skylib//rules:common_settings.bzl", "string_list_flag")
+load("@lowrisc_opentitan//rules:fusesoc.bzl", "fusesoc_build")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -82,8 +82,15 @@
     name = "all_files",
     srcs = glob(["**"]) + [
         "//hw/top_matcha:all_files",
-        "@kelvin_hw//hdl/chisel:matcha_kelvin_verilog",
-        "@kelvin_hw//hdl/chisel:kelvin.core",
         "@lowrisc_opentitan//hw/dv:all_files",
-    ],
+    ] + select({
+        "//rules:airgapped_env": [
+            "@fastvdma_core//:all_files",
+            "@kelvin_core//:all_files",
+        ],
+        "//conditions:default": [
+            "//hw/top_matcha/ip/dma/chisel:fastvdma_core",
+            "@kelvin_hw//hdl/chisel:kelvin_core",
+        ],
+    }),
 )
diff --git a/hw/dv/tools/dvsim/fusesoc.hjson b/hw/dv/tools/dvsim/fusesoc.hjson
index 522e5a6..3337b7a 100644
--- a/hw/dv/tools/dvsim/fusesoc.hjson
+++ b/hw/dv/tools/dvsim/fusesoc.hjson
@@ -14,6 +14,8 @@
   fusesoc_cores_root_dirs: ["--cores-root {titan_root}/hw/ip",
           "--cores-root {proj_root}/bazel-bin/external/kelvin_hw/hdl/chisel",
           "--cores-root {proj_root}/bazel-bin/hw/top_matcha/ip/dma/chisel",
+          "--cores-root {proj_root}/../../out/kelvin/hw/kelvin_core",
+          "--cores-root {proj_root}/../../out/matcha/hw/fastvdma_core",
           "--cores-root {titan_root}/hw/dv/sv",
           "--cores-root {titan_root}/hw/dv/verilator",
           "--cores-root {titan_root}/hw/formal",
diff --git a/rules/BUILD b/rules/BUILD
index d21803e..a10bb72 100644
--- a/rules/BUILD
+++ b/rules/BUILD
@@ -2,8 +2,9 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-load("//rules:matcha.bzl", "OPENTITAN_PLATFORM")
 load("@bazel_skylib//lib:selects.bzl", "selects")
+load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
+load("//rules:matcha.bzl", "OPENTITAN_PLATFORM")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -24,5 +25,20 @@
 
 selects.config_setting_group(
     name = "sparrow_platform",
-    match_any = [":sparrow_platform_internal", ":sparrow_platform_external"],
+    match_any = [
+        ":sparrow_platform_internal",
+        ":sparrow_platform_external",
+    ],
+)
+
+string_flag(
+    name = "build_env",
+    build_setting_default = "",
+)
+
+config_setting(
+    name = "airgapped_env",
+    flag_values = {
+        ":build_env": "airgapped",
+    },
 )
diff --git a/sw/device/cheriot/soundstream/soundstream.cc b/sw/device/cheriot/soundstream/soundstream.cc
index 6d6c06f..9e880da 100644
--- a/sw/device/cheriot/soundstream/soundstream.cc
+++ b/sw/device/cheriot/soundstream/soundstream.cc
@@ -28,10 +28,16 @@
 
 #define ABS(x) (x > 0 ? x : -x)
 
-//#define kSamples (5 * 16000)
-#define kSamples (2000) // NB: reduced sample count for slow renode
+// #define kSamples (5 * 16000)
+#define kSamples (2000)  // NB: reduce sample count for slow renode
 #define kFilterSamples (256)
 
+// Marker symbols to hook to enable/disable profiling
+extern "C" {
+void __attribute__((noinline)) stats_enable(void) { asm(""); }
+void __attribute__((noinline)) stats_disable(void) { asm(""); }
+}
+
 void __cheri_compartment("soundstream") entry(void) {
   Debug::log("soundstream (Thread {})", thread_id_get());
 
@@ -56,7 +62,13 @@
 
   Debug::log("Setup complete");
 
+  stats_enable();
+// NB: once around the loop for collecting profile data
+#if 0
   while (true) {
+#else
+  {
+#endif
     // TODO(sleffler): need custom security core code running and
     //   a way to toggle the gpio associated with the button; for now
     //   just force it to appear as though the button has been pressed.
@@ -115,7 +127,7 @@
     int32_t max = INT16_MIN;
     int32_t min = INT16_MAX;
     for (int i = 1; i < (samples_captured * 2); i += 2) {
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       int32_t sample = samples_s16[i];
       if (sample < min) {
         min = sample;
@@ -131,7 +143,7 @@
     int32_t scale_min = ABS(((int32_t)min * 100) / ((int32_t)INT16_MIN));
     int32_t scale = scale_max > scale_min ? scale_max : scale_min;
     for (int i = 1; i < (samples_captured * 2); i += 2) {
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       int16_t sample = samples_s16[i];
       int16_t scaled_sample = (int16_t)(((int32_t)sample * 100) / scale);
       scaled_sample = (((int32_t)scaled_sample * 75) / 100);
@@ -151,7 +163,7 @@
 
     for (int i = 0; i < iterations_to_process; ++i) {
       Debug::log("Iteration {}", i);
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       // Extract left channel audio
       for (int j = 0; j < 320; ++j) {
         process_buffer[j] = samples_s16[(i * 320 * 2) + (j * 2) + 1];
@@ -165,7 +177,8 @@
       ml_top_wait_for_finish();
 
       ml_top_get_output_header(&header);
-      Debug::Assert(header.length == sizeof(result_buffer), "Unexpected ML result size");
+      Debug::Assert(header.length == sizeof(result_buffer),
+                    "Unexpected ML result size");
       ml_top_get_output_data(&header, result_buffer);
 
       encode((const unsigned char*)result_buffer, sizeof(result_buffer),
@@ -177,5 +190,6 @@
     Debug::log("[sound]::ENCODER: done");
     Debug::log("Done with processing.");
   }
-  panic();
+  stats_disable();
+  simulation_exit(0);
 }
diff --git a/sw/device/examples/demo_hps_live/BUILD b/sw/device/examples/demo_hps_live/BUILD
index e8b2bdf..cbe8e37 100644
--- a/sw/device/examples/demo_hps_live/BUILD
+++ b/sw/device/examples/demo_hps_live/BUILD
@@ -7,6 +7,7 @@
     "//rules:matcha.bzl",
     "ASIC_CORE_TARGETS",
     "NEXUS_CORE_TARGETS",
+    "matcha_extflash_tar",
     "sec_flash_binary",
     "smc_flash_binary",
 )
@@ -73,3 +74,14 @@
         ],
     }),
 )
+
+matcha_extflash_tar(
+    name = "hps_demo_asic_extflash",
+    sc_binary = ":hps_demo_asic_bin",
+)
+
+matcha_extflash_tar(
+    name = "hps_demo_fpga_nexus_extflash",
+    sc_binary = ":hps_demo_fpga_nexus_bin",
+)
+
diff --git a/sw/device/examples/hello_world/BUILD b/sw/device/examples/hello_world/BUILD
index ea9de45..b9b2189 100644
--- a/sw/device/examples/hello_world/BUILD
+++ b/sw/device/examples/hello_world/BUILD
@@ -63,6 +63,7 @@
     tags = [
         "verilator",
     ],
+    visibility = ["//sw/device/tests:sw_device_test_group"],
 )
 
 sh_test(
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 64f3b94..85e2b9c 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -3,11 +3,16 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
-load("//rules:matcha_test.bzl", "matcha_dv_test", "matcha_verilator_test")
 load("//rules:matcha.bzl", "NEXUS_CORE_TARGETS", "OPENTITAN_CPU", "sec_flash_binary")
+load("//rules:matcha_test.bzl", "matcha_dv_test", "matcha_verilator_test")
 
 package(default_visibility = ["//visibility:public"])
 
+package_group(
+    name = "sw_device_test_group",
+    packages = ["//sw/device/tests/..."],
+)
+
 sec_fpga_device = {
     "fpga_nexus": [NEXUS_CORE_TARGETS.get("secure_core")],
 }