Category: hardware

First Steps with the Tang Nano FPGA Development Board

The Tang Nano is a very very low cost FPGA development board by Sipeed featuring a GW1N-1-LV FPGA produced by GOWIN Semiconductors. GOWIN is another Chinese chip manufacturer entering the FPGA arena, like Efinix and Anlogic.
The GW1N-1-LV is the smallest member of GOWINs “Little Bee” series, which consists of small footprint instant-on FPGA devices for IoT and interfacing solutions.

The Tang Nano FPGA development board

The Tang Nano offers the following features:

  • GW1N-1-LV FPGA (QFN48 package)
    • 1152 LUT’s
    • 864 FF’s
    • 4 BRAM’s à 18 kbit (72 kbit total)
    • 96 kbit flash memory
    • 1 PLL
  • 34 user IO pins
  • LCD interface connector (ZIF FFC)
  • 2 user buttons
  • 24 MHz oscillator
  • 64 MBit QSPI PSRAM
  • USB-JTAG downloader/debugger (via USB-C connector)
  • 4 pin JTAG header (split into 2 x 2 pins left/right of the USB-C connector)
  • costs just about 5 $ (like the Longan Nano)

Like most of Sipeed’s latest development boards the Tang Nano comes with a USB-C connector, thus a USB-C cable is required to use the board without unnecessary tinkering.
Regarding the LCD interface I am unsure how this would be useful, except for generating some fancy test patterns. Almost all user IO pins are utilized by the LCD interface if it is used, so there are not many pins left which could be used to get a video signal into the FPGA anymore.

The Toolchain

All steps from HDL to bitstream are handled by GOWIN FPGA Designer, a graphical IDE which offers a project based design flow. Both VHDL and Verilog are supported (allegedly up to SystemVerilog-2017).
Timing constraints are defined by industry standard SDC files, however it is not clear which subset of SDC commands is supported.
Pin assignments and IO constraints are defined in a proprietary CST file. Alternatively UCF syntax is supported, as known from Xilinx ISE.

The design flow is very simple and offers just the most basic options.
The synthesis tool can be set to either GowinSynthesis (included with GOWIN FPGA Designer) or Synplify Pro (external synthesis tool by Synopsys). I strongly doubt that anyone will use Synplify Pro for GOWIN FPGA’s. In the following GowinSynthesis is assumed to be the selected synthesis engine.
The PAR step is simple yet effective as well, however I did not test (yet) how PAR performs once the device utilization reaches a higher percentage.
Timing analysis and power analysis reports can be generated once implementation is complete.
GOWIN FPGA Designer also comes with a programmer utility which can be used to program the Tang Nano and read out some device IDs and status registers. The FPGA configuration bitstream can be programmed into embedded flash memory, into external flash memory or can be written directly to the (volatile) SRAM cells of the FPGA.

The Example

To test that the Tang Nano board is working properly I implemented the infamous blinky LED example.

The Tang Nano offers 2 different clock sources: an on-board 24 MHz oscillator and an integrated oscillator running at roughly 240 MHz.
The external 24 MHz clock reference should be used in conjunction with the PLL inside the FPGA, in order to generate an adequate clock signal to drive the logic on the FPGA fabric. For the start, the PLL is generated by using the IP Generator tool to get the correct parameters for the PLL. However, the 24 MHz reference clock can also be used to drive logic directly, without using the PLL.

/* On-Chip PLL 108 MHz. *****************************************************/
wire clk_108M;
wire pll_lock;
wire pll_reset = 1'b0;

assign clk_24M = XTAL_IN;

Gowin_rPLL Gowin_rPLL_inst(
    .clkout(clk_108M),
    .lock(pll_lock),
    .reset(pll_reset),
    .clkin(clk_24M));

To make use of the integrated oscillator another IP core is generated with the IP Generator tool. Alternatively the respective device primtive can be instantiated explicitly.

/* On-Chip Oscillator 2.5 MHz (240 MHz / 96). ********************************/
wire clk_2M5;
Gowin_OSC_div96 Gowin_OSC_div96_inst (.oscout(clk_2M5));

Finally one of the generated clocks can be used to drive a counter, which will get the RGB LED blinking.

/* Blink RGB LED. ***********************************************************/
localparam CNT_LEN = 26;
reg [CNT_LEN-1:0] cnt = 0;

