simulate your RTL with real multi-threaded speed
interface different simulators, chiplets and platforms together
multisim is a systemverilog/DPI library allowing multiple simulations/platforms to run in parallel and communicate to simulate your DUT.
Typically, you can have:
- 1 server simulation with your DUT skeleton (NOC, fabric, etc)
- N client simulations with 1 big instance each (computing core, chip, etc)
Assuming your original simulation has N CPUs that take a lot of simulation time.
Into this one, running on N+1 simulation instances:

If the CPU is the bottleneck in terms of performance, you could speed up your simulation N times.
Reusing this example where we have:
- 1 server simulation with 1 NOC
CPU numberclient simulations with 1cpu(slow module) each
- core library (ready/valid protocol)
client->server: multisim_client_push and multisim_server_pullserver->client: multisim_server_push and multisim_client_pull
- other protocols:
- axi
- apb
- quasi static signals (useful for signals without control signals like IRQ)
All examples can be found here:
Tested platform combinations:
| client \ server | sim | emu | sw | sim (4-state) |
|---|---|---|---|---|
| sim | ✅ examples | ✅ examples | untested | unsupported |
| emu | untested | untested | untested | unsupported |
| sw | ✅ examples | ✅ examples | ✅ examples | unsupported |
| sim (4-state) | unsupported | unsupported | unsupported | ✅ examples |
- server simulation and client simulations communicate through channels
- channels direction can be
client->serverorserver->client - each simulation can use multiple channels
multisimmodules need a uniqueserver_nameto link a client/server channel together- client modules need to set
SERVER_RUNTIME_DIRECTORYto know the port/ip address of each channel
You can either:
- use the helper function
$MULTISIM_SRC/bin/kill_all_clientsto kill clients running in the backgroud - use an "exit" channel to send exit instructions to the clients/servers you want to kill
- write a custom kill script
Find more info about PIDs/IPs of your clients in the server runtime directory in .multisim/client*.txt
- source env.sh
- pass the right files to your simulator:
If your platform requires a shared object (.so file), it can be compiled like so:
# SW client example
g++ -o multisim_sw_client.so -g -shared -fPIC \
-DMULTISIM_SW \
$MULTISIM_SRC/core/multisim_client.cpp \
$MULTISIM_SRC/core/socket_server/client.cppLook in the example directory for more examples.
Pros:
- speed: split your big DUT in as many smaller parts as you want
- interoperability: can use different simulators/platforms combinations (Verilator, VCS, Questa, Xcelium, Veloce, Palladium, Zebu, Qemu etc)
- scalability: as long as you have enough CPUs on your server
Cons:
- ⚠ no cycle accuracy ⚠: functionally accurate, but not cycle accurate
- harder debug: waveforms split on N+1 simulation, no time coherency in between them
- simple transaction logging to help debug

