Developing FPGA under linux

Posted by Brian Swan on Sun, 30 Jan 2022 07:03:02 +0100

For more sharing, please visit my personal blog

https://www.niuiic.top/

This paper introduces how to develop FPGA under linux.

compiler

Due to the particularity of FPGA, only commercial ides can be competent for the whole development process. Therefore, there is no need to find open source alternative products. It is most appropriate to directly use the IDE provided by the development board manufacturer. If the manufacturer does not develop IDE, you can use more commonly used ide such as vivado.

Although we use IDE, we only use it to compile and download. Other tools are recommended for simulation and editing. The reason is that at present, no FPGA IDE can provide a good editing experience. In addition, the simulation speed of IDE like vivado is really a little slow.

editor

Under linux, it is recommended to use vim/neovim or emacs for editing. Step back and choose vscode.

For the configuration of system Verilog by vim/neovim, see Another article.

simulator

Use gtkwave as the waveform viewer.

Users using verilog/VHDL can choose to use iverilog as the emulator.

The simulation speed of iverilog is acceptable, and I feel it is much faster than vivado. As for the usage of iverilog with gtkwave, you can find it only by searching on the Internet. This article will not repeat it.

System Verilog users recommend using verilator. The reason is that the support of iverilog for system Verilog is still not very good. In addition, verilator is much faster. It claims to be the fastest simulator in the world.

verilator converts system Verilog into C + + model and uses multithreaded C + + for simulation. Therefore, its speed is very fast, but also because of this principle, users need to write test files in C + +.

Let's look at a case.

// Demo.sv

module Demo ();
  initial begin
    $display("Hello World");
    $finish;
  end
endmodule

The above codes do not produce waveforms. Next, write the corresponding simulation test file.

// sim_main.cpp

#include "VDemo.h"
#include <fstream>
#include <iostream>
#include <verilated.h>
#include <verilated_vcd_c.h>
using namespace std;

// top object pointer
VDemo *top = nullptr;
// wave generation pointer
VerilatedVcdC *tfp = nullptr;

// simulation timestamp
vluint64_t main_time = 0;
// upper limit of simulation timestamp
const vluint64_t sim_time = 1024;

int main(int argc, char **argv) {
  // init
  Verilated::commandArgs(argc, argv);
  Verilated::traceEverOn(true);
  top = new VDemo;
  tfp = new VerilatedVcdC;
  top->trace(tfp, 99);
  tfp->open("VDemo.vcd");

  while (!Verilated::gotFinish() && main_time < sim_time) {
    // simulation time step in
    top->eval();
    // wave output step in
    tfp->dump(main_time);
    main_time++;
  }

  // clear sources and exit
  tfp->close();
  delete top;
  delete tfp;
  exit(0);
  return 0;
}

The above code gives a standard template. The syntax is very simple. You can write it with a little C + + foundation.

The following describes the simulation test.

  1. Where does the header file of the emulator come from

Use verilator -- CC demo SV -- trace can generate an obj_dir directory. This directory contains cpp files converted from systemverilog. In addition, there are a series of general header files in the installation directory of verifier, usually under / usr / share / verifier / include. In addition, it is the file of cpp standard library.

  1. How to use the program

Execute the command verilator -- CC demo sv --trace --exe sim_ main. cpp && make -j $(nproc) -C ./ obj_ dir -f VDemo. mk VDemo.

( n p r o c ) surface show meter count machine of most large Line Cheng number . than as 4 nucleus 8 Line Cheng , be by − j 8 . Should set up Set by Cheng order Compile translate Time send use of Line Cheng number , build Discuss set up Set by (nproc) indicates the maximum number of threads on the computer. For example, 4-core 8-thread is -j 8. This setting is the number of threads used during program compilation. It is recommended to set it to (nproc) indicates the maximum number of threads on the computer. For example, 4-core 8-thread is − j8. This setting is the number of threads used during program compilation. It is recommended to set it to (nproc), which can be reduced, but it is better not to increase.

The above command will generate an executable file, obj_dir/VDemo.

Run this file to see the output. If there is a waveform in the simulation, the waveform obj will be output_ dir/VDemo. vcd. Then use gtkwave obj_dir/VDemo.vcd to view the waveform.

  1. How to configure signals

The above systemverilog code does not set the port or signal. Now suppose there is input clk, output logic out, and assign out = clk;.

