fud: The Calyx Driver

Working with Calyx involves a lot of command-line tools. For example, an incomplete yet daunting list of CLI tools used by Calyx is:

  • All the Calyx frontends.
  • Calyx compiler and its various command line tools
  • Verilator, the Verilog simulation framework used to test Calyx-generated designs.
  • Waveform viewers to see the results of simulation

fud aims to provide a simple interface for using these toolchains and executing them in a pipeline. The source for fud is here.


Fud requires Python 3.9 or higher to work correctly.

fud currently has a dependency on calyx-py, which you need to install first.

You need Flit to install fud. Install it with pip3 install flit.

You can then install fud with

cd fud && flit install

(If using this method to install fud, pip3 should be version >= 20)

If you are working on fud itself, you can install it with a symlink with:

cd fud && flit install --symlink

You can also install fud with

flit build
pip3 install dist/fud-0.3.0-py3-none-any.whl

Finally, point fud to the root of the repository:

fud config global.root <full path to Calyx repository>


Fud uses a global configuration file to locate tool paths and default values. To view the configuration, use fud c or fud config.

Check. Fud can automatically check if your configuration is valid and can help you set certain variables. Perform this check with:

fud check

Viewing keys. To view the current value of a key, use fud config key. For example, the following shows the path to the Calyx compiler.

fud config stages.calyx.exec

Updating keys. Keys can be updated using fud config key value. For example, the following command updates the path to the Calyx compiler.

fud config stages.calyx.exec ./target/debug/calyx

Adding Backends

fud wraps both frontends and backends for Calyx. For a useful fud installation, you need to configure the Verilator backend and accompanying tools.


We use the open source Verilator tool to simulate Verilog programs generated by the Calyx compiler. Install Verilator by following the official instructions. On macOS, you can use brew install verilator or, otherwise, compile from source:

git clone https://github.com/verilator/verilator
cd verilator
git pull
git checkout master
sudo make install

Run fud check to make sure you have the right version. We currently require >=v5.002 of Verilator with fud.

By default, fud will use the verilator executable to run Verilator. To use a different binary, configure the path by:

fud config stages.verilog.exec <binary>

Vcdump. Vcdump is a tool for converting vcd (Value Change Dump) files to JSON for easier analysis with the command line.

Install it with:

cargo install vcdump

Icarus Verilog

fud also supports Icarus Verilog as a simulation backend. Since Icarus Verilog interprets programs, it can often be faster than verilator. First install Icarus Verilog and ensure that iverilog and vvp are on your path. Next, register the icarus-verilog external stage with fud:

fud register icarus-verilog -p fud/icarus/icarus.py

To test the simulation backend, run:

fud e --to dat examples/tutorial/language-tutorial-iterate.futil -s verilog.data examples/tutorial/data.json --through icarus-verilog

Registering this stage will define multiple paths in the fud transformation graph between futil and the vcd and dat stages. If you'd like fud to default to verilog stage, give it a high priority:

fud c stages.verilog.priority 1

Dahlia Frontend

In order to use the Dahlia frontend with Fud, first install Dahlia. Once Dahlia is compiled, point fud to the Dahlia compiler binary:

fud config stages.dahlia.exec <full path to dahlia repo>/fuse

Python frontends (Systolic array, NTT, MrXL, TVM Relay)

You need flit to install our Python frontends.

pip3 install flit

Our Python frontends use a Calyx ast library written in Python. Install with:

cd calyx-py && flit install -s

Frontend specific instructions:

  • Systolic array: Nothing else needed.
  • NTT:
    • Install dependencies: pip3 install prettytable
    • Install external fud stage: fud register ntt -p frontends/ntt-pipeline/fud/ntt.py
  • MrXL:
    • Install mrxl binary: cd frontends/mrxl && flit install -s
    • Install mrxl external stage for fud: fud register mrxl -p frontends/mrxl/fud/mrxl.py
  • TVM Relay: See instructions.

Adding Synthesis Backends

fud supports wraps the Vivado (synth-verilog) and Vivado HLS (vivado-hls) tools to generate area and resource estimates for Calyx designs. See the instructions to configure them.

Working with Stages

Fud is structured as a sequence of stages that transform inputs of one form to outputs.

Stages. fud transforms a file in one stage into a file in a later stage. The --from and --to options specify the input and output stages to the fud exec subcommand. Use fud info to view all possible stages.

Guessing stages. fud will try to guess the starting stage by looking at the extension of the input file and output file (if specified using the -o flag). If it fails to guess correctly or doesn't know about the extension, you can manually set the stages using --to and --from.


Fud provides some very basic profiling tools through the use of the --dump_prof (or -pr) flag. You can get overall stage durations for a fud run by simply using -pr. For example,

  fud e examples/dahlia/dot-product.fuse --to dat \
  -s verilog.data examples/dahlia/dot-product.fuse.data \

will output:

stage                           elapsed time (s)
dahlia                          1.231
futil                           0.029
verilog                         4.915

If you want time elapsed for each step in a stage, you can also provide one or more stages after the flag. For example,

  fud e examples/dahlia/dot-product.fuse --to dat \
  -s verilog.data examples/dahlia/dot-product.fuse.data \
  -pr verilog

will output:

verilog                         elapsed time (s)
mktmp                           0.0
json_to_dat                     0.004
compile_with_verilator          5.584
simulate                        0.161
output_json                     0.003
cleanup                         0.003

If you want time elapsed for a single step, you can specify the given step, e.g.

  fud e examples/dahlia/dot-product.fuse --to dat \
  -s verilog.data examples/dahlia/dot-product.fuse.data \
  -pr verilog.simulate

will output:

verilog                         elapsed time (s)
simulate                        0.161

Lastly, the -csv flag will provide the profiling information in CSV format.