Skip to content

Commit

Permalink
Merge pull request #130 from Bill94l/rvls-update
Browse files Browse the repository at this point in the history
Add CI scripts and setup files to automate installation
  • Loading branch information
Dolu1990 authored Feb 12, 2025
2 parents 10fafe7 + 3cda546 commit 1e1bc54
Show file tree
Hide file tree
Showing 33 changed files with 3,819 additions and 103 deletions.
24 changes: 13 additions & 11 deletions .github/workflows/scala.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,20 @@ jobs:
- name: Setup env
run: echo "$HOME/tools/bin" >> $GITHUB_PATH

- name: Install cached tools
if: steps.tools.outputs.cache-hit != 'true'
run: source .github/workflows/tools.sh && install_cached

- name: Install uncached tools
run: source .github/workflows/tools.sh && install_uncached

- name: Install SpinalHDL
run: (cd .. && git clone https://github.com/SpinalHDL/SpinalHDL.git -b dev)
- name: Install all tools
run: source .github/workflows/tools.sh && install_all

- name: Compile
run: sbt clean compile

- name: Test
run: NAXRISCV_REGRESSION_THREAD_COUNT=1 SBT_OPTS="-Xmx2G -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xss2M -Duser.timezone=GMT" sbt test
- name: Regression Test SIMULATOR
run: |
export NAXRISCV_REGRESSION_THREAD_COUNT=1
export SBT_OPTS="-Xmx2G -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xss2M -Duser.timezone=GMT"
sbt "testOnly *NaxRiscvRegression"
- name: Regression Test RVLS
run: |
export NAXRISCV_REGRESSION_THREAD_COUNT=1
export SBT_OPTS="-Xmx2G -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=2G -Xss2M -Duser.timezone=GMT"
sbt "testOnly *NaxRiscvRvls"
6 changes: 6 additions & 0 deletions .github/workflows/tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ install_elfio(){
install_packages(){
sudo apt-get update
sudo apt install -y zlib1g-dev libboost-all-dev libboost-dev libasio-dev device-tree-compiler libsdl2-2.0-0 libsdl2-dev
sudo apt install -y git make autoconf build-essential flex libfl-dev bison help2man # First time prerequisites
}

install_uncached(){
Expand All @@ -78,3 +79,8 @@ install_cached(){
(install_spike)
(install_verilator)
}

install_all(){
export NAXRISCV=${PWD}
make install
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ obj_dir
explor
nax.h

toolchain/
simWorkspace/
tmp/
/archive.tar.gz
*.out32
.metals/
src/test/python/naxriscv/*.mk
*.diff
169 changes: 169 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Constants
PRJ_NAX=NaxRiscv
PROJECT?=$(PRJ_NAX)
# Dirs
MKFILE_PATH=$(abspath $(firstword $(MAKEFILE_LIST)))
CORE_DIR=$(dir $(MKFILE_PATH))
TOOLCHAIN_DIR=$(CORE_DIR)/toolchain
# Tools
SPIKE_DIR=$(CORE_DIR)/ext/riscv-isa-sim
RVLS_DIR=$(CORE_DIR)/ext/rvls
RISCV_TEST_DIR=$(CORE_DIR)/ext/NaxSoftware/riscv-tests
# Riscv gcc
RISCV_HOST=riscv64-unknown-elf
RISCV=$(TOOLCHAIN_DIR)/riscv-gnu-toolchain
RISCV_VERSION=409b951ba6621f2f115aebddfb15ce2dd78ec24f
RISCV_GCC=$(RISCV)/bin/$(RISCV_HOST)-gcc
RISCV_OBJCOPY=$(RISCV)/bin/$(RISCV_HOST)-objcopy
RISCV_OBJDUMP=$(RISCV)/bin/$(RISCV_HOST)-objdump
# Verilator
VERILATOR_VERSION_NAX=v4.216
VERILATOR_ROOT_NAX=$(TOOLCHAIN_DIR)/verilator-$(VERILATOR_VERSION_NAX)
# ELFIO
ELFIO_VERSION=d251da09a07dff40af0b63b8f6c8ae71d2d1938d # Avoid C++17
# SDL
LIBSDL_VERSION=60d1944e463da73f753661190d783961a9c5b764
# SBT
SBT_VERSION=1.7.1
# OpenJDK
OPENJDK_VERSION=11.0.15+10
OPENJDK_HOME=$(TOOLCHAIN_DIR)/openjdk
# Git links
GIT_URL_NAXRISCV=https://github.com/SpinalHDL/NaxRiscv
GIT_URL_SPINALHDL=https://github.com/SpinalHDL/SpinalHDL.git

# install toolchain ####################################

# install core
install-core:
./ci/clone-submodules.sh $(CORE_DIR)

# install initial
install-toolchain-initial: install-core
mkdir -p $(TOOLCHAIN_DIR)
./ci/install-sbt.sh $(SBT_VERSION) $(TOOLCHAIN_DIR)
./ci/install-openjdk.sh $(OPENJDK_VERSION) $(TOOLCHAIN_DIR)

# install toolchain
install-toolchain: install-toolchain-initial
./ci/install-verilator.sh $(VERILATOR_VERSION_NAX) $(TOOLCHAIN_DIR)
./ci/install-libsdl-elfio-spikespinalhdl.sh $(SPIKE_DIR) $(ELFIO_VERSION) $(LIBSDL_VERSION)
./ci/install-rvls.sh $(RVLS_DIR)

# build spike & rvls after modification
build-spike-rvls:
./ci/build_spike_rvls.sh $(CORE_DIR)

# build regress simulator after modification
build-simulator:
./ci/build_regress_simulator.sh $(CORE_DIR)

# All NaxRiscv targets implements machine, supervisor and user mode
TARGETS_NAX=("rv32imasu" "rv32imacsu" "rv32imafcsu" "rv32imafdcsu" "rv64imasu" "rv64imacsu" "rv64imafcsu" "rv64imafdcsu")

# Set default target if not specified
TARGET_NAX ?= rv64imafdcsu

# Define parameters for each target
# RV32
rv32imasu_PARAMS :=
rv32imacsu_PARAMS := --withRvc
rv32imafcsu_PARAMS := --withRvc --withFloat
rv32imafdcsu_PARAMS := --withRvc --withFloat --withDouble
# RV64
rv64imasu_PARAMS :=
rv64imacsu_PARAMS := --withRvc
rv64imafcsu_PARAMS := --withRvc --withFloat
rv64imafdcsu_PARAMS := --withRvc --withFloat --withDouble

# Get the parameters for the selected target
PARAMS := $($(TARGET_NAX)_PARAMS)

# Determine the command based on the target architecture (32-bit or 64-bit)
ifneq (,$(findstring 32,$(TARGET_NAX)))
GEN_CMD := $(TOOLCHAIN_DIR)/sbt/bin/sbt "runMain naxriscv.Gen $(PARAMS)"
XLEN := 32
else
GEN_CMD := $(TOOLCHAIN_DIR)/sbt/bin/sbt "runMain naxriscv.Gen64 $(PARAMS)"
XLEN := 64
endif

# RTL of NaxRiscv
.PHONY: $(PRJ_NAX).v
$(PRJ_NAX).v:
echo " ";\
echo "Selected target: $(TARGET_NAX)";\
echo "Parameters: $(PARAMS)";\
echo "Generation command: $(GEN_CMD)";\
echo " ";\
export JAVA_HOME=$(OPENJDK_HOME); \
export NAXRISCV=$(CORE_DIR); \
export PATH=$(OPENJDK_HOME)/bin:$(PATH); \
$(MAKE) clean-gen; \
cd $(CORE_DIR); \
$(GEN_CMD); \

# Verilator model of NaxRiscv
.PHONY: src/test/cpp/naxriscv/obj_dir/VNaxRiscv
src/test/cpp/naxriscv/obj_dir/VNaxRiscv:$(PRJ_NAX).v
make -C $(CORE_DIR)/src/test/cpp/naxriscv compile
VERILATOR_ROOT=$(VERILATOR_ROOT_NAX)
SPIKE=$(SPIKE_DIR)
PATH=$(VERILATOR_ROOT_NAX)/bin:$(PATH)

verilate-$(PRJ_NAX): src/test/cpp/naxriscv/obj_dir/VNaxRiscv

# install
install:clean-all install-toolchain
@echo " "
@echo "[SUCCESS] The entire toolchain is built with Success."
@echo " "

# test execute #########################################
test-regression :
@echo "Testing with NaxRiscvRegression...."
sbt "testOnly *.NaxRiscvRegression"

test-rvls :
@echo "Testing with NaxRiscvRvls...."
sbt "testOnly *.NaxRiscvRvls"
# clean ################################################

clean-submodules:
rm -rf $(CORE_DIR)/ext/*

clean-install:
rm -rf $(CORE_DIR)/tmp

clean-sim:
rm -rf $(CORE_DIR)/.venv

clean-workspace:
rm -rf $(CORE_DIR)/simWorkspace

clean-exec:
rm -rf *.tmp
rm -rf *.xml
rm -rf *.tar.gz

clean-toolchain:
rm -rf $(TOOLCHAIN_DIR)

clean-gen:
rm -rf $(CORE_DIR)/src/test/cpp/naxriscv/obj_dir
rm -f $(PRJ_NAX).v
rm -f nax.h
rm -f NaxRiscvSynt.v

clean-all: clean-install clean-sim clean-workspace clean-exec clean-gen
rm -rf $(TOOLCHAIN_DIR)/openjdk
rm -rf $(TOOLCHAIN_DIR)/sbt
rm -rf $(TOOLCHAIN_DIR)/verilator-$(VERILATOR_VERSION_NAX)
rm -rf $(SPIKE_DIR)
rm -rf $(RVLS_DIR)
rm -rf $(CORE_DIR)/ext/SpinalHDL
rm -rf $(CORE_DIR)/ext/NaxSoftware

# include ################################################
-include testsRvls.mk
-include src/test/python/naxriscv/all_testsRvls.mk
80 changes: 80 additions & 0 deletions Patch_DualSimTracer_toSupportSeveralELF_addRunningLinuxFlag.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
diff --git a/lib/src/main/scala/spinal/lib/misc/test/DualSimTracer.scala b/lib/src/main/scala/spinal/lib/misc/test/DualSimTracer.scala
index 5160ace69..d12a2a8ef 100644
--- a/lib/src/main/scala/spinal/lib/misc/test/DualSimTracer.scala
+++ b/lib/src/main/scala/spinal/lib/misc/test/DualSimTracer.scala
@@ -12,14 +12,68 @@ import scala.concurrent.ExecutionContext
*/
object DualSimTracer {
def apply[T <: Component](compiled: SimCompiled[T], window: Long, seed: Int)(testbench: T => Unit): Unit = withCb(compiled, window, seed) { (dut, _) => testbench(dut) }
- def withCb[T <: Component](compiled: SimCompiled[T], window: Long, seed: Int, dualSimEnable : Boolean)(testbench: (T, (=> Unit) => Unit) => Unit): Unit = {
- dualSimEnable match {
- case true => DualSimTracer.withCb(compiled, window, seed)(testbench)
- case false => {
- val traceCallbacks = ArrayBuffer[() => Unit]()
- compiled.doSimUntilVoid(seed = seed) { dut => testbench(dut, f => traceCallbacks += (() => f)); traceCallbacks.foreach(_())}
+
+ def apply[T <: Component](compiled: SimCompiled[T], window: Long, seed: Int, elfFile : String, runBuildroot: Boolean = false)(testbench: T => Unit): Unit = withCb(compiled, window, seed, elfFile, runBuildroot) { (dut: T, _, _, _) => testbench(dut) }
+
+ def withCb[T <: Component](compiled: SimCompiled[T], window: Long, seed: Int, elfFile : String, runBuildroot: Boolean = false)(testbench: (T, (=> Unit) => Unit, String, Boolean) => Unit): Unit = {
+ var mTime = 0l
+ var mEnded = false
+ var explorerFailed = false
+
+ implicit val ec = ExecutionContext.global
+
+ val testName = elfFile.substring(elfFile.lastIndexOf("/") + 1)
+
+ val explorer = new AsyncJob(toStdout = true, logsPath = new File(compiled.compiledPath, "explorer/" + testName)) ({
+ try {
+ compiled.doSimUntilVoid(name = testName + s"_explorer", seed = seed) { dut =>
+ disableSimWave()
+ periodicaly(window) {
+ mTime = simTime()
+ }
+ onSimEnd {
+ mTime = simTime()
+ mEnded = true
+ }
+ testbench(dut, cb => {}, elfFile, runBuildroot)
+ }
+// println("Explorer success")
+ } catch {
+ case e: Throwable => explorerFailed = true; throw e
}
- }
+ })
+
+ val tracer = new AsyncJob(toStdout = false, logsPath = new File(compiled.compiledPath, "tracer/" + testName))({
+ val traceCallbacks = ArrayBuffer[() => Unit]()
+ compiled.doSimUntilVoid(name = testName + s"_tracer", seed = seed) { dut =>
+ disableSimWave()
+ fork {
+ sleep(0)
+ while (true) {
+ while (simTime + window * 2 >= mTime && !mEnded) {
+ Thread.sleep(100, 0)
+ }
+ if (mEnded && explorerFailed) {
+ sleep((mTime - simTime - window) max 0)
+ enableSimWave()
+ traceCallbacks.foreach(_())
+ sleep(window + 1000)
+ simFailure("slave thread didn't ended ????")
+ }
+ sleep(window)
+ }
+ }
+// println("Tracer success")
+ testbench(dut, callback => traceCallbacks += (() => callback), elfFile, runBuildroot)
+ }
+ })
+
+ explorer.join()
+ tracer.join()
+
+ assert(explorer.failed == tracer.failed)
+
+ if (tracer.failed) throw new Exception(s"Dual sim reached end with failure, see ${tracer.logsPath.getAbsolutePath}")
}

def withCb[T <: Component](compiled: SimCompiled[T], window: Long, seed: Int)(testbench: (T, (=> Unit) => Unit) => Unit): Unit = {
80 changes: 80 additions & 0 deletions adding_wavePath_simConfig.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
diff --git a/core/src/main/scala/spinal/core/sim/SimBootstraps.scala b/core/src/main/scala/spinal/core/sim/SimBootstraps.scala
index cb825e689..7f5cf3b2a 100644
--- a/core/src/main/scala/spinal/core/sim/SimBootstraps.scala
+++ b/core/src/main/scala/spinal/core/sim/SimBootstraps.scala
@@ -658,6 +658,7 @@ object SpinalSimBackendSel{
case class SpinalSimConfig(
var _workspacePath : String = System.getenv().getOrDefault("SPINALSIM_WORKSPACE","./simWorkspace"),
var _workspaceName : String = null,
+ var _wavePath : String = "./",
var _waveDepth : Int = 0, //0 => all
var _spinalConfig : SpinalConfig = SpinalConfig(),
var _optimisationLevel : Int = 0,
@@ -813,6 +814,12 @@ case class SpinalSimConfig(
this
}

+ def wavePath(path: String): this.type = {
+ _wavePath = path
+ println("SET WAVE PATH: " + _wavePath)
+ this
+ }
+
def withConfig(config: SpinalConfig): this.type = {
_spinalConfig = config
this
@@ -972,9 +979,33 @@ case class SpinalSimConfig(
_workspaceName = SimWorkspace.allocateWorkspace(_workspacePath, _workspaceName)

println(f"[Progress] Simulation workspace in ${new File(s"${_workspacePath}/${_workspaceName}").getAbsolutePath}")
- new File(s"${_workspacePath}").mkdirs()
- FileUtils.deleteQuietly(new File(s"${_workspacePath}/${_workspaceName}"))
- new File(s"${_workspacePath}/${_workspaceName}").mkdirs()
+ val workspacePathDir = new File(s"${_workspacePath}")
+ // Create folder only if it does not exist
+ if (!workspacePathDir.exists()) workspacePathDir.mkdirs()
+
+ val workspaceDir = new File(s"${_workspacePath}/${_workspaceName}")
+ if (workspaceDir.exists() && workspaceDir.isDirectory()) {
+ workspaceDir.listFiles().foreach { file =>
+ try {
+ val extension = file.getName().split('.').lastOption.getOrElse("")
+ if (!Set("py", "mk").contains(extension) && file.getName() != "Makefile" && file.getName() != "logs" && file.getName() != "waves" && !file.isDirectory()) {
+ FileUtils.deleteQuietly(file)
+ }
+ } catch {
+ case e: Exception =>
+ println(s"Failed to delete file: ${file.getName()}")
+ e.printStackTrace()
+ }
+ }
+ } else {
+ println(s"Directory ${workspaceDir.getAbsolutePath()} does not exist or is not a directory.")
+ }
+
+ if (!workspaceDir.exists()) workspaceDir.mkdirs()
+
+ val wavePathDir = new File(s"${_workspacePath}/${_workspaceName}/${_wavePath}")
+ if (!wavePathDir.exists()) wavePathDir.mkdirs()
+
new File(s"${_workspacePath}/${_workspaceName}/rtl").mkdirs()

val compiledPath = new File(s"${_workspacePath}/${_workspaceName}")
@@ -1022,7 +1053,7 @@ case class SpinalSimConfig(
maxCacheEntries = _maxCacheEntries,
cachePath = if (!_disableCache) (if (_cachePath != null) _cachePath else s"${_workspacePath}/.cache") else null,
workspacePath = s"${_workspacePath}/${_workspaceName}",
- vcdPath = wavePath,
+ vcdPath = s"${_workspacePath}/${_workspaceName}/${_wavePath}",
vcdPrefix = null,
workspaceName = "verilator",
waveDepth = _waveDepth,
@@ -1174,6 +1205,8 @@ case class SimConfigLegacy[T <: Component](
def workspacePath(path: String): this.type = { _simConfig.workspacePath(path); this }
def workspaceName(name: String): this.type = { _simConfig.workspaceName(name); this }

+ def wavePath(path: String): this.type = { _simConfig.wavePath(path); this }
+
def withConfig(config: SpinalConfig): this.type = { _simConfig.withConfig(config); this }

def noOptimisation: this.type = { _simConfig.noOptimisation ; this }
Loading

0 comments on commit 1e1bc54

Please sign in to comment.