Skip to content

htminuslab/Questa_Scala_IPC

Repository files navigation

Questa Scala/SpinalHDL IPC demo design

This repository contains a very basic Questa to Scala InterProcessor Communication(IPC) demo. It doesn't do anything useful it is just a demonstration showing that it is possible to embed Scala into Questa.

Image showing top level

Why is this required?

I have been looking at SpinalHDL which is quite impressive language but the development environment is somewhat lacking.

In the ideal case I would like to run the testbench and the generated code both on Questa. Currently this is not possible, I can think of the following options:

  1. Use one of the supported simulators (GHDL/Verilator/VCS/Icarus) and debug via text and waveforms
  2. Duplicate your SpinalHDL testbench in RTL and use that with the generated code on Questa
  3. Use SpinalHDL to generate a vcd file and use that to drive your stimulus
  4. Use some IPC method to connect the JVM running externally to Questa
  5. Embed the Java Virtual Machine (JVM) into Questa via one of the many C/C++ interfaces (FLI/DPI/VPI/PLI/VHPI)

Option 1: did not work for me under Windows unless I moved the whole environment to wsl. I also like to have more debugging capabilities than just text and waveforms. Once you start using Questa's Visualizer/Verdi/Riviera/etc you get spoiled.

Option 2: Duplicating the testbench is not really an option

Option 3: This works but gives the user a static testbench which for modern designs is too limited.

Option 4: There are quite a few IPC methods that can be used, files, sockets, named pipes, shared memory, or some virtual peripheral bridge. The performance will be slow as you most likely will need to clock to be transmitted over the IPC.

Option 5: This is the nicest solution as you have effectively one environment with both the Questa simulation kernel and the JVM running in lockstep.

Java has a native C/C++ interface (JNI) which was my first approach. Unfortunately this failed as the Questa C/C++ environment is too restrictive. The JVM runtime attempts to control threads, memory management, signals, and system resources which is simply too heavy (if that is the right word) for Questa's restrictive environment. After trying for a weekend I gave up. Whenever I tried to initialise the JVM I got:

res = JNI_CreateJavaVM(&inst->jvm, (void**)&inst->env, &vm_args);

Error occurred during initialization of VM
Failed setting boot class path.

Running the same JNI from a simple C-wrapper worked fine so I know the issue is Questa related.

Luckily all is not lost as the issue seems to be caused by the JVM and there is a different route which is to compile the code. This will replace the heavy JVM with a lightweight runtime manager and hence easier to run in a restrictive environment.

Scala has a compiler called Scala Native which is what I used for this demo. I suspect there will be limitations in terms of Scala/SpinalHDL support.

Tools you need

First you need JAVA, I used JDK21 which I downloaded from here. Install this before you install anything else. Once this is installed make sure you have the JAVA_HOME environmental variable set and pointing to the root directory

Next install Coursier as described in the Spinal Documentation and confirm scala/sbt are available

H:\GitHub\Questa_Scala_IPC>echo %JAVA_HOME%
C:\Program Files\Eclipse Adoptium\jdk-21.0.8.9-hotspot\

H:\GitHub\Questa_Scala_IPC>scala -version
Scala code runner version: 1.9.0
Scala version (default): 3.7.3

H:\GitHub\Questa_Scala_IPC>sbt -version
sbt version in this project: 1.11.6
sbt runner version: 1.11.6

You can now optionally install Verilator/GHDL/Icarus and VSCodium (IDE) as per the SpinalHDL documentation. Note that on my Windows11 I never managed to get Verilator to work, I tried both msys/mingw and wsl route. Verilator run fine in their respective environment but when called from sbt running under a Windows cmd prompt it fails.

[info] [Progress] Verilator compilation started
[info] [info] Found cached verilator binaries
[error] Nonzero exit code returned from runner: -1073740791
[error] (Compile / run) Nonzero exit code returned from runner: -1073740791
[error] Total time: 7 s, completed 12 Sept 2025, 19:51:29

