注意:看完这篇博客你不会学会 Nios,但可能对理解 Nios 开发套件有一点帮助。

Nios 方面笔者仅过了一遍 Demo 的流程,没有自己独立开发的经验,这里重点在如何使用 Quartus 下载配置启用 Nios 的 FPGA。

本文基于 Windows 环境下的 Quartus 20.1 Lite,但应当对 Pro 和 Standard 版本适用。

用到的代码/文件来自 Terasic DE1-Soc 的 DE1-SoC_v.5.1.3_HWrevF.revG_SystemCD.zip 内的 \Demonstrations\FPGA\DE1_SoC_Audio 项目。

下文中的 path\to\intelFPGA_lite 需要按照您的实际情况进行修改。

基本概念

比较浅显的理解:SOF 文件是 HDL 编译来的,用来形成电路,ELF 文件是 Nios II 上面跑的程序。(描述并不准确)

下载 SOF 大家都比较熟悉,关键在于怎么下载 ELF。

我们知道,Quartus 现在已经内置了 Nios II 开发套件,位于 path\to\intelFPGA_lite\20.1\nios2eds\。这个套件的主要使用方式是通过一个特殊的命令行:Nios II Command Shell。这个命令行说白了就是一个 bash 带上了一堆预置的环境变量,启动后你就可以直接调用 Nios 相关的工具。

之所以 Intel 这么做,原因无非有二:

  • Nios 相关的工具和脚本散落在 Quartus 各处,统一导入环境变量方便使用,同时在关闭后不会污染本机的环境变量。
  • Nios 套件的工具部分是编译好的程序,部分是脚本。为了降低跨平台维护软件的难度,这部分脚本就使用了 Shell 书写,要在 Windows 上运行 shell 脚本,必须有恰当的命令行(例如 bash)。

在 Microsoft 推出 适用于 Linux 的 Windows 子系统 (WSL) 之前,在 Windows 上运行 bash 需要借助 Cygwin,所以 Intel 的不少脚本都是针对 Cygwin 写的。

后来 WSL 成为主流,单独安装一个 Cygwin 已经没有必要,于是 Quartus 不再内置 Cygwin,转而在安装的时候提醒用户自行安装 WSL。但是Intel 没有做好脚本的兼容(可能是因为 WSL 可以运行不同的发行版、WSL 默认 shell 不是 Bash、WSL 本身迭代快)。具体表现为:Nios Command Shell 正确启动了,但是环境变量没有被完全导入,进而找不到需要的工具。或者 WSL 下某些脚本不会加上.exe 拓展名,导致没法启动指定的程序等等等等。

总之,就是很吃💩!Intel 这波操作相当于让我在 Linux 和 Windows 之间反复横跳...体验甚至不如继续内置个 Cygwin,经过半个下午的调试,大概总结了一下 Workaround。

下载 SOF 文件

和以前一样,使用 Quartus 的 Programmer 把 SOF 文件通过 JTAG 下载进去就可以了。

下面这个脚本是官方给的,实际上是通过命令行把 SOF 下载进去,换汤不换药。但是新版本 Quartus 不能使用,主要是因为新版不再自带 Cygwin,转而使用 WSL。大家可以酌情参考。

@ REM ######################################
@ echo off

@set QUARTUS_BIN=%QUARTUS_ROOTDIR%\\bin
@if exist %QUARTUS_BIN%\\quartus_pgm.exe (goto DownLoad)

@set QUARTUS_BIN=%QUARTUS_ROOTDIR%\\bin64
@if exist %QUARTUS_BIN%\\quartus_pgm.exe (goto DownLoad)


:DownLoad
%QUARTUS_BIN%\\jtagconfig.exe > %%JTAG_INFO
IF ERRORLEVEL 1 goto error
setlocal enableextensions

rem check DE-SoC Board
for /f "tokens=2" %%a in (
%%JTAG_INFO
) do (
if %%a == DE-SoC goto Board_Ready
)

echo Can not find DE-SoC board, please check the hardware.
goto end


