Program Your First FPGA With GOWIN GW1N-4

If you’re a software developer like me, you might be thrilled to see so many exciting embedded hardware platforms that we can now program easily, from Arduinos to the PADI IoT Stamp and the STM32 Blue Pill.

Today we’ll look at a totally different kind of gadget that’s now within our programming reach — FPGA or Field-Programmable Gate Array. But unless you’re a hardware engineer it’s hard to understand how an FPGA works and why it’s different from microcontrollers and CPUs (even though they are all made from the same semiconductor stuff).

GOWIN FPGA dev kit DK-START-GW1N4

Instead of learning FPGA theory, we’ll go hands-on with a real FPGA dev kit —GOWIN DK-START-GW1N4, based on the GW1N-4 FPGA (with 4K LUTs). As we learn how to program the FPGA, we’ll soon realise that FPGA programming is really extraordinary, unlike any other kind of programming we have done before.

Disclosure: I’m using an evaluation dev kit that was kindly loaned to me by GOWIN and Nexcomm Asia. This is not a sponsored product review, this is actually my very first exploration of FPGA tech stemming from my interest in IoT.


Designing Your FPGA

GOWIN (or 高云 in China) provides a simple tool, GOWIN YunYuan (云源), as the starting point for designing our FPGA. All the tools we need for FPGA programming are in that screen above. Before we dive into the code, let’s get familiar with some FPGA concepts…

Grid of logic modules in an FPGA. Colour lines represent connections between logic modules.
GOWIN Configuration Function Unit — Our FPGA connects (and reconnects) thousands of these logic modules together

Think of an FPGA as a two-dimensional grid of semiconductor modules with many rows and columns (our dev kit packs over 4,000 of such tiny modules).

Each logic module has very limited computing capability — counting numbers, adding and multiplying numbers (but not division because that’s too complex).

We have the power to connect (and reconnect) all 4,000 of such modules together to create something useful, like an IoT Sensor device or a video gaming console.

Thankfully we don’t need to connect the modules ourselves. All we need to do: Write some code using the Verilog language. The Verilog compiler converts our code into connections between the logic modules. Let’s look at a simple Verilog code module…

https://github.com/lupyuen/gowin-blink/blob/master/src/demo.v

Coding Your FPGA In Verilog

Take a moment to read through the above Verilog code (which looks like C). On an Arduino we write C programs that are compiled into CPU instructions. On the FPGA however, our Verilog programs are compiled into connections between many many logical semiconductor modules. Since FPGA operates at the logical hardware level, we will code using hardware concepts like…

Clocks at the logic level. Each row is a different Clock Signal.

Clock Signals: All computers (including microcontrollers and FPGAs) operate on very precise clock tick signals that alternate between high and low states at a fixed rate. That’s why we visualise the Clock Signal as a square wave, like you see in the screen.

In the Verilog code above, we use a Clock Signal named clk_50M. That’s because the GOWIN dev board includes a 50 MHz clock (crystal oscillator) that we may connect to the FPGA logic modules for performing timed operations.

Input / Output Signal Pins: On the Arduino we have digital input / output pins like D0, D1, D2, … that we may configure as input or output pins to interface with sensors and other peripherals. Our FPGA code uses the same concept of Input / Output Signal Pins (declared with the input and output Verilog keywords) to connect 4 LEDs and a reset switch.

Registers: If the Verilog code above were really a C program, we would expect variables like clk_50M to maintain their values in memory while the program was running. But with Verilog, the values are not saved in memory unless we declare them as Registers using the reg keyword.

Registers are 1 bit wide by default if we don’t specify the size. To declare led as a 4-bit Register, we use reg[3:0] led.

Connecting The FPGA Signal Pins

In the Verilog code, we have declared 3 Input / Output Signal Pins…

DK-START-GW1N4 dev kit. The GW1N-4 FPGA is at the top, with GPIO ports at the left and right. The bottom edge has 4 push buttons, 4 LEDs and 4 switches.

input clk_50M — To be connected to the 50 MHz clock on the dev board

input rst_n — To be connected to the Reset Button on the dev board

output[3:0] led — To be connected to the 4 LEDs on the dev board (see the photo)

The GOWIN dev board is remarkably dense with plenty of GPIO pins, LVDS pins (for connecting to high resolution displays), buttons, switches and LEDs. Each of these pins and components are wired to the 144 pins of the FPGA. In the schematic below we can see that the vast majority of the pins (labelled F_A_* and F_B_*) are allocated to the two GPIO ports.

The GW1N-4 FPGA wired to the onboard GPIO, LVDS, buttons, switches and LEDs
Arduino Uno Schematic. Pins PD0 and 1 are dedicated for Serial I/O. Pins PB2 to 5 are dedicated for SPI. From https://store.arduino.cc/usa/arduino-uno-rev3

Why do FPGAs have so many general-purpose pins? Because FPGAs can be used to build all kinds of hardware interfaces — I2C, SPI, UART / Serial, even HDMI for video processing. So we no longer need to dedicate specific pins for SPI and Serial ports like the Arduino. We are free now to configure as many ports as we wish, even multiple instances of the ports.

At the lower edge of the FPGA schematic above we can see 4 pins for LEDs: Pins 47, 57, 60 and 61. Here’s how we connect them to output[3:0] led

GOWIN FloorPlanner tool for connecting our Verilog ports to FPGA pins

With the GOWIN FloorPlanner tool we simply click the FPGA pin that we wish to connect to each LED port that was referenced in our Verilog code. We also connect clk_50M to Pin 6, which provides the 50 MHz clock signal, and rst_n to Pin 92, which changes its logic value when the board restarts or when the Reset Button is pressed.

These connections are also known as I/O Constraints. Remember that the FPGA tools will connect the logic modules for us in order to execute our Verilog code and make the LEDs flash. The LED Pins are located at the lower edge of the FPGA, so the tools will allocate logic modules near the lower edge to reduce the latency. In short, the location of the LED Pins actually imposes a constraint on the layout of the logic modules.

What Really Happens Inside The FPGA

After clicking the Synthesize and Place & Route functions in GOWIN YunYuan, we will get a “compiled FPGA program” — essentially a list of allocated logic modules, their locations in the FPGA grid, and how the modules are connected to one another and to the FPGA input/output pins. We can launch GOWIN FloorPlanner again to visualise the results:

  1. How the logic modules were allocated inside the FPGA
  2. The expected latency from the input (clock signal) to the output (LEDs)
  3. How we could reduce the latency by selecting the modules closer to the input and output pins. (This is actually a 2D optimisation problem!)

All the details are explained in my presentation here…

One final step to wrap up the demo — connect the dev board to the PC via USB, power on the dev board and launch the GOWIN Programmer tool to upload our code into the FPGA…

Uploading our FPGA code with the GOWIN Programmer

This step feels exactly like uploading a program to the Arduino. When our code runs, the LEDs on the dev board flash as expected.

For the source files and detailed steps used in this demo, check out my GitHub repository…

What’s Next?

I’m very grateful that GOWIN has created a dev kit that helps software developers like me to understand the internals of FPGA hardware. And inspire us to wire up our own hardware gadgets with FPGA.

What would I build with FPGA? Power drain has always been a major problem for IoT devices — we would create much better IoT sensing networks if FPGAs could run our devices for longer periods on battery power. I’m now experimenting with the simplest sensors (BME280 on I2C) and the simplest network transceivers (Wisol Sigfox on UART), connecting them with FPGA. I hope to create a very simple IoT device that works but consumes much less power than today’s CPU-based devices.