Tang Nano 9K

A project log for vector-06c mini

A 50% size replica of my favourite 8-bit computer

svofskisvofski 04/14/2024 at 08:210 Comments

Gowin version of Verilog is a bit weird, but after spending some very frustrating days hunting down the gotchas, I have the first signs of life. Behold, vector06cc on Tang Nano 9K with 800x480 RGB panel. The chip is GW1NR-LV9QN88PC6/15.

Quirk 1: `default_nettype none

It's been customary for me to use this to avoid implicit inference of forgotten or just mistyped nets. If the default type is none, a signal without an explicit declaration is an error and you instantly know. In Gowin flavour of Verilog if you set default nettype none, you become obliged to also declare each wire input / output of a module explicitly as wire. This looks exceedingly ugly and makes zero sense. But the worst part is that it makes your project incompatible with GAO. So I had to say goodbye to this and be extra alert with the warnings.

Quirk 2: discarded assignments after implicit net instantiation

For example if you have code like this:

mymodule instance(.input(important_wire), .output(something));
wire important_wire = a & b;

From the point of view of Quartus, it's perfectly fine. But in Gowin this results in important_wire flapping around in the breeze without a driver. Everything compiles but doesn't work and you're frustrated for many hours.

Apparently what happens is this. The compiler finds important_wire, instantiates the net as a wire. Then when it finds the actual declaration with assignment, it treats it as a duplicate and discards not just the declaration but the assignment as well. The solution here is to use declaration with assignments before use, like this:

wire important_wire = a & b;
mymodule instance(.input(important_wire), .output(something));

It also seems that a separate assign is safer than assignment in declaration because it will not get discarded in a similar situation.


There's some confusion about what kind of memory different Tang Nano boards have. Sipeed's own documents don't do a good job explaining the differences. 

TL;DR Tang Nano 9K == PSRAM, Tang Nano 20K == SDRAM.

To go a bit in detail you need to look at the chip family specs, "GW1NR series of FPGA Products Data Sheet", DS117-3.0E, 9/25/20. Table 1-1 "Product Resources" may make you believe that GW1NR-9 has both SDRAM and PSRAM. However table 1-2 "Package-Memory Combinations" on the next page shows that PSRAM and SDRAM are mutually exclusive. QN88P package used in Tang Nano 9K has 2x32Mbit PSRAM dies. From obscure sources, the die seems to be a copy/paste of W955D8MBYA.

I have the 9K, PSRAM.

A huge shout out to [Feng Zhou] for his PSRAM controller: It was easy to tailor it to my needs with 32-bit reads.

I'm clocking PSRAM at 48MHz. A 16-bit read is completed in 10 cycles. For the video controller vector06cc to make it in time, it needs to read 32-bit words. A 32-bit read is done in 11 cycles.