Annoyingly, ghdl also failed:

[info] [Progress] GHDL compilation started
[info] [Progress] GHDL compilation done in 5.620 ms
[info] In file included from D:/msys64/mingw64/include/c++/15.2.0/ext/string_conversions.h:45,
[info]                  from D:/msys64/mingw64/include/c++/15.2.0/bits/basic_string.h:4444,
[error] Exception in thread "main" java.lang.Exception: Compilation of SharedMemIface.cpp failed
[info]                  from D:/msys64/mingw64/include/c++/15.2.0/string:56,

mixing environments (windows with Msys/wsl) is simply to error prone.

Scala Native only works with LLVM/Clang and not with gcc, so you need to install LLVM/Clang. There is a Windows installer to make life easier.

Unfortunately LLVM/Clang does not come with the required Windows runtime/library/header files so you also need to install Visual Studio. I went for the free Visual Studio Community edition.

Once both compilers are installed check that they are in your search path, the same applied to Questa:

H:\GitHub\Questa_Scala_IPC>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.39.33520 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

H:\GitHub\Questa_Scala_IPC>clang --version
clang version 21.1.1
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

H:\GitHub\Questa_Scala_IPC>vcom -version
QuestaSim Base Edition-64 vcom 2025.1 Compiler 2025.01 Jan 17 2025

Run the demo

The Scala testbench is located in src/main/scala/RandomGen.scala, this is an AI generated file which simply generates 8 bit numbers:

import scala.scalanative.unsafe.*
import scala.scalanative.unsigned.*
import scala.util.Random

object RandomGen:
  private val rng = new Random()

  // Exported C function: returns 0–255
  @extern
  @link("c")
  object C

  @exported
  def scala_random8(): CUnsignedChar =
    (rng.nextInt(256)).toUByte

To compile the code into a shared object (DLL for windows) run compile_scala.bat:

h:\GitHub\Questa_Scala_IPC>compile_scala.bat
Compiling SpinalHDL testbench into a shared object...