always @ (posedge clk_108M, negedge rstn)
begin
    if (rstn == 1'b0) begin
        cnt <= 'd0;
    end else begin
        cnt <= cnt + 1;
    end
end

always @ (*)
begin
    LED_R <= ~cnt[CNT_LEN-1];
    LED_G <= ~cnt[CNT_LEN-2];
    LED_B <= ~cnt[CNT_LEN-3];
end

I use the 3 MSB’s of the counter to blink the red, green and blue color channel of the RGB LED respectively. Thus the RGB LED will cycle through all possible combinations of colors. The blinking speed may vary depending on the clock driving the counter.

The final step to get the blinky LED design running on the Tang Nano is to define the pin assignment and timing constraints.
The timing constraints consist of two create_clock commands for the 24 MHz reference clock input and the internal oscillator, which is set to 2.5 MHz.

# tang_nano.sdc
create_clock -name CLK -period 41.667 [get_ports {XTAL_IN}]
create_clock -name SLOW -period 400 [get_pins {Gowin_OSC_div96_inst/osc_inst.OSCOUT}]

The pin assignments can be created using the Floorplanner tool and the Tang Nano schematic. For simplicity the constraints can be copied over from the Tang Nano examples repository or my own example code (file tang_nano.cst). Note that I tried to stay as close to the net names of the schematic while naming the top level ports.

// tang_nano.cst
//Copyright (C)2014-2019 Gowin Semiconductor Corporation.
//All rights reserved. 
//File Title: Physical Constraints file
//GOWIN Version: V1.9.3Beta
//Part Number: GW1N-LV1QN48C6/I5
//Created Time: Tue 12 24 23:51:04 2019

IO_LOC "USER_BTN_A" 15;
IO_PORT "USER_BTN_A" IO_TYPE=LVCMOS33;
IO_LOC "XTAL_IN" 35;
IO_PORT "XTAL_IN" IO_TYPE=LVCMOS33;
IO_LOC "USER_BTN_B" 14;
IO_PORT "USER_BTN_B" IO_TYPE=LVCMOS33;
IO_LOC "LCD_R[0]" 27;
IO_PORT "LCD_R[0]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_R[1]" 28;
IO_PORT "LCD_R[1]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_R[2]" 29;
IO_PORT "LCD_R[2]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_R[3]" 30;
IO_PORT "LCD_R[3]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_R[4]" 31;
IO_PORT "LCD_R[4]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[0]" 32;
IO_PORT "LCD_G[0]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[1]" 33;
IO_PORT "LCD_G[1]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[2]" 34;
IO_PORT "LCD_G[2]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[3]" 38;
IO_PORT "LCD_G[3]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[4]" 39;
IO_PORT "LCD_G[4]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_G[5]" 40;
IO_PORT "LCD_G[5]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_B[0]" 41;
IO_PORT "LCD_B[0]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_B[1]" 42;
IO_PORT "LCD_B[1]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_B[2]" 43;
IO_PORT "LCD_B[2]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_B[3]" 44;
IO_PORT "LCD_B[3]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_B[4]" 45;
IO_PORT "LCD_B[4]" IO_TYPE=LVCMOS33;
IO_LOC "LCD_CLK" 11;
IO_PORT "LCD_CLK" IO_TYPE=LVCMOS33;
IO_LOC "LCD_DE" 5;
IO_PORT "LCD_DE" IO_TYPE=LVCMOS33;
IO_LOC "LCD_HSYNC" 10;
IO_PORT "LCD_HSYNC" IO_TYPE=LVCMOS33;
IO_LOC "LCD_VSYNC" 46;
IO_PORT "LCD_VSYNC" IO_TYPE=LVCMOS33;
IO_LOC "LED_R" 16;
IO_PORT "LED_R" IO_TYPE=LVCMOS33 SLEW_RATE=SLOW;
IO_LOC "LED_G" 17;
IO_PORT "LED_G" IO_TYPE=LVCMOS33 SLEW_RATE=SLOW;
IO_LOC "LED_B" 18;
IO_PORT "LED_B" IO_TYPE=LVCMOS33 SLEW_RATE=SLOW;
GOWIN FPGA Designer: Floorplanner

So far so good. The only thing left now is to generate a programming file for the Tang Nano and toss it on the board.

GOWIN FPGA Designer: Programmer

All done. Time to get impressed by the pinnacle of modern human civilization: a blinking LED.

The Tang Nano skillfully flashing its RGB LED

As usual, the example from this article is available on my Tang Nano github repository.

That’s it for today. See you next time.


References:

  1. https://www.seeedstudio.com/Sipeed-Tang-Nano-FPGA-board-powered-by-GW1N-1-FPGA-p-4304.html
  2. https://github.com/sipeed/Tang-Nano-Doc
  3. https://github.com/sipeed/Tang-Nano-examples
  4. http://dl.sipeed.com/TANG/Nano
  5. https://xesscorp.github.io/tang_nano_user/docs/_site/
  6. https://www.gowinsemi.com/en/product/detail/2/

Gigabit Transceiver(s) for a Cheap FPGA Development Board

There are a lot of FPGA development boards out there to buy. Official vendor boards with the latest advanced devices on it can easily cost several thousand Euros.
Hobbyists and makers are more interested in FPGA development boards within an affordable price range (roughly << 100 $/€). The logic resources and feature set of the FPGA devices on these boards is not that important on the other hand. The main application for makers/hobbyists is small projects and self-learning, I assume, and not rolling out their own 5G equipment.

There are already a lot of affordable entry level FPGA boards available and more are being released every year. The one thing missing on these boards is usually gigabit transceivers (GT’s). Of course the cheapest FPGA devices do not come with pricey extras like GT’s, but is the price difference really that big?

So I started to search for low cost FPGA devices which include GT’s. I only looked at the three major vendors: Xilinx, Intel/Altera and Lattice. I tried to focus on the latest FPGA families in the low cost segment. The prices from Mouser are as of December 2019 and are valid for single quantity purchase.

Intel/Altera Cyclone IV GX EP4CGX15 with two 2.5 Gbps GT’s
Xilinx Spartan-6 XC6SLX25T with two 3.2 Gbps GT’s
Xilinx Artix-7 XC7A12T with two 6.6 Gbps GT’s
Lattice ECP5 LFE5UM-25 with two 3.2 Gbps GT’s

The comparison shows that Lattice is the first choice when aiming for a low cost FPGA with GT’s. The prices are only from one distributor and only for single quantities, so the price sample must be taken with a grain of salt.
Interestingly the old Spartan-6 is much more expensive than the newer Artix-7.

However, there are other aspects to consider than just the price and transceiver speed, e.g. if a PCIe endpoint IP is available for free or not (the same goes for all IP cores utilizing the GT’s). Without the support of IP cores and tools the GT’s won’t be any good anyhow.

An interesting board announced on CrowdSupply right now is a new member of the TinyFPGA series, the TinyFPGA EX with a EX85-5G FPGA. This one will have two GT’s with up to 5 Gbps. Looking at the board layout it’s not clear to me if the full capability of the GT’s will be usable in the end, because there are only plain pin headers for board IO, no BNC or F-conncetors.
The end user price has not been announced yet. Let’s wait and see what the GT’s are going to cost in a “commercial” product.


References:

  1. https://www.mouser.de/Search/Refine?Keyword=LFE5UM-25&Ns=Pricing%7C0
  2. https://www.mouser.de/_/?Keyword=XC7A12T&Ns=Pricing%7c0&FS=True
  3. https://www.mouser.de/Intel/Semiconductors/Programmable-Logic-ICs/FPGA-Field-Programmable-Gate-Array/_/N-3oh9p?P=1yy6lwuZ1y9hztvZ1yy1mfxZ1yy1mdnZ1yy1mfwZ1yy1mcsZ1yy1mcqZ1yy1mcp&Ns=Pricing%7C0
  4. https://www.mouser.de/datasheet/2/225/FPGA-DS-02012-2-1-ECP5-ECP5G-Family-Data-Sheet-1022822.pdf
  5. https://www.xilinx.com/support/documentation/data_sheets/ds180_7Series_Overview.pdf
  6. https://www.mouser.de/datasheet/2/612/cv_51001-1098989.pdf
  7. https://www.mouser.de/Xilinx/Semiconductors/Programmable-Logic-ICs/FPGA-Field-Programmable-Gate-Array/_/N-3oh9p?P=1y8eeklZ1y8efd7&Keyword=XC6SLX25T&Ns=Pricing%7c0
  8. https://www.xilinx.com/support/documentation/data_sheets/ds160.pdf

First Steps with the iCEBreaker FPGA Development Board

The iCEBreaker board is the first FPGA development board with a fully open-source toolchain, which allows to go all the way from HDL code to configuration bitstream. All the schematics and hardware information is openly available at no extra cost.

The Board

The iCEBreaker board features a Lattice iCE40UP5K FPGA with the following integrated components:

  • 5280 PLB’s consisting of one 4-input LUT, carry-chain and one FF each
  • 128 Mbit dual-port BRAM’s
  • 1 MBit single-port BRAM’s
  • 8 DSP’s
  • 1 programmable PLL and 2 on-chip oscillators
  • 2 hard-IP’s for SPI and I2C each
  • 3 hard-IP’s for PWM
  • Up to 32 user IO pins. The IO pins are available as 3 PMOD edge connectors
  • One PMOD module with 3 push-buttons and 5 LEDs is included
  • On-board FTDI FT2232H for easy FPGA configuration and debugging via USB
  • 128 Mbit Winbond QSPI flash, programmable over USB or via a separate SPI pin-header
Overview of the iCEBreaker.

The Toolchain

The remainder of this article will guide through the procedure of setting up the open-source toolchain for the iCEBreaker. No Lattice tools and software will be used, maybe that will be covered another time. In a final step the toolchain will be tested by implementing and loading a simple example design. The OS will be asusmed to be Ubuntu 18.04 for the rest of this article.

Let’s begin by installing the dependencies which are required to build the toolchain. The command below will install the superset of all dependencies which are required for the steps that follow.

$> sudo apt install build-essential clang bison flex libreadline-dev gawk tcl-dev libffi-dev git mercurial graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev libftdi-dev qt5-default python3-dev libboost-all-dev cmake libeigen3-dev

Next clone the github repository for yosys, the synthesis tool of the toolchain. The latest stable release/tag of yosys is recommended, but instead the latest master branch can also be used.

$> git clone https://github.com/yosyshq/yosys
$> cd yosys
$> git checkout yosys-v0.9
$> make -j(nproc)
$> sudo make install

Continue with the bitstream generation tool icestorm.

git clone https://github.com/cliffordwolf/icestorm
cd icestorm
make -j$(nproc)
sudo make install

Finally we have to choose between the place-and-route tool nextpnr and arachne-pnr. Since arachne-pnr is considered obsolete it’s successor nextpnr should be used. Since I like to play around and compare results between different tools I will install both, but note that only one of the two is required.

$> git clone https://github.com/yosyshq/nextpnr
$> cd nextpnr
$> cmake -DARCH=ice40
$> make -j$(nproc)
$> sudo make install
$> git clone https://github.com/yosyshq/arachne-pnr
$> cd arachne-pnr
$> make -j$(nproc)
$> sudo make install

That concludes the setup of the toolchain. Time for an example, to see if everything works.

The Example

Now that we are all set, let’s try to synthesize a simple example design, run the place-and-route tool and generate a bitstream for the iCEBreaker.

$> yosys -p "synth_ice40 -top icebreaker_top -blif icebreaker_top.blif" src/icebreaker_top.v
$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc
$> icepack icebreaker_top.asc icebreaker_top.bin
$> iceprog icebreaker_top.bin

Aaaand the board is bricked (for the moment)! The iCEBreaker no longer is properly recognized neither by Ubuntu nor my Windows 10 machine. It took me a few moments to understand what had gone wrong, but not close to as long as I feared it would take.
Well, the problem was that no physical constraint file (.pcf) was passed to arachne-pnr. The .pcf file defines which top module port is connected to which physical package pin. Without this information arachne-pnr will choose these pins assignments arbitrarily, like most place-and-route tools do in such a situation. After asking arachne-pnr to output the pin assignments it had chosen (-w option) the problem became very clear.

$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc -w icebreaker_top.asc.pcf
... (some irrelevant output)
$> cat icebreaker_top.asc.pcf 
$> arachne-pnr 0.1+328+0 (git sha1 c40fb22, g++ 7.4.0-1ubuntu1~18.04.1 -O2)
set_io led_o 35

Cross-checking this with the iCEBreaker pinout-sheet or schematic and we can see that pin 35 is actually connected to the external 12 MHz oscillator output. Unfortunately this oscillator also drives the FTDI chip (FT2232) which takes care of the USB connection to the outside world. Driving a dumb blinky LED signal on that pin will wreak havoc on the 12 MHz clock signal and mess with the FTDI chip.
To fix this issue the CRESET jumper on the board must be closed. Setting the CRESET jumper will keep the FPGA in reset. This way no output pin of the FPGA is driven and we have time to replace the bitstream in the SPI flash with one that doesn’t do any harm.

So let’s try again, this time with the correct .pcf file.

$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc -p constr/icebreaker_top.pcf -w icebreaker_top.asc.pcf
... (some irrelevant output)
$> icepack icebreaker_top.asc icebreaker_top.bin
$> iceprog icebreaker_top.bin 
Behold, the iCEBreaker blinking like a boss! Imagine the possibilities…

The example from this article – and hopefully some more advanced stuff in the near future too – will be available on my iCEBreaker github repository.

That’s it for today. See you next time.


References:

  1. https://github.com/icebreaker-fpga/icebreaker
  2. https://github.com/icebreaker-fpga/icebreaker-examples
  3. https://github.com/YosysHQ/yosys
  4. http://www.clifford.at/icestorm/#install

VLSI tools in 500 LOC or Longing for Attention

My VLSI tools take a chip from conception through testing. Perhaps 500 lines of source code. Cadence, Mentor Graphics do the same, more or less. With how much source/object code?

– Chuck Moore, the inventor of Forth –

Now, I’ve seen chip design tools by the likes of Cadence and Mentor Graphics. Astronomically costly licenses. Geological run times. And nobody quite knows what they do.

– http://yosefk.com/blog/my-history-with-forth-stack-machines.html –

© bananatronics.org