First, install Firrtl by following their installation instructions

Be sure to add the directory containing the firrtl command line tool (typically firrtl/utils/bin) to your $PATH

The FIRRTL backend for magma is experimental and woefully lacking in support for standard mantle circuits. The core functionality has been implemented to demonstrate the capability of compiling magma circuits to FIRRTL. Pull requests that expand support for the FIRRTL are welcome.


In [1]:
import magma as m
m.set_mantle_target("coreir")
import mantle

main = m.DefineCircuit('main', "a", m.In(m.Bit), "b", m.In(m.Bit), "c", m.In(m.Bit), "d", m.Out(m.Bit))
d = (main.a & main.b) ^ main.c
m.wire(d, main.d)
m.compile("build/main", main, output="firrtl")

with open("build/main.fir", "r") as f:
    print(f.read())


compiling main
circuit main :
  module main :
    input a : UInt<1>
    input b : UInt<1>
    input c : UInt<1>
    output d : UInt<1>
    
    wire inst0_out : UInt<1>
    wire inst1_out : UInt<1>
    inst0_out <= and(a, b)
    inst1_out <= xor(inst0_out, c)
    d <= inst1_out

Note: the ! syntax used in the next cell is jupyter notebook syntax sugar for executing a shell command


In [2]:
!firrtl -i build/main.fir -o build/main.v -X verilog


Total FIRRTL Compile Time: 1404.8 ms

In [3]:
with open("build/main.v", "r") as f:
    print(f.read())


module main( // @[:main.fir@2.2]
  input   a, // @[:main.fir@3.4]
  input   b, // @[:main.fir@4.4]
  input   c, // @[:main.fir@5.4]
  output  d // @[:main.fir@6.4]
);
  wire  inst0_out; // @[:main.fir@8.4 :main.fir@10.4]
  assign inst0_out = a & b; // @[:main.fir@8.4 :main.fir@10.4]
  assign d = inst0_out ^ c; // @[:main.fir@12.4]
endmodule


In [4]:
with open("build/sim_main.cpp", "w") as sim_main_f:
    sim_main_f.write("""
#include "Vmain.h"
#include "verilated.h"
#include <cassert>
#include <iostream>

int main(int argc, char **argv, char **env) {
    Verilated::commandArgs(argc, argv);
    Vmain* top = new Vmain;
    int tests[8][4] = {
        {0, 0, 0, 0},
        {1, 0, 0, 0},
        {0, 1, 0, 0},
        {1, 1, 0, 1},
        {0, 0, 1, 1},
        {1, 0, 1, 1},
        {0, 1, 1, 1},
        {1, 1, 1, 0},
    };
    for(int i = 0; i < 8; i++) {
        int* test = tests[i];
        int a = test[0];
        int b = test[1];
        int c = test[2];
        int d = test[3];

        top->a = a;
        top->b = b;
        top->c = c;

        top->eval();
        assert(top->d == d);
    }

    delete top;
    std::cout << "Success" << std::endl;
    exit(0);
}    
""")

Note: The %%bash statement is a jupyter notebook magic operator that treats the cell as a bash script


In [5]:
%%bash
cd build
verilator -Wall -Wno-DECLFILENAME --cc main.v --exe sim_main.cpp
make -C obj_dir -j -f Vmain.mk Vmain
./obj_dir/Vmain


clang++  -I.  -MMD -I/usr/local/Cellar/verilator/3.924/share/verilator/include -I/usr/local/Cellar/verilator/3.924/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=0 -faligned-new -fbracket-depth=4096 -Qunused-arguments -Wno-parentheses-equality -Wno-sign-compare -Wno-uninitialized -Wno-unused-parameter -Wno-unused-variable -Wno-shadow       -c -o sim_main.o ../sim_main.cpp
/usr/bin/perl /usr/local/Cellar/verilator/3.924/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include Vmain.cpp > Vmain__ALLcls.cpp
/usr/bin/perl /usr/local/Cellar/verilator/3.924/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include Vmain__Syms.cpp > Vmain__ALLsup.cpp
clang++  -I.  -MMD -I/usr/local/Cellar/verilator/3.924/share/verilator/include -I/usr/local/Cellar/verilator/3.924/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=0 -faligned-new -fbracket-depth=4096 -Qunused-arguments -Wno-parentheses-equality -Wno-sign-compare -Wno-uninitialized -Wno-unused-parameter -Wno-unused-variable -Wno-shadow       -c -o Vmain__ALLcls.o Vmain__ALLcls.cpp
clang++  -I.  -MMD -I/usr/local/Cellar/verilator/3.924/share/verilator/include -I/usr/local/Cellar/verilator/3.924/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=0 -faligned-new -fbracket-depth=4096 -Qunused-arguments -Wno-parentheses-equality -Wno-sign-compare -Wno-uninitialized -Wno-unused-parameter -Wno-unused-variable -Wno-shadow       -c -o Vmain__ALLsup.o Vmain__ALLsup.cpp
      Archiving Vmain__ALL.a ...
ar r Vmain__ALL.a Vmain__ALLcls.o Vmain__ALLsup.o
ranlib Vmain__ALL.a
clang++    sim_main.o verilated.o Vmain__ALL.a    -o Vmain -lm -lstdc++ 
Success