Home › Forums › Electronics › Tang Nano 20k FPGA dev board
- This topic has 1 reply, 1 voice, and was last updated 1 month, 3 weeks ago by
modrobert.
-
AuthorPosts
-
June 12, 2026 at 7:59 #1044::

I recently bought a Tang Nano 20k development board from Sipeed. The hardware worked out of the box but I had some software problems with the IDE initially. Programming using the built-in Gowin programmer has been working fine so far (which seems to be common problem). I’m using Xubuntu 24.04.4 LTS (which is basically a slimmed down Ubuntu 24.04.4 LTS running with Xorg and XFCE) on a PC.
After downloading ‘Gowin_V1.9.11.03_Education_Linux.tar.gz’ from gowinsemi.com (requires registering), I unpacked the files into ‘/opt/gowin’ (any directory you create is fine), and tried to run it, but got library version errors and core dumps. In order to fix the problem I created a script called ‘gowin_ide.sh’ to launch ‘gw_ide’:
#!/bin/bash cd /opt/gowin/IDE/bin export LD_LIBRARY_PATH=/opt/gowin/IDE/lib ./gw_ideThis will make sure the IDE uses its own libraries first (before system) and sub processes launched from the GUI also finds them. There was still a library error where it complains about undefined symbols in “libfontconfig”, this needed a separate fix:
rm /opt/gowin/IDE/lib/libfreetype.so.6Now finally ‘gw_ide’ launches, and also the tools from within the GUI.
I then decided to try an example tutorial found here:
https://wiki.sipeed.com/hardware/en/tang/tang-nano-20k/example/led.htmlThis worked for the most part, just had to change the “IO Type” voltages to “LVCMOS33” in the FloorPlanner part, more info about in that comments of that article.
I modified the example LED blink design a bit, added another counter LED blink and a Verilog testbench (even though a testbench might be overkill in this case), mostly to figure out how to run a simulation with this toolchain because I didn’t feel like using DSim from Altair (requires registration) which is linked in the GUI.
Here is the modified ‘led.v’ example:
`timescale 1ns / 1ps module led( input wire Clock, output wire LED1, output wire LED5 ); /********** Counters **********/ //parameter Clock_frequency = 27_000_000; // Crystal oscillator frequency is 27Mhz `ifdef SIM_COUNT_OVERRIDE parameter LED1_value = `SIM_COUNT_OVERRIDE; parameter LED5_value = `SIM_COUNT_OVERRIDE; `else parameter LED1_value = 13_499_999; // The number of times needed to time 0.5s parameter LED5_value = 1_349_999; // This currently acts like a slow clock for GAO at 0.05s `endif reg [23:0] LED1_value_reg = 24'b0; // counter value reg LED1_value_flag = 1'b0; // IO change flag always @(posedge Clock) begin if ( LED1_value_reg <= LED1_value ) begin // not count to 0.5s LED1_value_reg <= LED1_value_reg + 1'b1; // Continue counting LED1_value_flag <= 1'b0; // No flip flag end else begin //Count to 0.5S LED1_value_reg <= 24'b0; // Clear counter,prepare for next time counting. LED1_value_flag <= 1'b1 ; // Flip flag end end reg [23:0] LED5_value_reg = 24'b0; // counter value for LED5 reg LED5_value_flag = 1'b0; // IO change flag always @(posedge Clock) begin if ( LED5_value_reg <= LED5_value ) begin //not count to 0.05s LED5_value_reg <= LED5_value_reg + 1'b1; // Continue counting LED5_value_flag <= 1'b0; // No flip flag end else begin LED5_value_reg <= 24'b0; // Clear counter,prepare for next time counting. LED5_value_flag <= 1'b1; // Flip flag end end /********** IO voltage flip **********/ reg LED1_reg = 1'b0; // Initial state always @(posedge Clock) begin if ( LED1_value_flag ) begin // Flip flag LED1_reg <= ~LED1_reg; // IO voltage flip `ifdef SIMULATION $strobe("Time: %0t LED1: %0d", $time, LED1_reg); `endif end else // No flip flag LED1_reg <= LED1_reg; // IO voltage constant end assign LED1 = LED1_reg; /********** IO voltage flip **********/ reg LED5_reg = 1'b0; // Initial state always @(posedge Clock) begin if ( LED5_value_flag ) begin // Flip flag LED5_reg <= ~LED5_reg; // IO voltage flip `ifdef SIMULATION $strobe("Time: %0t LED5: %0d", $time, LED5_reg); `endif end else // No flip flag LED5_reg <= LED5_reg; // IO voltage constant end assign LED5 = LED5_reg; endmodule…and the testbench ‘tb_led.v’:
`timescale 1ns / 1ps module tb_led; // Declare signals to connect to the LED module reg Clock = 0; wire LED1; wire LED5; // Instantiate your original LED module led uut ( .Clock(Clock), .LED1(LED1), .LED5(LED5) ); // Generate a 27MHz clock always #18.5185 Clock <= ~Clock; always @(LED1) begin $strobe("time: %0t | Testbench observed LED1 at: %b", $time, LED1); end always @(LED5) begin $strobe("time: %0t | Testbench observed LED5 at: %b", $time, LED5); end // Control the simulation timeline initial begin // Tell Verilator the name of the waveform file to create $dumpfile("waveform.fst"); // Dump all signals inside the testbench and child modules (0 means everything) $dumpvars(0, tb_led); // Set a clean format for %0t reporting $timeformat(0, 4, "s", 20); // Let it run for 1.2 seconds #1200000000; $display("Simulation successfully completed!"); $finish; end endmoduleWhat I ended up using for simulation is Verilator which is open source can be installed like this in Ubuntu Linux:
sudo apt-get install verilatorI also installed GTKWave Analyzer to visually see trace dumps from Verilator:
sudo apt-get install gtkwaveTo build the simulation for my custom testbench I use a terminal shell (command line) in the directory where the Verilog sources are:
verilator --binary --timing --trace-fst --top-module tb_led -DSIMULATION -Wall +1364-2001ext+v led.v tb_led.v…and then to run the simulation:
obj_dir/Vtb_ledThe trace can be found in current directory after simulation run, I load it like this to view:
gtkwave waveform.fstAfter playing around with the Gowin Analyzer Oscilloscope (GAO) for a while which is a tool included in the GUI, it seems very powerful (reminds me of Xilinx ChipScope), more info in the user guide.
I hope this info helps to get started, let me know if you have any questions or want to share your own tips.
June 12, 2026 at 15:45 #1051::I tried some example code found here:
https://github.com/sipeed/TangNano-20K-exampleThe HDMI example works.

-
AuthorPosts
- You must be logged in to reply to this topic.
Share this:
- Email a link to a friend (Opens in new window) Email
- Print (Opens in new window) Print
- Share on X (Opens in new window) X
- Share on Mastodon (Opens in new window) Mastodon
- Share on Bluesky (Opens in new window) Bluesky
- Share on Telegram (Opens in new window) Telegram
- Share on Tumblr (Opens in new window) Tumblr
- Share on WhatsApp (Opens in new window) WhatsApp
- Share on Nextdoor (Opens in new window) Nextdoor
- Share on LinkedIn (Opens in new window) LinkedIn
- Share on Pinterest (Opens in new window) Pinterest
- Share on Threads (Opens in new window) Threads
- Share on Reddit (Opens in new window) Reddit
- Share on Facebook (Opens in new window) Facebook