最近收到了一个 Tang nano 9K FPGA开发板,就想借此机会研究一下。
官方文档里介绍如果想使用高云的 FPGA,就需要使用 GOWIN IDE,但是需要申请 license 提交一堆资料,我是别人送的就不太方便让别人弄。加上 IDE 其实并不是很适合学习和投入生产,因为 IDE 忽略了很多细节,以及对一些工作做了处理。所以就想找到其他的工作流程,就像可以使用任何文本编辑器加上 Clang/LLVM 就可以编译 C/C++ 程序一样。
首先是需要知道,FPGA 开发到底是在开发什么,这样才能找到需要的工具和软件。
计算机械执行各种指令的本质是给一系列逻辑单元的引脚通电,然后经过逻辑电路之后输出新的电路信号。从软件的层面来说,每个引脚的输入就是一个常见到的一串二进制数字(比如01011101010
)中的一位(一般使用的正逻辑中,1
表示高电平,0
表示低电平),早期的打孔板就是实体版的这种二进制数字。也就是说,最终我们需要的是一个存放二进制指令的文件,然后由 FPGA 执行。
这时候还有一个问题:指令怎么知道接口和针脚谁是谁呢?不知道的话,是没有办法弄到正确的二进制指令的,因为一些指令的操作对象就可能是错误的。
接口和针脚本质是一些数字表示的,需要通过这些数字来标识,所以我们还需要标识对应接口和针脚的文件。
简而言之,开发 FPGA 就是编写两个文件:xxxx.v
和xxxx.cst
。
.v
文件里存放的是 Verilog 语言的代码,用来连接电路中的各种门、寄存器,以及一些硬 IP(hard intellectual property)。.cst
文件里存放的是引脚约束文件,用来表示 FPGA 开发板上每个引脚的作用和电压。然后再通过一些工具,最后将其转换成存放了一堆位(bit)的文件,称之为比特流文件,来控制各部分的连接、工作等。不同 FPGA 厂商使用的文件格式不一样。这里 Tang nano 9K 使用的文件后缀为.fs
,内容如下:
你需要有Python 3.8 或更新的版本,因为生成比特流需要使用一个 Python 脚本。Mac 一般回预装 Python,你只需要检查和更新版本即可。
接下来使用需要 OSS CAD Suite,这是一个工具链,可以将xxxx.v
和xxxx.cst
转换成最终的比特流文件(有点像编译器或者说交叉编译里的工具链),最后将其写入 FPGA。
这个套件包含了很多 FPGA 的工具,一般目录名或程序名带
gowin
的便是这里 Tang Nano 系列所需的。但其实可以只安装 Gowin FPGA 芯片所需的工具的,不过 OSS CAD Suite 不光终端可以使用,VS Code 也可以使用,所以使用 OSS CAD Suite 比较方便两头使用,如果你使用其他 FPGA 的话,也可以减少安装新的工具链。
OSS CAD Suite 下载地址为:https://github.com/YosysHQ/oss-cad-suite-build/releases/latest
如果你使用最新的 OSS CAD Suite 构建时出现下列这种错误,那么建议下载 2023 年 2 月或 3 月的版本(版本更新特别快,基本上几天就一版,随便哪天的都行)
gowin_pack -d GW1N-9C -o rio.fs rio_pnr.json
Traceback (most recent call last):
File "/opt/oss-cad-suite/libexec/gowin_pack", line 33, in
sys.exit(load_entry_point('Apycula==0.8.2a1', 'console_scripts', 'gowin_pack')())
File "/opt/oss-cad-suite/lib/python3.8/site-packages/Apycula-0.8.2a1-py3.8.egg/apycula/gowin_pack.py", line 984, in main
AttributeError: module 'importlib.resources' has no attribute 'files'
make: *** [Makefile:16: rio.fs] Error 1
然后将 OSS-CAD-Suite 中bin
的路径放到环境变量PATH
中,你可以放到你的 Shell 配置文件中。语句如下:
export PATH="存放位置/oss-cad-suite/bin:$PATH"
然后使用source
激活更新或者新开一个终端窗口即可。
Tang Nano 使用的 Gowin FPGA 芯片,它的比特流和格式的工具在 Apicula 项目中,这是地址:https://github.com/YosysHQ/apicula。如果你需要阅读文档,那么也在这个项目中。
安装方法如下:
$ pip3 install apycula
如果你想简洁安装,那么可以使用这种方法。这样下载安装的包体积会小特别多(4.1 MB 对 1.35 GB),但是万一开发过程中需要使用其他的工具,那么就得自己再去单独下载这些工具了。
编写代码这里使用 Visual Studio Code,当然你使用任何文本编辑器来编写代码,比如 Vim、Emacs 等。但是不能使用 Word、Pages 这种应用程序,因为这种应用程序实际上并不是文本编辑器,而是文本处理器,在底层并不是简单的文本。
这里使用 Visual Studio Code 的原因主要是扩展会高亮代码和方便设置针脚,以及构建最终的比特流文件必须要使用一个插件来自动构建。所以需要安装两个扩展:Lushay Code
和Verilog-HDL/SystemVerilog/Bluespec SystemVerilo
。Lushay Code
是为了使用 OSS-CAD-Suite,这是一个自动构建工具,而后者是为了高亮代码和方便设置针脚。如果Lushay Code
不支持你的 FPGA,那么还请找一下支持自己 FPGA 的扩展插件。
此外要配置一下扩展,在“设置-扩展”中,将你的 OSS-CAD-Suite 位置输入到下图位置,这样 VS Code 才可以使用 OSS-CAD-Suite:
这里有两个文件:top.v
和tangnano9k.cst
,内容分别如下(需要注意top.v
最后需要有一个空行)
// top.v
module top
(
input clk,
output [5:0] led
);
localparam WAIT_TIME = 13500000;
reg [23:0] clockCounter = 0;
reg [5:0] cur_state = 6'b111111; // 这个六位二进制数的每一位都表示一个 LED
always @(posedge clk) begin
clockCounter <= clockCounter + 1;
if (clockCounter == WAIT_TIME) begin
clockCounter <= 0;
cur_state <= cur_state << 1;
if (cur_state == 6'b000000) begin
cur_state <= 6'b111111;
end
end
end
assign led[5:0] = cur_state[5:0];
endmodule
// tangnano9k.cst
IO_LOC "clk" 52;
IO_PORT "clk" PULL_MODE=UP;
IO_LOC "led[0]" 10;
IO_LOC "led[1]" 11;
IO_LOC "led[2]" 13;
IO_LOC "led[3]" 14;
IO_LOC "led[4]" 15;
IO_LOC "led[5]" 16;
如果你的tangnano9k.cst
是用 VS Code 设置的,那么应该如下:
这种方法很简单,如果你之前配置好了 VS Code,并且也已经将你的 FPGA 连接到 Mac 上,直接按照下图的顺序点击,等一会儿,fs
文件就已经构建好并且将其烧录到 FPGA 上了:
这部分划成两节,第一节详细介绍了每一步的使用和原由,第二节则将其整理成一个脚本,这样就方便许多了。
然后输入以下命令:
# 读取分析top.v的内容
> read -sv top.v
# 将top.v的内容合成转换为json格式(由于yosys已经分析了文件,所以不用文件名top.v,而是模块名top)
> synth_gowin -top top -json test.json
# 退出yosys
> exit
当然上面这部分可以化简成一句话:
$ yosys -p "read_verilog top.v; synth_gowin -json test.json"
然后使用下面的命令来进行进一步的工作:
# 通过设置设备名、CST文件和刚才生成的 JSON 文件来生成 FPGA 布局和布线信息,并且放入 test_pnr.json 中。
$ nextpnr-gowin --family GW1N-9C --device GW1NR-LV9QN88PC6/I5 --cst tangnano9k.cst --json test.json --write test_pnr.json
上面的家族名和设备名需要根据你自己的 FPGA 型号进行修改(如果不是 Tang nano 9K 的话可以不写--family
这个选项),这个型号不是官网上短的那种。你可以在自己 FPGA 芯片封装上看到,比如下图就是 Tang nano 9K 的设备名GW1NR-LV9QN88PC6/I5
:
也可以根据下面的表格进行查找:
名称 | 设备名(device) | 板子的名称(board) |
---|---|---|
Trenz TEC0117 | GW1NR-UV9QN881C6/I5 | tec0117 |
Sipeed Tang Nano: | GW1N-LV1QN48C6/I5 | tangnano |
Sipeed Tang Nano 1K | GW1NZ-LV1QN48C6/I5 | tangnano1k |
Sipeed Tang Nano 4K | GW1NSR-LV4CQN48PC7/I6 | tangnano4k |
Sipeed Tang Nano 9K | GW1NR-LV9QN88PC6/I5 | tangnano9k |
Seeed RUNBER | GW1N-UV4LQ144C6/I5 | runber |
@Disasm honeycomb | GW1NS-UX2CQN48C5/I4 | honeycomb |
接下来需要注意,如果你和我一样是 Tang nano 9K,那么使用下面的语句(设备不能写上面那个长的):
$ gowin_pack -d GW1N-9C -o top.fs test_pnr.json
如果你是其他型号的 Gowin FPGA,那么使用:
$ gowin_pack -d 你的设备型号 -o top.fs test_pnr.json
然后就是将比特流文件烧录到 FPGA 上:
openFPGALoader -b 板子的名字 pack.fs
这个板子的名称
在上面的表格里可以看到对应的。如果你看到类似下面的内容,那么就是烧录成功了:
然后就可以看到这样的现象:
这里搞点生产力,我们将其写成脚本来实现“一步生成和烧录”,你可以根据自己的型号进行修改.
新建一个空白文本文件build.sh
,然后输入:
#!/bin/bash
DEVICE='GW1NR-LV9QN88PC6/I5|tangnano9k'
BOARD='tangnano9k'
yosys -p "read_verilog top.v; synth_gowin -json temp.json"
nextpnr-gowin --family GW1N-9C --device GW1NR-LV9QN88PC6/I5 --cst tangnano9k.cst --json temp.json --write test_pnr.json
gowin_pack -d GW1N-9C -o top.fs test_pnr.json
openFPGALoader -b $BOARD top.fs
然后使用下面的语句赋予运行权限:
chmod +x build.sh
这样只用./build.sh
就可以在当前目录下进行构建和烧录了。
FPGA 是数电的一个分支,FPGA 学习过程中需要了解很多数电的术语和概念,所以可以使用数电专业的专业书来做一些入门,这对后续学习也有帮助。这里推荐剑桥大学的这些资料:
这些资料对于非数电专业的人士来说是一些不错的资料。其中很多知识点并不是问题,初高中都学过,主要是国内中学时期使用的是苏联式的符号,而绝大部分资料使用的都是美式符号或者现在的国标符号,所以如果你直接看电路图可能会看不懂。
如果你和我一样是 FPGA 新手,那么关于 FPGA 的一些术语会让人头大。比如说 Verilog 是什么?硬 IP 又是什么?针对这些 FPGA 的术语和概念,我推荐看看 Intel 联合出版的一本书《FPGAs for Dummies》,你可以很轻松的在搜索引擎中通过“FPGAs for Dummies PDF”找到,《FPGAs for Dummies》的封面如下图:
这本书用非常轻松的语言介绍了你准备踏入 FPGA 领域所需的术语、语言、设计思路、发展历程、应用等各方面的知识,以及最基础的那个问题:为什么你要使用 FPGA。
《XXX FOR DUMMIES》是一个系列书籍,致力于用诙谐、简单的语言介绍技术,类似《十分钟学会xxx》,但是作者有一些事业内蛮厉害的人。这个系列并不是 Intel 的,只是 FPGA 这本是 Intel 合作的。
关于 tang nano 9k 还有国外写的很不错的专栏,介绍了很多案例和用法,上文中提到的 Lushay Code 插件就是这个团队做的:https://learn.lushaylabs.com/getting-setup-with-the-tang-nano-9k/
然后就是 YosysHQ 一些项目的代码和文档了,比如说上文提到的:
希望能帮到有需要的人~