zeroasiccorp / switchboard

Communication framework for RTL simulation and emulation.
https://zeroasiccorp.github.io/switchboard/
Apache License 2.0
262 stars 20 forks source link

Single netlist mode #223

Closed sgherbst closed 5 months ago

sgherbst commented 5 months ago

This PR adds "single netlist" mode, where an SbNetwork can be simulated in a single Verilator or Icarus simulator instance. This is accomplished by generating Verilog code that implements the network that is specified by .connect() and .external() statements.

Prerequistes

morty

Single netlist mode currently requires morty for Verilog processing, which adds a unique suffix to module definitions used by each unique SbDut. To see why this is necessary, suppose that the network contains two SbDuts, each using an RTL module called memory with different implementations. When a single netlist is constructed, the module definitions for memory will conflict. (This is not a problem outside of single-netlist mode, since the two SbDuts are compiled separately)

To install morty:

  1. Install Rust if you don't have it already:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. Install morty (will take a few minutes)

    cargo install --git https://github.com/pulp-platform/morty.git
  3. Check if morty is in the path: which morty. If nothing is returned, add $HOME/.cargo/bin to the path.

In the future, we can explore packaging morty with switchboard, or solving this problem another way.

Update packages

The lambdalib version needs to be updated for the example below to work, and this update is included in examples/requirements.txt. Please run

pip install -r examples/requirements.txt

Testing the PR

cd into examples/network and run ./test.py --single-netlist (or ./test.py --tool icarus --single-netlist). If you're curious, you can see the generated Verilog code in build/testbench-*/testbench.sv.

Enabling single netlist mode is just a matter of setting SbNetwork(..., single_netlist=True) or including --single-netlist as a command-line option if cmdline=True has been set. However, there is a caveat, which is that SbDuts used in the network must have autowrap=False and subcomponent=True

To make it easier to define SbDuts that can be used in either single-netlist mode or distributed mode, this PR provides a new method, SbNetwork.make_dut(), that automatically fills in autowrap and subcomponent based on whether single netlist mode is being used. It also passes through command-line arguments automatically. make_dut accepts the same arguments as the SbDut constructor.

If you take a look at examples/network/tests.py, you can see usage examples for make_dut: it just replaces the SbDut constructor where it was being used before.

https://github.com/zeroasiccorp/switchboard/blob/c26ed38323e1b63bbd7d29844e1616a7808a3c48/examples/network/test.py#L170-L171

Future work