Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ CHANGELOG_GEN.md
# Container Artifacts
.pyusbip/
.cache/

CLAUDE.md
12 changes: 11 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ elseif(platform STREQUAL PULPOpen)
elseif(platform STREQUAL GAP9)
message(STATUS "Building for platform 'GAP9'")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(ENV{KCONFIG_CONFIG} DeeployTest/Platforms/GAP9/sdk.config)

# Select SDK config based on simulator type
if(SIMULATOR STREQUAL "board")
set(ENV{KCONFIG_CONFIG} DeeployTest/Platforms/GAP9/sdk_board.config)
message(STATUS "[GAP9] Using board SDK configuration")
else()
set(ENV{KCONFIG_CONFIG} DeeployTest/Platforms/GAP9/sdk_gvsoc.config)
message(STATUS "[GAP9] Using GVSoC SDK configuration")
endif()

include($ENV{GAP_SDK_HOME}/utils/cmake/setup.cmake)
elseif(platform STREQUAL Generic)
message(STATUS "Building for platform 'Generic'")
Expand Down Expand Up @@ -225,6 +234,7 @@ endif()
if(platform STREQUAL GAP9)
project(${TESTNAME} LANGUAGES C ASM)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/gap9/gap9_gvsoc.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/gap9/gap9_board.cmake)
add_compile_options(
-Wno-error=unknown-pragmas
)
Expand Down
5 changes: 5 additions & 0 deletions DeeployTest/Platforms/GAP9/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ target_include_directories(${ProjectId} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/inc)
target_link_libraries(${ProjectId} PRIVATE network deeploylib)
target_compile_options(${ProjectId} INTERFACE network)
add_gvsoc_emulation(${ProjectId} "gap9.evk")
add_board_deployment(${ProjectId} "gap9.evk")

if(POWER_MEASUREMENT)
target_compile_definitions(${ProjectId} PRIVATE POWER_MEASUREMENT)
endif()

