kernel panik icon

How to run your own Verilog on roboRIO



Github repo: https://github.com/fpga4roborio/lv-adder

1. What is roboRIO?

(Feel free to skip this if you already know about it. This section is aimed at non-FRC people who somehow got access to a roboRIO and want to run some Verilog on it)

roboRIO 1.0

From WPILib's docs:

The roboRIO is a reconfigurable robotics controller that includes built-in ports for inter-integrated circuits (I2C), serial peripheral interfaces (SPI), RS232, USB, Ethernet, pulse width modulation (PWM), and relays to quickly connect the common sensors and actuators used in robotics. The controller features LEDs, buttons, an onboard accelerometer, and a custom electronics port. It has an onboard dual-core ARM real-time Cortex‑A9 processor and customizable Xilinx FPGA.

So basically it:
 - Is a Xilinx Zynq-7000 based board for controlling FRC robots,
 - Uses Zynq Z-7020 SoC (exact part name xc7z020clg400-1 for roboRIO 1.0 and something like xc7z020clg400-2 (higher clock) for roboRIO 2.0)
 - Runs NI Realtime Linux (kernel version 4.14)
 - Is primarily programmed via C/Java (using WPILib, without direct access to FPGA) or LabVIEW (less commonly used, but can access FPGA).
For more details on roboRIO's specifications, see roboRIO 1.0's spec and RoboRIO 2.0's spec.
This post will mainly focus on roboRIO 1.0 (because I only have that version for now), but steps may be replicated on roboRIO 2.0 with minimal modifications and equal success.

2. Why using roboRIO as an FPGA?

