The FPGA Chronicles: Open Source It


Last time, we looked at getting started with the GOWIN tools and a Tang Nano 20K FPGA. The software program from GOWIN isn’t unhealthy, however it isn’t open supply, and there are a number of oddities about it. In addition, simulation is thru a third-party simulation package deal that has undergone some adjustments since an acquisition. There are tons of free simulation applications which can be extraordinarily good, and there may be an open-source toolchain for the FPGA.

You may go seize the whole lot you want piece by piece. But you don’t must. There are a number of efforts to supply a toolchain from all of the totally different items. We’re going to have a look at APIO.

APIO

APIO isn’t a lot an FPGA toolchain challenge as it’s an aggregator of toolchain initiatives. It reminded us of PlatformIO, and notes that it was impressed by it. It updates the instruments you want, consists of its personal libraries, and provides you a standard workflow throughout the FPGAs it supports.

You can download it for the command line, however it’s also possible to set up it as a Visual Studio Code extension, which is what I did. You must create a easy file that describes your challenge, and that’s about it.

Install Problems

Since APIO has its personal libraries, it’s doable that you will see some conflicts together with your system libraries. In my case, the libreadline.so.8 file (in ~/.apio/bin/_internal) was inflicting issues that prevented something from working. I merely renamed it out of the way in which, or you possibly can simply delete it. That took care of the issue.

Keep in thoughts that APIO simply orchestrates a bunch of different instruments like Yosys and GTKWave. Even when you have your personal variations, APIO expects to make use of its personal copies. For instance, GTKWave on my system is a unique model than the APIO copy, and if I attempt to learn wave recordsdata with out utilizing APIO, I get error messages. You can, nonetheless, open a shell from the Tools/Misc menu of the APIO panel in Visual Studio Code.

The APIO Project File

I made a easy LED-blinking design to check APIO. We’ll discuss extra in regards to the Verilog within it subsequent time, however for now, you possibly can deal with it as a black field. Each APIO challenge wants an apio.ini file. Here’s mine:

[env:default]
board = sipeed-tang-nano-20k
top-module=led

That’s it. Of course, you can do more. But you don’t usually want any greater than this. However, you’ll see on the finish of this submit that I often add a bit extra to this bare-bones challenge.

You can use the apio create command to start out a challenge, when you like. You can set choices to set the board, the highest module, and the trail. However, there doesn’t appear to be a straightforward approach to run that from inside Visual Studio Code. The finest approach I’ve discovered is to open the APIO panel, click on on Tools, after which APIO Shell. From there, you possibly can run apio create with the arguments: use apio create -h to see what you possibly can and should specify.

Win Some, Lose Some

A big camp of individuals will ask, “Why did you utilize the GOWIN instruments in any respect if this exists?” Another camp asks, “Why hassle with this when the GOWIN instruments work simply fantastic?” Turns out, there are causes you may select one over the opposite.

The open-source instruments are glorious in the case of Verilog. With APIO, you possibly can format your supply code and verify it for correctness utilizing a classy linter. Then there’s simulation. APIO has an excellent driver for simulating designs with highly effective instruments.

The GOWIN instruments are fantastic. The simulator, nonetheless, is tied to a simulator that seems to now not be accessible in the way in which they’re utilizing it. That could change, after all, however nice open-source instruments exist, and APIO makes them trivial to make use of.

A spreadsheet for creating constraints

So why use GOWIN? If you wish to use their IP (operate blocks that do issues as mundane as producing a clock or as complicated as making a CPU), you will see it troublesome to combine these with APIO, though in all probability not not possible. There’s additionally a facility that may add a logic analyzer into your design so you possibly can look at issues at runtime. That isn’t simply adaptable to APIO both. There are some open ways to do similar things, however they aren’t as neat because the built-in instruments.

You additionally lose the great GUI constraints editor: the factor that permits you to outline what pins correspond to what Verilog names. That’s a small drawback, as a result of you possibly can simply write your personal constraint recordsdata as textual content. Or you should use this spreadsheet I built to make it a little easier, or go to GitHub for a lightly-tested Excel model. Just save your personal copy and edit it. If you favor utilizing Visual Studio Code, do that constraint editor extension.