All signals can be accessed through the top pointer, such as top - > CLK. Next, change the while statement to the following.

  while (!Verilated::gotFinish() && main_time < sim_time) {
    top->clk = top->clk == 0 ? 1 : 0;
    // simulation time step in
    top->eval();
    // wave output step in
    tfp->dump(main_time);
    main_time++;
  }

The clk signal can be simulated.

As for the writing method of simulation test files, there are many case files in the installation directory of verifier (usually / usr / share / verifier / examples).

Optimize simulation process

Simulation process is the top priority of the whole development process. Here are some tools to improve the simulation experience.

Make a script to initialize the project.

sourcefile="demo.sv"
exe="Vdemo"
simfile="sim_main.cpp"
buildcmd="verilator --cc $sourcefile --trace"
runcmd="verilator --cc $sourcefile --trace --exe $simfile && make -j $(nproc) -C ./obj_dir -f $exe.mk $exe"

if [ $1 == "run" ]; then
    eval $runcmd &>/dev/null
    cd ./obj_dir
    eval "./$exe"
    if [ -f "wave.vcd" ]; then
        gtkwave "./$exe.vcd"
    fi
elif [ $1 == "build" ]; then
    eval $runcmd
elif [ $1 == "check" ]; then
    eval $buildcmd
elif [ $1 == "clean" ]; then
    if [ -d "obj_dir" ]; then
        rm obj_dir
    fi
elif [ $1 == "watch" ]; then
    if [ -f "wave.vcd" ]; then
        cd ./obj_dir
        gtkwave "./$exe.vcd"
    else
        echo -e "\033[31mNo vcd file exists.\033[0m"
    fi
elif [ $1 == "init" ]; then
    project_path=$(pwd)
    eval $buildcmd
    cat >compile_commands.json <<EOF
[
  {
    "directory": "$project_path",
    "command": "g++ $simfile -I ./obj_dir -I /usr/share/verilator/include -I /usr/share/verilator/include/*",
    "file": "./$simfile"
  }
]
EOF
    cat >$simfile <<EOF
#include "$exe.h"
#include <fstream>
#include <iostream>
#include <verilated.h>
#include <verilated_vcd_c.h>
using namespace std;

// top object pointer
$exe *top = nullptr;
// wave generation pointer
VerilatedVcdC *tfp = nullptr;

// simulation timestamp
vluint64_t main_time = 0;
// upper limit of simulation timestamp
const vluint64_t sim_time = 1024;

int main(int argc, char **argv) {
  // init
  Verilated::commandArgs(argc, argv);
  Verilated::traceEverOn(true);
  top = new $exe;
  tfp = new VerilatedVcdC;
  top->trace(tfp, 99);
  tfp->open("$exe.vcd");

  while (!Verilated::gotFinish() && main_time < sim_time) {
    // simulation time step in
    top->eval();
    // wave output step in
    tfp->dump(main_time);
    main_time++;
  }

  // clear sources and exit
  tfp->close();
  delete top;
  delete tfp;
  exit(0);
  return 0;
}
EOF
fi

Note: check the compile in the init branch_ commands. Location of header file in JSON content / usr / Is it correct.

When using, you can modify sourcefile, simfile and exe. Note that the directory where the script is executed is obj_dir is the same as the directory. The functions of each part are described below.

  1. init: put the simulation test file SIM into the current directory_ main. cpp and compile required by cpp lsp_ commands. JSON (used for cpp code checking, syntax completion, etc.).
  2. Run: compile and run, and use gtkwave to open the waveform diagram.
  3. build: compile and check whether there are errors in the source file and simulation test file.
  4. Check: check the source file for errors.
  5. Clean: clean.
  6. watch: view the waveform diagram.

Further, users using vim can refer to Another article , combine the above contents with VIM quickfix and asynctasks to complete the whole simulation process with shortcut keys.

summary

According to the above contents, clarify a process of developing FPGA under linux.

  1. Create a project using the IDE.
  2. Write code using an external editor.
  3. Use an external simulator to simulate.
  4. Use the IDE to do the rest.

advantage

  1. Good editing experience.
  2. Fast simulation speed.
  3. Due to the underlying principle of linux, vivado runs much faster on linux than on windows. If you want to further improve the speed of vivado, you can use multithreading and incremental compilation, which can be found on the Internet.

Topics: Linux FPGA systemverilog