# RW: Waive sign comparison warnings from pulp_nn_utils.h
target_compile_options(network PRIVATE
Expand Down
34 changes: 34 additions & 0 deletions DeeployTest/Platforms/GAP9/sdk_board.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0

CONFIG_BOARD_GAP9MOD_V1_0_B=y
CONFIG_BOARD_GAP9EVK_V1_3=y

CONFIG_DRIVER_CLUSTER=y
CONFIG_DRIVER_CLUSTER_CONF_PROPERTY_ICACHE_CONF=0x7FF

CONFIG_DRIVER_TYPE_FLASH=y
CONFIG_DRIVER_TYPE_RAM=y

CONFIG_DRIVER_MRAM=y
CONFIG_READFS_FLASH_TYPE_OSPI=y

CONFIG_DRIVER_READFS=y
# CONFIG_READFS_FLASH_TYPE_MRAM=y

CONFIG_DRIVER_APS256XXN=y
CONFIG_DRIVER_RAM_API=y

CONFIG_ENABLE_LIBMATH=y

# OS float printf
CONFIG_IO_PRINTF_FLOAT_ENABLE=y
CONFIG_IO_PRINTF_FLOAT_EXPONENT_ENABLE=y

# CONFIG_PLATFORM_GVSOC=y
CONFIG_PLATFORM_BOARD=y
# CONFIG_DRIVER_CLUSTERDECOMPRESSOR=n

#CONFIG_CL_MASTER_CORE_STACK_SIZE=14000
#CONFIG_CL_SLAVE_CORE_STACK_SIZE=1000
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ CONFIG_IO_PRINTF_FLOAT_ENABLE=y
CONFIG_IO_PRINTF_FLOAT_EXPONENT_ENABLE=y

CONFIG_PLATFORM_GVSOC=y
# CONFIG_PLATFORM_BOARD=y
# CONFIG_DRIVER_CLUSTERDECOMPRESSOR=n

# GAP9 cluster stack size configuration
# Uncomment and adjust these values if you need to modify stack sizes:
# CONFIG_CL_MASTER_CORE_STACK_SIZE=14000
# CONFIG_CL_SLAVE_CORE_STACK_SIZE=1000
# CONFIG_CL_SLAVE_CORE_STACK_SIZE=1000
21 changes: 21 additions & 0 deletions DeeployTest/Platforms/GAP9/src/deeploytest.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
// RW: Remove MAINSTACKSIZE because gap9-sdk does not use it
#define SLAVESTACKSIZE 3800

#ifdef POWER_MEASUREMENT
unsigned int GPIOs = 89;
#define WRITE_GPIO(x) pi_gpio_pin_write(GPIOs, x)
#endif

struct pi_device cluster_dev;
uint32_t total_cycles = 0;

Expand Down Expand Up @@ -78,6 +83,13 @@ void RunNetworkWrapper(void *args) {
}

int main(void) {

#ifdef POWER_MEASUREMENT
pi_pad_function_set(GPIOs, 1);
pi_gpio_pin_configure(GPIOs, PI_GPIO_OUTPUT);
pi_gpio_pin_write(GPIOs, 0);
#endif

#ifndef CI
uint32_t core_id = pi_core_id(), cluster_id = pi_cluster_id();
printf("[%d %d] Hello World!\n", cluster_id, core_id);
Expand Down Expand Up @@ -119,8 +131,17 @@ int main(void) {

pi_cluster_task(&cluster_task, RunNetworkWrapper, NULL);
cluster_task.slave_stack_size = SLAVESTACKSIZE;

#ifdef POWER_MEASUREMENT
WRITE_GPIO(1);
#endif

pi_cluster_send_task_to_cl(&cluster_dev, &cluster_task);

#ifdef POWER_MEASUREMENT
WRITE_GPIO(0);
#endif

#ifndef CI
printf("Output:\r\n");
#endif
Expand Down
4 changes: 4 additions & 0 deletions DeeployTest/deeployRunner_gap9.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
# Define parser setup callback to add GAP9-specific arguments
def setup_parser(parser):
parser.add_argument('--cores', type = int, default = 8, help = 'Number of cores (default: 8)\n')
parser.add_argument('--powerMeasurement',
action = 'store_true',
default = False,
help = 'Enable power measurement GPIO toggling\n')

sys.exit(
main(default_platform = "GAP9",
Expand Down
4 changes: 4 additions & 0 deletions DeeployTest/deeployRunner_tiled_gap9.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
# Define parser setup callback to add GAP9-specific arguments
def setup_parser(parser):
parser.add_argument('--cores', type = int, default = 8, help = 'Number of cores (default: 8)\n')
parser.add_argument('--powerMeasurement',
action = 'store_true',
default = False,
help = 'Enable power measurement GPIO toggling\n')

sys.exit(
main(default_platform = "GAP9",
Expand Down
36 changes: 28 additions & 8 deletions DeeployTest/testUtils/core/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# SPDX-License-Identifier: Apache-2.0

import os
import re
import shutil
import subprocess
import sys
from pathlib import Path

from Deeploy.Logging import DEFAULT_LOGGER as log
Expand Down Expand Up @@ -148,6 +148,12 @@ def build_binary(config: DeeployTestConfig) -> None:
raise RuntimeError(f"Build failed for {config.test_name}")


# Source: https://stackoverflow.com/a/38662876
def escapeAnsi(line):
ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
return ansi_escape.sub('', line)


def run_simulation(config: DeeployTestConfig, skip: bool = False) -> TestResult:
"""
Run simulation and parse output.
Expand Down Expand Up @@ -191,15 +197,29 @@ def run_simulation(config: DeeployTestConfig, skip: bool = False) -> TestResult:

log.debug(f"[Execution] Simulation command: {' '.join(cmd)}")

result = subprocess.run(cmd, capture_output = True, text = True, env = env)

if result.stdout:
print(result.stdout, end = '')
if result.stderr:
print(result.stderr, end = '', file = sys.stderr)
cmd_str = " ".join(cmd)
with subprocess.Popen(cmd_str,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
shell = True,
encoding = 'utf-8') as process:

with open('out.txt', 'a', encoding = 'utf-8') as fileHandle:
fileHandle.write(
f"################## Testing {config.test_dir} on {config.platform} Platform ##################\n")

result = ""
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
result += output
fileHandle.write(f"{escapeAnsi(output)}")

# Parse output for error count and cycles
test_result = parse_test_output(result.stdout, result.stderr)
test_result = parse_test_output(result, "")

if not test_result.success and test_result.error_count == -1:
log.warning(f"Could not parse error count from output")
Expand Down
7 changes: 6 additions & 1 deletion DeeployTest/testUtils/deeployRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,6 @@ def main(default_platform: Optional[str] = None,
# Extract platform-specific CMake args from parsed args if available
if platform_specific_cmake_args is None:
platform_specific_cmake_args = []

# Check for platform-specific arguments in args object and build CMake args
if hasattr(args, 'cores'):
platform_specific_cmake_args.append(f"-DNUM_CORES={args.cores}")
Expand All @@ -405,6 +404,12 @@ def main(default_platform: Optional[str] = None,
if hasattr(args, 'num_clusters'):
platform_specific_cmake_args.append(f"-DNUM_CLUSTERS={args.num_clusters}")

if hasattr(args, 'powerMeasurement') and args.powerMeasurement:
platform_specific_cmake_args.append("-DPOWER_MEASUREMENT=ON")

if platform == 'GAP9':
platform_specific_cmake_args.append("-D SIMULATOR=" + simulator)

config = create_config_from_args(args, platform, simulator, tiling_enabled, platform_specific_cmake_args)

print_configuration(config)
Expand Down
6 changes: 4 additions & 2 deletions DeeployTest/testUtils/testRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def __init__(self,
gen_args: str = "",
cmake_args: str = ""):

if simulator not in ['gvsoc', 'banshee', 'qemu', 'vsim', 'vsim.gui', 'host', 'none']:
if simulator not in ['gvsoc', 'banshee', 'qemu', 'vsim', 'vsim.gui', 'host', 'board', 'none']:
raise ValueError(
f"Invalid emulator {simulator} (valid options are 'gvsoc', 'banshee', 'qemu', 'vsim', 'vsim.gui', 'host', 'none')!"
)
Expand Down Expand Up @@ -381,7 +381,7 @@ def configure_cmake_project(self):
else:
self.cmake_args += " -D gvsoc_simulation=OFF"

command = f"$CMAKE -D TOOLCHAIN={self._args.toolchain} -D GVSOC_INSTALL_DIR={self._dir_gvsoc} -D TOOLCHAIN_INSTALL_DIR={self._dir_toolchain} -D GENERATED_SOURCE={self._dir_gen} -D platform={self._platform} {self.cmake_args} -B {self._dir_build} -D TESTNAME={self._name_test} .."
command = f"$CMAKE -D TOOLCHAIN={self._args.toolchain} -D GVSOC_INSTALL_DIR={self._dir_gvsoc} -D TOOLCHAIN_INSTALL_DIR={self._dir_toolchain} -D GENERATED_SOURCE={self._dir_gen} -D platform={self._platform} -D SIMULATOR={self._simulator} {self.cmake_args} -B {self._dir_build} -D TESTNAME={self._name_test} .."

if self._args.verbose >= 3:
command = "VERBOSE=1 " + command + " --log-level debug"
Expand Down Expand Up @@ -414,6 +414,8 @@ def run_simulation(self, out_file = 'out.txt'):

if self._simulator == 'host':
command = f"{self._dir_build}/bin/{self._name_test}"
elif self._simulator == 'board':
command = f"$CMAKE --build {self._dir_build} --target board_{self._name_test}"
else:
command = f"$CMAKE --build {self._dir_build} --target {self._simulator}_{self._name_test}"

Expand Down
76 changes: 76 additions & 0 deletions cmake/gap9/gap9_board.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0


macro(add_board_deployment name target)

if(NOT DEFINED GVSOC_INSTALL_DIR)
message(FATAL_ERROR "Environment variable GVSOC_INSTALL_DIR not set")
endif()

message(STATUS "[Deeploy GAP9] Running on Board")

set(BOARD_WORKDIR ${CMAKE_BINARY_DIR}/board_workdir)
set(DEEPLOY_BINARY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${name}")
set(GAP9_SDK_HOME $ENV{GAP_SDK_HOME})
set(GAPY "${GAP9_SDK_HOME}/utils/gapy_v2/bin/gapy")
set(FLASH_LAYOUT "${GAP9_SDK_HOME}/utils/layouts/default_layout_multi_readfs.json")
set(FSBL_BINARY "${GAP9_SDK_HOME}/install/target/bin/fsbl")
set(SSBL_BINARY "${GAP9_SDK_HOME}/install/target/bin/ssbl")

make_directory(${BOARD_WORKDIR})

if(NOT DEFINED GAP9_SDK_HOME)
message(FATAL_ERROR "Environment variable GAP_SDK_HOME not set")
endif()

# Command to run on board
set(GAPY_CMD
${GAPY}
--target=gap9.evk
--platform=board
--target-property=boot.flash_device=mram
--target-property=boot.mode=flash
--target-dir=${GAP9_SDK_HOME}/utils/gapy_v2/targets
--openocd-cable=${GAP9_SDK_HOME}/utils/openocd_tools/tcl/gapuino_ftdi.cfg
--openocd-script=${GAP9_SDK_HOME}/utils/openocd_tools/tcl/gap9revb.tcl
--openocd-tools=${GAP9_SDK_HOME}/utils/openocd_tools
--binary=${DEEPLOY_BINARY}
--work-dir=${BOARD_WORKDIR}
--multi-flash-content=${FLASH_LAYOUT}
--flash-size=67108864
--flash-property=${FSBL_BINARY}@mram:fsbl:binary
--flash-property=${SSBL_BINARY}@mram:ssbl:binary
--flash-property=${DEEPLOY_BINARY}@mram:app:binary run
--py-stack
)

# Add readfs files if provided
if(GAPY_RUNNER_ARGS)
list(LENGTH GAPY_RUNNER_ARGS num_readfs_files)
message(STATUS "[Deeploy GAP9] Adding ${num_readfs_files} readfs file(s)")
list(APPEND GAPY_CMD ${GAPY_RUNNER_ARGS})
endif()

# Convert list to string for printing
string(REPLACE ";" " " GAPY_CMD_STR "${GAPY_CMD}")

add_custom_target(board_${name}
DEPENDS ${name}
WORKING_DIRECTORY ${BOARD_WORKDIR}
COMMAND bash -c "${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/*.bin ${BOARD_WORKDIR}/ 2>/dev/null || true"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${GAP9_SDK_HOME}/utils/efuse/GAP9/efuse_hyper_preload.data
${BOARD_WORKDIR}/chip.efuse_preload.data
COMMAND ${CMAKE_COMMAND} -E echo "=========================================="
COMMAND ${CMAKE_COMMAND} -E echo "[Deeploy GAP9] Executing gapy command to run on board:"
COMMAND ${CMAKE_COMMAND} -E echo "${GAPY_CMD_STR}"
COMMAND ${CMAKE_COMMAND} -E echo "=========================================="
COMMAND ${GAPY_CMD}
COMMENT "Running ${name} with gapy on GAP9 board"
POST_BUILD
USES_TERMINAL
VERBATIM
)
endmacro()
4 changes: 1 addition & 3 deletions cmake/gap9/gap9_gvsoc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#
# SPDX-License-Identifier: Apache-2.0

# Mark that GAP9-specific gvsoc emulation is defined
set(GAP9_GVSOC_DEFINED TRUE)

macro(add_gvsoc_emulation name target)

Expand All @@ -19,6 +17,7 @@ macro(add_gvsoc_emulation name target)

# Check if GAPY_RUNNER_ARGS is defined and non-empty (indicates L3 with readfs files)
if(GAPY_RUNNER_ARGS)

# L3 mode: Use gapy with flash layout and readfs
message(STATUS "[Deeploy GAP9] L3 mode: using gapy with readfs")

Expand Down Expand Up @@ -81,7 +80,6 @@ macro(add_gvsoc_emulation name target)
USES_TERMINAL
VERBATIM
)

else()
# L2 mode: Use traditional gvsoc command directly (no flash/readfs)
message(STATUS "[Deeploy GAP9] L2 mode: using traditional gvsoc without flash")
Expand Down
Loading
Loading