There is one different problem. Which synthesis instrument does a greater job? That’s onerous to say with out testing and, even then, one could excel in a single space and fall behind in one other. Do you need sooner efficiency? Lower useful resource utilization? Access to all of the particular machine sources? The solely approach to know for certain is to attempt each. Keep in thoughts that APIO itself doesn’t do the Verilog synthesis or place and route. Other comparable toolchain aggregators exist, however they usually use the identical instruments, so selecting one over the opposite gained’t materially change the top end result.

Example for Open Source

You can download the example files. For now, I wish to deal with utilizing APIO as an alternative of the main points of the Verilog. This design makes use of a 27 MHz clock. There are a number of methods to get a clock like this into the FPGA. However, clocks are a particular sort of sign to FPGAs, and most of them, together with ours, have particular pins that work finest as clocks.

Since we gained’t look “contained in the field” this time, right here’s the important thing a part of the led prime module:


module led #(
    parameter integer CLOCK_FREQUENCY = 27_000_000,
    parameter integer INTERVAL_MS     = 500
) (
    enter wire reset,
    enter wire Clock,
    enter wire serialin,
    enter wire pushbtn,
    output wire [5:0] leds,
    output wire serialout
);

This lets the module anticipate a sure clock frequency and a sure blink price. There are inputs for reset, Clock, serialin, and pushbtn. There are additionally outputs for the LEDs and serialout. (We’re not utilizing the serial or pushbuttons for this text.)

Programming the Clock

When you plug within the Nano 20K, it is best to get a serial port. On Linux, attempt ls -l /dev/serial/by-id to determine it out. If you open that together with your favourite serial terminal program, you’ll in all probability see… nothing. That’s as a result of the FPGA isn’t sending or receiving something.

The TangNano20K menu

However, the serial port goes by way of a microcontroller, the identical one which flashes the FPGA. It is at all times looking forward to a particular enter character sequence ^X^C [Enter]. That ought to provide you with a “TangNano20K />” immediate. If you think your model may be outdated, you possibly can replace it utilizing Sipeed’s instructions. Make certain you decide the proper firmware from the desk, as there are comparable variations you possibly can flash that look newer however are incompatible.

The board has a number of clocks you possibly can program. We will use O0, which is on FPGA pin 10. So as soon as you might be on the immediate, you possibly can kind:


pll_clk O0=27M -s

If you wish to verify the standing, you possibly can simply use pll_clk with no arguments. We don’t use the UART in the mean time, however when you did, “select uart” would put it again in regular mode.

Go forward and download the straightforward LED challenge, open Visual Studio Code, and, when you haven’t already, use the extensions market to put in the APIO extension. You’ll have the ability to open the challenge.

From the APIO panel, you possibly can open the “make” instructions and choose “construct.” Once that works, you should use “add” to ship the file to the machine’s flash, by default. APIO behaves like Make. That is, when you add and the supply adjustments, it rebuilds.

Instead of flashing the machine each time, I needed to program to SRAM by default. APIO helps environments, so I modified my ini file to appear like this:


[apio]
default-env = ram

[common]
board = sipeed-tang-nano-20k
top-module = led

[env:ram]
programmer-cmd = openFPGALoader -b tangnano20k ${BIN_FILE}

[env:flash]
programmer-cmd = openFPGALoader -b tangnano20k -f ${BIN_FILE}

Now, by default, the obtain goes to SRAM. I can’t discover a approach to make the Visual Studio Code extension swap environments, nonetheless. To flash, you’ll must open the APIO shell and run:


apio add --env flash

One different small level. I usually wish to disable recordsdata that I exploit for simulation or debugging, and the GOWIN IDE helps that. For instance, I might need three copies of a module which have totally different debugging outputs. Unfortunately, there’s no straightforward approach to try this utilizing APIO. The finest I’ve discovered is to rename recordsdata like foo.v and foo-test.v to foo.v.possibility and foo-test.v.possibility. Then you possibly can hyperlink foo.v to both one and will even script that simply, when you like. Or simply rename them each time, which can be straightforward to script.