h:\GitHub\Questa_Scala_IPC>sbt nativeLink
[info] welcome to sbt 1.11.6 (Eclipse Adoptium Java 21.0.8)
[info] loading settings for project questa_scala_ipc-build from plugins.sbt...
[info] loading project definition from H:\GitHub\Questa_Scala_IPC\project
[info] loading settings for project questa_scala_ipc from build.sbt...
[info] set current project to SpinalTB (in build file:/H:/GitHub/Questa_Scala_IPC/)
[info] Linking (multithreadingEnabled=true, disable if not used) (1594 ms)
[info] Discovered 873 classes and 5388 methods after classloading
[info] Checking intermediate code (quick) (94 ms)
[info] Multithreading was not explicitly enabled - initial class loading has not detected any usage of system threads. Multithreading support will be disabled to improve performance.
[info] Linking (multithreadingEnabled=false) (729 ms)
[info] Discovered 769 classes and 4657 methods after classloading
[info] Checking intermediate code (quick) (12 ms)
[info] Discovered 552 classes and 2011 methods after optimization
[info] Optimizing (release-full mode) (4319 ms)
[error] H:/GitHub/Questa_Scala_IPC/target/scala-3.3.1/native/dependencies/nativelib_native0.5_3-0.5.5-0/scala-native/dylib_init.c:17:14: warning: 'getenv' is deprecated: This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations]
[error]    17 |         if (!getenv(NO_DYLIB_CTOR_ENV)) {
[error]       |              ^
[error] C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt\stdlib.h:1183:20: note: 'getenv' has been explicitly marked deprecated here
[error]  1183 |     _Check_return_ _CRT_INSECURE_DEPRECATE(_dupenv_s)
[error]       |                    ^
[error] C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vcruntime.h:355:55: note: expanded from macro '_CRT_INSECURE_DEPRECATE'
[error]   355 |         #define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT(    \
[error]       |                                                       ^
[error] C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vcruntime.h:345:47: note: expanded from macro '_CRT_DEPRECATE_TEXT'
[error]   345 | #define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))
[error]       |                                               ^
[error] 1 warning generated.
[info] Produced 44 LLVM IR files
[info] Generating intermediate code (2270 ms)
[info] Compiling to native code (2534 ms)
[info] Linking with [dbghelp, kernel32, userenv, advapi32]
[info]    Creating library H:/GitHub/Questa_Scala_IPC/target/scala-3.3.1/spinaltb.lib and object H:/GitHub/Questa_Scala_IPC/target/scala-3.3.1/spinaltb.exp
[info] Linking native code (immix gc, none lto) (192 ms)
[info] Postprocessing (0 ms)
[info] Total (10605 ms)
[success] Total time: 12 s, completed 18 Sept 2025, 15:00:58

Note you can ignore the errors, these are caused by Scala Native using insecure functions.

Next compile the VHDL code by running compile_vhdl.bat, the files are located in ./testbench.

h:\GitHub\Questa_Scala_IPC>compile_vhdl.bat
Compiling VHDL testbench...

h:\GitHub\Questa_Scala_IPC>vlib work
Errors: 0, Warnings: 1
h:\GitHub\Questa_Scala_IPC>vcom  -quiet testbench\counter_tester.vhd
h:\GitHub\Questa_Scala_IPC>vcom  -quiet testbench\counter_tb.vhd

next compile the FLI code with compile_fli.bat:

h:\GitHub\Questa_Scala_IPC>compile_fli.bat
Copy testbench DLL to root directory...

h:\GitHub\Questa_Scala_IPC>copy /Y H:\GitHub\Questa_Scala_IPC\target\scala-3.3.1\spinaltb.dll .
        1 file(s) copied.
Compiling FLI code...

h:\GitHub\Questa_Scala_IPC>cl /LD spinal_fli.c /I"D:\Products\questabase_2025.1\\include" "target\scala-3.3.1\spinaltb.lib" "D:\Products\questabase_2025.1\\win64\mtipli.lib" /link /out:spinal_fli.dll
Microsoft (R) C/C++ Optimizing Compiler Version 19.39.33520 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

spinal_fli.c
Microsoft (R) Incremental Linker Version 14.39.33520.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:spinal_fli.dll
/dll
/implib:spinal_fli.lib
/out:spinal_fli.dll
spinal_fli.obj
target\scala-3.3.1\spinaltb.lib
D:\Products\questabase_2025.1\\win64\mtipli.lib
   Creating library spinal_fli.lib and object spinal_fli.exp

The batch file also copies the testbench(scala) dll file to the root directory so we don't have to setup the search path.

Finally run the testbench:

h:\GitHub\Questa_Scala_IPC>vsim -gui -visualizer counter_tb

Image showing Visualizer interface

You will see the VHDL rand8 port being updated by the Scala testbench.

Some advice

  • Forget about using AI for the FLI, it makes too many mistakes such as occasionally mixes VPI with FLI code. It is much quicker to write the code yourself. There is an excellent FLI pdf with examples supplied with Questa
  • AI is OK for generating scala code, make sure you add your tool version to the prompt before you ask it to generate code.
  • If you are serious about SpinalHDL, install it under WSL/Linux, forget about Windows.
  • For waveform display you can convert vcd into qwave (vcd2qwave.exe) and use Visualizer to display it, alternatively use surfer with the fst format. There is also a nice plugin for VSCodium.
  • If you install Verilator under wsl, don't install the binary (sudo apt install verilator) but instead compile from source as you need the latest version.
git clone https://github.com/verilator/verilator
cd verilator/
autoconf
./configure
make -j$(nproc)
sudo apt install help2man
sudo make install

License

See the LICENSE file for details.

Notice

All logos, trademarks and graphics used herein are the property of their respective owners.

About

Connect Scala to Questa

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published