Skip to content
antoinemadecPublic

About

SV/DPI library allowing multiple simulations/platforms to run in parallel and communicate

Topics

Resources

Stars

17 stars

Watchers

2 watching

Forks

Latest commit

 

History

101 Commits

Folders and files

Repository files navigation

Multisim

simulate your RTL with real multi-threaded speed
interface different simulators, chiplets and platforms together

✨ Rationale

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)

example: normal vs multisim simulation

Assuming your original simulation has N CPUs that take a lot of simulation time.

You could transform this DUT:
normal simulation

Into this one, running on N+1 simulation instances:
multi simulations

🚄 Performance

Reusing this example where we have:

  • 1 server simulation with 1 NOC
  • CPU number client simulations with 1 cpu (slow module) each

sim speed

📚 Usage

examples

Tested platform combinations:

client \ server sim emu sw
sim ✅ examples ✅ examples untested
emu untested untested untested
sw ✅ examples ✅ examples ✅ examples

regression

./run_regression.sh            # all the tools: sw,verilator,vcs,zebu
./run_regression.sh -t sw,vcs  # some of them
./run_regression.sh -z         # also build the ZeBu database if needed (about 1 hour)
./run_regression.sh -a         # also run the long sim_server and emu_server example suites

Short versions of the tests, a summary at the end (PASS/FAIL/SKIP per tool and test), exit code 1 if a test fails. Tools that are not installed are skipped. Logs and the summary (summary.txt) are in output_regression/.

  • sw (g++ only, about 1 min): example/sw_server/sw_client/run_all.sh, the read_write example and the unit regression tests of the library
  • verilator: sim_server examples, 2 CPUs for the multi ones
  • vcs: sim_server/sw_client/read_write and sim_server/sim_client/axi_4state/multi (2 CPUs)
  • zebu: emu_server/sw_client/read_write, reusing its database unless the SV sources changed (then skipped, -z builds it); the host code is rebuilt alone when the C sources changed

example/sw_server/sw_client/bench/run measures the client/server library (SW, about 15 s): latency of a round trip, throughput of a stream, cost of a pull with no data.

available modules

available platforms

Look at those files to have more info about those platforms:

channels

  • server simulation and client simulations communicate through channels
  • channels direction can be client->server or server->client
  • each simulation can use multiple channels
  • multisim modules need a unique server_name to link a client/server channel together
  • client modules need to set server_runtime_directory to know the port/ip address of each channel
  • a client on the host of the server connects through a Unix socket (in .multisim/), a client on another host through TCP
  • the pull modules call their DPI at every cycle while no data comes: their DPI_DELAY_CYCLES_INACTIVE/DPI_DELAY_CYCLES_ACTIVE parameters space the calls (faster idle simulation, more latency), e.g. 1000 cycles cuts the idle cost of a VCS client by 75%

ZeBu

# optional site settings
export MULTISIM_ZEBU_SETTINGS=site.utf  # UTF sourced by the zCui project (grid_cmd, clock_config...)
export MULTISIM_ZEBU_LAUNCHER="srun --emu-work-dir ./zcui.work/zebu.work"  # zRci prefix, books an emulator

cd example/emu_server/sw_client/core
./compile -e zebu
./output/run
# or all the examples
cd example/emu_server && ./run_all.sh -e zebu
  • define MULTISIM_ZEBU instead of MULTISIM_EMULATION in SV and C/C++ compilation
  • server_name must be a string literal of at most 512 characters
  • the server modules are ZEMI3 transactors, see example/emu_server/zebu for the zCui project and the zRci script

4-state support

By default, multisim uses 2-state logic (0 and 1).

However 4-state logic (0, 1, X and Z) can be used by using the parameter DATA_IS_4STATE.
See the axi_4state example

4-state logic:

  • is currently not supported in EMULATION
  • doubles the amount of bytes exchanges over TCP/IP sockets

compilation

  1. source env.sh
  2. pass the right files to your simulator:

shared objects

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.cpp

Look in the example directory for more examples.

end of simulation

You can either:

  • use the helper function $MULTISIM_SRC/bin/kill_all_clients to 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

⚖️ Pros and Cons

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 ⚠️: transactionally accurate, but not cycle accurate
  • harder debug: waveforms split on N+1 simulation, no time coherency in between them

🚀 Future

  • simple transaction logging to help debug

About

SV/DPI library allowing multiple simulations/platforms to run in parallel and communicate

Topics

Resources

Stars

17 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages