命令行?
没错,这比 GUI 编程工具方便多了。把比特流(bitstream)文件加载到 FPGA 是个反反复复的活儿:总是同一个文件、同一个板子上的同一颗 FPGA、连着同一台电脑。可 GUI 工具却硬是把这事变成了一场烦人的仪式(有时甚至像一场问答考试——当它无法判断出具体连接的是哪个设备时,它反而指望我知道精确型号)。
而用命令行,说白了就是从 bash 历史记录里把命令翻出来,再按个回车就行了。更让人意外的是,命令行工具不会问 GUI 工具那些傻问题。
先来点试探性操作
先设置好环境:
$ /path/to/quartus/15.1/nios2eds/nios2_command_shell.sh
列出检测到的所有设备(下载电缆是自动识别的):
$ quartus_pgm --auto
Info: *******************************************************************
Info: Running Quartus Prime Programmer
Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
Info: Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
[ ... ]
Info: agreement for further details.
Info: Processing started: Sun May 27 15:06:22 2018
Info: Command: quartus_pgm --auto
Info (213045): Using programming cable "USB-BlasterII [2-5.1]"
1) USB-BlasterII [2-5.1]
02B040DD 5CGTFD9(A5|C5|D5|E5)/..
020A40DD 5M2210Z/EPM2210
[ ... ]
注意,像上面这样列出设备并不是加载比特流(bitstream)所必需的。它顶多用来确定 FPGA 在 JTAG 链里的位置。这种事真的只在探索板卡时做一次。
jtagd
必须知道有个叫 jtagd 的守护进程,它监听 TCP/IP 的 1309 端口,负责通过 USB 总线与 JTAG 适配器通信。GUI 编程工具和命令行工具都依赖它。如果这个进程没在运行,它们俩都会自己把它启动起来。
不过,如果你同时用过多个版本的 Quartus,它可能会成为困惑的来源。尤其是当你先用旧版本尝试加载 FPGA,接着又换新版本的时候。这是因为新版本的 Quartus 会继续沿用旧版本的 jtagd。而这个旧 jtagd 可能不支持新 Quartus 能支持的 FPGA。所以结论是:如果碰到奇怪的现象,下面这条命令也许能解决问题,而且无论如何都不会有害:
$ killall jtagd
给 FPGA 加载程序
quartus_pgm 的大部分输出都是绿色文字。一般来说,只要红字没有出现,就说明一切正常。
$ quartus_pgm -m jtag -o "p;path/to/file.sof"
也可以把设备在 JTAG 链中的位置明确写出来(尤其当它不是链上的第一个设备时)。比如下面的@1 表示它是 JTAG 链上的第一个设备,如果是第二个设备,就写 @2,依此类推。
$ quartus_pgm -m jtag -o "p;path/to/file.sof@1"
Info: *******************************************************************
Info: Running Quartus Prime Programmer
Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
Info: Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
Info: Your use of Altera Corporation's design tools, logic functions
Info: and other software and tools, and its AMPP partner logic
Info: functions, and any output files from any of the foregoing
Info: (including device programming or simulation files), and any
Info: associated documentation or information are expressly subject
Info: to the terms and conditions of the Altera Program License
Info: Subscription Agreement, the Altera Quartus Prime License Agreement,
Info: the Altera MegaCore Function License Agreement, or other
Info: applicable license agreement, including, without limitation,
Info: that your use is for the sole purpose of programming logic
Info: devices manufactured by Altera and sold by Altera or its
Info: authorized distributors. Please refer to the applicable
Info: agreement for further details.
Info: Processing started: Sun May 27 15:35:02 2018
Info: Command: quartus_pgm -m jtag -o p;path/to/file.sof@1
Info (213045): Using programming cable "USB-BlasterII [2-5.1]"
Info (213011): Using programming file p;path/to/file.sof@1 with checksum 0x061958E1 for device 5CGTFD9E5F35@1
Info (209060): Started Programmer operation at Sun May 27 15:35:05 2018
Info (209016): Configuring device index 1
Info (209017): Device 1 contains JTAG ID code 0x02B040DD
Info (209007): Configuration succeeded -- 1 device(s) configured
Info (209011): Successfully performed operation(s)
Info (209061): Ended Programmer operation at Sun May 27 15:35:09 2018
Info: Quartus Prime Programmer was successful. 0 errors, 0 warnings
Info: Peak virtual memory: 432 megabytes
Info: Processing ended: Sun May 27 15:35:09 2018
Info: Elapsed time: 00:00:07
Info: Total CPU time (on all processors): 00:00:03
一旦出现问题——器件不匹配、JTAG 链扫描失败等乱七八糟的事,会很难忽略掉,因为错误会用红色文字显示出来。命令行界面的一个好处是:每次尝试都会从头开始整个过程,所以只需把板卡重新上电再试一次即可。
Cyclone 10 GX FPGA 开发套件
这块板子给我额外添了不少麻烦,所以这里多写几句。当这块板卡连接到电脑时,它显示为 09fb:6810。但尝试给 FPGA 加载程序后(注意命令末尾的@2):
$ quartus_pgm -m jtag -o "p;thecode.sof@2"
Error (213019): Can't scan JTAG chain. Error code 86.
设备的 ID 却变成了 09fb:6010。所以它显然重新编程了板卡上的固件(系统日志会显示出断开连接、再以新 ID 重新连接的过程)。Quartus 的 GUI 编程工具把这块板卡识别为 GX0000406,但点击 Auto Detect(自动检测)却得到“Unable to scan device chain. Hardware is not connected”。
那好,试试扫描一下会怎样?
$ quartus_pgm --auto
[ ... ]
Info (213045): Using programming cable "10CGX0000406 [1-5.1.2]"
1) 10CGX0000406 [1-5.1.2]
Unable to read device chain - Hardware not attached
就我遇到的问题而言,原因显然是当时正在运行的 jtagd 是由旧版 Quartus 启动的,而旧版 jtagd 不认识 Cyclone 10 器件。所以,按上面的建议,把它杀掉。之后,用 Quartus Pro 17.1 执行上面那条编程命令就能正常工作了:
$ quartus_pgm --auto
[...]
Info (213045): Using programming cable "USB-BlasterII [1-5.1.2]"
1) USB-BlasterII [1-5.1.2]
031820DD 10M08SA(.|ES)/10M08SC
02E120DD 10CX220Y