:Board_Ready
rem Find out device index
set /a Index=0
for /f "tokens=1" %%a in (
%%JTAG_INFO) do (
if %%a == 02D120DD goto Find_FPGA
set /a Index+=1
)

echo Can not find 5CSE(BA5|MA5)/5CSTFD5D5 FPGA Device, please check the hardware.
goto end


:Find_FPGA
::echo INDEX = %Index%
if %Index% == 1 goto Rev_B
if %Index% == 2 goto Rev_F

echo Device out of range(1 or 2), please check the hardware.
goto end


:Rev_B
echo ===========================================================
echo "DE1-SoC Rev B"
echo ===========================================================
goto Program_FPGA


:Rev_F
echo ===========================================================
echo "DE1-SoC Rev F"
echo ===========================================================


:Program_FPGA
@ REM ######################################
@ REM # Variable to ignore <CR> in DOS
@ REM # line endings
@ set SHELLOPTS=igncr

@ REM ######################################
@ REM # Variable to ignore mixed paths
@ REM # i.e. G:/$SOPC_KIT_NIOS2/bin
@ set CYGWIN=nodosfilewarning
%QUARTUS_BIN%\\quartus_pgm.exe -m jtag -c 1 -o "p;DE1_SoC_Audio.sof@%Index%"
@ set SOPC_BUILDER_PATH=%SOPC_KIT_NIOS2%+%SOPC_BUILDER_PATH%
@ "%QUARTUS_BIN%\cygwin\bin\bash.exe" --rcfile ".\DE1_SoC_Audio.sh"
goto end

:error
echo Please Check your USB Blaster!!


:end
echo Goodbye!!
del %%JTAG_INFO /F
endlocal

pause

下载 ELF 文件

ELF 文件需要使用 Nios 开发套件中的 nios2-downloadnios2-terminal 才能下载、调试。

需要说明的是,Nios 开发套件中的工具是要在 Nios II Command Shell 中才能使用。命令行启动脚本在 path\to\intelFPGA_lite\20.1\nios2eds\Nios II Command Shell.bat

这里同样给出下载 ELF 的官方脚本,尽管已经不能在新版使用:

# file: nios2_sdk_shell_bashrc

"$SOPC_KIT_NIOS2/nios2_command_shell.sh" nios2-download DE1_SoC_Audio.elf -c 1 -r -g
"$SOPC_KIT_NIOS2/nios2_command_shell.sh" nios2-terminal -c 1 

# End of file

新版已经迁移到了 WSL 上,所以我们通过上面提到的启动脚本进入 Nios II Command Shell,然后配置环境变量:

export PATH="$(wslpath "path\to\intelFPGA_lite\20.1\nios2eds\bin\gnu\H-x86_64-mingw32\bin"):$PATH" \
export PATH="$(wslpath "path\to\intelFPGA_lite\20.1\nios2eds\bin"):$PATH" \
export PATH="$(wslpath "path\to\intelFPGA_lite\20.1\quartus\bin64"):$PATH"

随后正常调用下载和调试命令:

nios2-download DE1_SoC_Audio.elf -c 1 -r -g
nios2-terminal.exe -c 1 

其他问题

如果还是各种报 “找不到文件”,可能是 .exe 后缀在 WSL 下没有被正确添加。

分析 nios2-download 脚本,最开头有这么几行:

uname=$(uname -r)
if [[ $uname =~ "Microsoft" ]]; then
    _IS_WSL=1
    windows_exe=.exe
fi

作用很显然就是判断当前是不是 WSL 环境,是的话就标记一下,同时给 Windows 的可执行文件添加 .exe 后缀。

但是在我的 Kali 上这段脚本并不生效(zsh/bash 都无效),只能说 Intel 活干的太不细致了((

解决方法是直接把 iffi 所在两行全部删掉,即钦定当前 Shell 为 WSL 环境。

_IS_WSL=1
windows_exe=.exe

至于是否能够通过自行安装 Cygwin 解决问题,我也不知道,请大家自行测试。