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())
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
In [3]:
with open("build/main.v", "r") as f:
print(f.read())
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