So why one may want to use roboRIO as an FPGA? Can't they just buy a proper that is designed for that purpose for a easier life? Well:
 - FIRST (the organization responsible for FRC and FTC) has issued a request for proposal of new robot control system that included requirements like . CPU – 64 bit (ARM64, 64-bit RISC-V, or x86-64), 1GHz+, Dual core. Quadcore preferred or RAM – 4GB minimum, at least 3GB available to user code. 8GB+ preferred. which current roboRIO versions cannot fulfill and may soon be deprecated. At that point, instead of throwing them away, people might want to reuse them as a normal FPGA (maybe for learning some FPGA).
 - Some Zynq-7020 based board might lying around on the internet, ranging from $85 to over $340 (I have seen crazier prices like over $4000 or even just $32). But for someone who already got a roboRIO (maybe from their FRC team) like me, they probably don't need to buy another FPGA.
 - RoboRIO has strong built-in protection for electrical faults (at least from my perspective). It's probably required to withstand these faults to some degree, since it's designed for students to use (and of course they tend to make electrical mistakes).
 - Some people might love LabVIEW (I personally don't, but maybe someone will do). RoboRIO support LabVIEW from its first day.
Whatever your reasons are, if you want to run your own FPGA logic on your roboRIO, this post is for you!

3. Installing softwares

It will takes you a day! So prepare your time. You might keep your computer running and go to sleep.

Recommened environment: Windows 10+

3.1. Installing Xilinx Vivado

You will need the EXACT VERSION of Vivado 2021.1 for NI LabVIEW 2023 & 2024 (that version may change in the future, so please check yourself). Otherwise there will be compatiblity problems with LabVIEW (I tried and failed, so you won't want to). For more information, see this.
Download that version from this page and install it.
The installer is pretty straightforward, but the installation may take a few hours to run.
When it comes to components selection, just select to install Vivado, and untick all other options except for Zynq-7000 series. You will need about 60GB of free disk space for that configuration.

3.2. Installing NI LabVIEW and roboRIO support packages

You will need to install NI Package Manager. Then open it up, and install the following packages (in exact order):

Package name Package image Package details Notes
FRC Game Tools FRC Game Tools
LabVIEW Software for FRC LabVIEW Software for FRC LabVIEW Software for FRC packages Note the installed LabVIEW version at bitness on your computer after installing this package.
LabVIEW and Drivers LabVIEW and Drivers LabVIEW and Drivers details Select the LabVIEW version and bitness you noted in the previous package installation.

4. Use Vivado to synthesize your IP module

In this post, we try a simple 8-bit adder in Verilog:

`timescale 1ns / 1ps

module Adder(

    input          clk,
    input           cEn,
    input          aReset,
    input          [7:0] dataInA,
    input          [7:0] dataInB,
    output reg  [7:0] dataOut
    
    );

always @ (posedge clk)

begin

    if(aReset)
        dataOut <= 0;
    else
        begin
            if (cEn)
                dataOut <= dataInA + dataInB;
        end 
        
end         

endmodule

First, open Vivado, then create a project:


New project: create new project

Give it a name and a working directory:


New project: new project name & directory

Select project type:


New project: select project type

Select your FPGA part name. roboRIO 1.0 (the version with LabVIEW text on its cover) has part name of xc7z020clg400-1 and roboRIO 2.0 has part name of xc7z020clg400-2 (need more confirmation on roboRIO 2.0 part name)


New project: select FPGA part name

Finally, click Next and then Finish to create the project:


Project created

Click on Add Sources, then select Add or create design source and click Next:


Add our Verilog code

Click on Create File, then set language type and file name:


Create Verilog file

Click on Ok, then Finish, then you have your new Verilog file opened in the editor:


Verilog file

Paste the Verilog code in, then click save


Verilog file

Click on Settings -> Synthesis -> More Options then fill in -mode out_of_context. This is required for calling Verilog code from VHDL, since LabVIEW only support VHDL import. You may choose to use VHDL from the starting point, but this post will follow Verilog. After that, click Apply and then OK.


Change settings

Next, run synthesis:


Run synthesis Run synthesis

Wait until you see this dialog, then select Open Synthesized Design and click on OK


Open synthesis

Using the same Add Sources process, add a VHDL file named AdderWrapper


Add VHDL file

Fill this in the Define Module dialog:


Define module

Open the file AdderWrapper file and then paste this VHDL code in and then save:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 07/14/2024 01:29:22 PM
-- Design Name: 
-- Module Name: AdderWrapper - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity AdderWrapper is
    Port ( clk : in STD_LOGIC;
           cEn : in STD_LOGIC;
           aReset : in STD_LOGIC;
           dataInA : in STD_LOGIC_VECTOR (7 downto 0);
           dataInB : in STD_LOGIC_VECTOR (7 downto 0);
           dataOut : out STD_LOGIC_VECTOR (7 downto 0));
end AdderWrapper;

architecture Behavioral of AdderWrapper is

component Adder 
    port ( clk : in STD_LOGIC;
           cEn : in STD_LOGIC;
           aReset : in STD_LOGIC;
           dataInA : in STD_LOGIC_VECTOR(7 downto 0);
           dataInB : in STD_LOGIC_VECTOR(7 downto 0);
           dataOut : out STD_LOGIC_VECTOR(7 downto 0));
end component;

begin

Adder_x : Adder 
    port map (
        clk => clk,
        cEn => cEn,
        aReset => aReset,
        dataInA => dataInA,
        dataInB => dataInB,
        dataOut => dataOut);

end Behavioral;

Work on Vivado is done now. Now you can switch to LabVIEW side.


Open NI LabVIEW 2023 Q3 (32-bit):


LabVIEW main menu

Create a blank project:


LabVIEW create project LabVIEW blank project

Add roboRIO target:


LabVIEW add target LabVIEW add target

Set roboRIO IP by right click on Project, then Properties -> General -> IP address:


LabVIEW add target

Add FPGA target by right click on Chassis (roboRIO), then New -> FPGA Target:


LabVIEW add FPGAs

Add CLIP (Component-level IP) by right click on FPGA Target (RIO0, roboRIO) -> Component-Level IP -> New:


LabVIEW add CLIP

Configure the next page as follow:


LabVIEW add CLIP

After that, click Check Syntax on the next page, then just Next until the process finishes. Then click OK.


LabVIEW add CLIP

Add CLIP by right click on FPGA Target -> New -> Component-Level IP.


LabVIEW add CLIP

Select AdderWrapper and the 40MHz clock. You can create derived clock from that 40MHz clock if you want to.


LabVIEW add CLIP LabVIEW add CLIP

Add FPGA VI.vi to the project.


LabVIEW add LV file

After that, just right click on roboRIO target, click on Connect to connect to target.


LabVIEW connect to target

Select Run on the FPGA VI.vi file. Then it will ask you to compile the FPGA code. Select local compile server, then let it run.


LabVIEW compile FPGA file

After the compilation is done, click on close. Then ssh to roboRIO (by ssh admin@[ip]) then rename the default WPILib lvbitx file:

NI Linux Real-Time (run mode)

Log in with your NI-Auth credentials.

admin@roboRIO:~# cd /usr/local/frc/bitfiles/
admin@roboRIO:/usr/local/frc/bitfiles# ls
roboRIO_FPGA_2024_24.0.0.lvbitx
admin@roboRIO:/usr/local/frc/bitfiles# mv roboRIO_FPGA_2024_24.0.0.lvbitx roboRIO_FPGA_2024_24.0.0.org.lvbitx
roboRIO_FPGA_2024_24.0.0.org.lvbitx
admin@roboRIO-6520-FRC:/usr/local/frc/bitfiles#

Select Run on the FPGA VI.vi file. Finally, you have the adder:


LabVIEW run

Reference:
https://fpganow.com/index.php/2018/04/03/labview-fpga-microblaze-and-uart-full-guide/
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000x4G6CAI
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000x0jiCAA