This repository contains a software stack for Spiking Neural Network (SNN) experiments built on top of a firmware fork from the SparkRV project. The main contribution of this project is the custom software implementation under firmware/sw/sparkRV_proj, containing the firmware implementation, as well as configuration and compilation files. The rest of the tree is mostly infrastructure and hardware support code inherited from the upstream SparkRV project. This work is paired with a software component that converts Spiking Neural Network trained from SpikingJelly, a simulation framework for SNNs. The conversion pipeline maps the network parameters on the hardware platform and provide the configuration files and headers used in this repository. The code for this component can be found here.
The software in this repository targets a hardware setup where multiple processing nodes exchange spikes through a Network on-Chip (NoC). The application code is written in C and is compiled for a NOERV32 RISC-V target, then loaded into the hardware flow.
The three main software variants are:
-
Simple reference implementation
- firmware/sw/sparkRV_proj/snn_simple/main.c
- A minimal two-node, single-layer example used to validate the basic execution model, packet format, and timestep-based synchronization.
-
Many-core partitioned implementation
- firmware/sw/sparkRV_proj/snn_manycores/main.c
- A more scalable version that maps the network to several partitions and nodes. It is configured through the configuration headers in firmware/sw/sparkRV_proj/snn_manycores/config/.
-
Event-driven implementation
- firmware/sw/sparkRV_proj/snn_events/main.c
- A variant that uses queue-based event handling and sample-level barriers, making it more suitable for asynchronous and timing-oriented experiments.
The behavior of the firmware is controlled primarily by compile-time macros and node configuration headers. The most important ones are:
N_TIMESTEPSandN_SAMPLES: control the number of timesteps each sample runs for and the number of samples processed.V_RESET_IDXandV_THRESHOLD_IDX: define the indexes to address the neuron parameters in memory.OUTPUT_BUFF_SIZE: defines the size of the output buffer in terms of number of elements, used in the event-driven implementation.TIMESTEP_BARRIERand related packet tags: distinguish control packets from spike payloads in the network protocol.
The timestep count is especially important because it determines how long each inference runs and how often the node waits for barrier packets before advancing to the next step. In practice, changing N_TIMESTEPS changes both the simulation schedule and the runtime behavior of the network.
Macros found in the configuration headers, such as N_NEURONS, N_DESTINATIONS etc., are generated by the conversion pipeline and should not be modified manually. They are used to define the memory layout of the network parameters and the size of the spike payloads.
Other macros, such as HZ_TO_MS_RATIO and CYCLES_PER_TS are used during experiments to measure different metrics, such as latency and periodic accuracy values; they don't affect the functional behavior of the firmware, but should be adjusted as needed when running experiments.
Each variant has its own build script, named compile_code.sh. Before running the script, the user should define the partitioning scheme, so that the configuration headers can be imported correctly. The scheme should match the configuration generated by the conversion pipeline, for example:
PARTITIONS=(
"INPUT"
"1_1"
"1_2"
"1_3"
"1_4"
"1_5"
"2_1"
"3_1"
)
The typical flow is:
- Enter the variant directory you want to build.
- Run the local build script, for example:
cd firmware/sw/sparkRV_proj/snn_manycoressource compile_code.sh
- The script performs the following steps:
- checks that a suitable RISC-V toolchain is available;
- selects the correct makefile from firmware/misc/cfg_make/makefile_rv32 or firmware/misc/cfg_make/makefile_rv64;
- runs
make checkto verify the toolchain; - builds the firmware for the requested node role (
INPUT,SPIKING, orOUTPUT); - emits the resulting ELF and memory initialization artifacts used by the simulator in the
buildfolder (by default located under firmware/sw/sparkRV_proj/).
The simulation is primarily meant to run directly on the hardware platform.
Once the firmware is compiled, the user can load the resulting ELF files into the hardware flow. The repository also provides some scripts to run OpenOCD in the simulation enviroment from firmware/gdb. For more information on how to run the simulation, please contact the SparkRV project maintainers or refer to the SparkRV documentation.
This project is open to contributions. While it mainly targets the SparkRV hardware platform, the software stack is designed to be portable and adaptable to other RISC-V based platforms. If you are interested in contributing, please fork the repository and submit a pull request with your changes. We welcome improvements, bug fixes, and new features that enhance the functionality and usability of the SNN software stack.