Testing, One, Two…

It is good to check your designs earlier than you set them on actual {hardware}. It is commonly a lot simpler to debug issues when you possibly can see the whole lot and arrange particular circumstances for the take a look at. The approach to try this is to create a testbench. This is a Verilog file that drives the “actual” Verilog and generates some output.

In an everyday Verilog file, you must watch out to solely do issues the synthesizer can fairly do on the FPGA. If you do one thing improper, it is going to generally refuse. Sometimes, although, it is going to simply generate horrible outcomes that you simply don’t really need. But in a testbench, you are able to do numerous issues like delays. The simulator is extra like a software program simulation of parallel execution, so it’s rather more forgiving.

Here’s a easy testbench that we are going to revisit in a later installment. For now, it’s already within the challenge.

 `timescale 1ms/1us
// every "tick" is value 1ms so #100 == 0.1 second delay

`default_nettype none

module led_tb;
    reg clk;
    reg reset;
    wire [5:0] leds;
    wire serialout;
// create prime block for testing
    led #(
        .CLOCK_FREQUENCY(10),  // however inform it to anticipate 10 Hz
        .INTERVAL_MS(1000)
    ) uut (
        .reset(reset),
        .Clock(clk),
        .serialin(1'b0),
        .pushbtn(1'b0),
        .leds(leds),
        .serialout(serialout)
    );

// generate simulation clock
    preliminary start
        clk = 0;
        perpetually #50 clk = ~clk;
    finish

// simulation "foremost"
    preliminary start
        $dumpvars(0, led_tb);  // retailer variables
        reset = 1;             // generate a reset pulse
        #200;
        reset = 0;
        #50000                 // let simulation run for a bit
        $end;               // exit
    finish

endmodule

Here’s the fundamental thought: We create the highest module of our design (led), however we wire it to run at 10 Hz with a 1-second interval. You may simulate at 27 MHz, however it could create enormous recordsdata which can be tougher to work with. At the beginning of the simulation, we generate a clock change each 50 milliseconds, so the interval is 100 milliseconds (10 Hz).

The final preliminary block additionally operates originally. It first units the variables we wish to dump. If you have a look at different tutorials otherwise you’ve accomplished this earlier than, you may marvel the place $dumpfile is. APIO likes to set that itself. It additionally insists that you simply title the file something_tb.v (or _tb.sv in case you are utilizing SystemVerilog). You can change the one thing half, however it has to finish with that sample for APIO to choose it up.

Simulation output reveals all of it.

If you don’t embody $dumpvars, you’ll get an empty simulation file. Then there’s a short reset sign. Then we wait a very long time (#50000 is 50 seconds right here, however the simulator will run that a lot sooner, so that you gained’t have to attend). Then there’s a name to $end. Without that, the simulator will run perpetually.

Once you’ve gotten this file in place, you possibly can open the APIO confirm and choose “sim.” The result’s a pleasant graphic view in GTKWave. You can add extra alerts from deeper down within the hierarchy.

Usually, it’s fairly straightforward to put in writing your personal testbench. However, individuals have tried to automate the job with various levels of success. Years in the past I forked one such tool and made some changes however it’s not onerous to discover a Verilog file it is not going to parse. You may additionally ask your favourite LLM to do it. In reality, I requested ChatGPT to do one, and it produced one nearly similar to the one above, aside from a number of the time decisions.

You can see a demo of the simulation within the video under.

Unreal

Of course, the simulation solely will get you to this point. If you wish to probe the design stay, you are able to do that too with the GOWIN instruments. We’ll be taking a look at that sooner or later. Next time, we’ll look extra at how this demo works and add some necessary options to it.

We additionally want to speak about issues like metastability, debouncing switches, and crossing clock domains. Fun stuff. But between this and the earlier submit, this could sq. you away on toolchains for now. Drop by the Discord and keep tuned for the following installment.



Source link