掌握FPGA嵌入式设计:实战实施指南
更强大的FPGA和更高效的编程环境让FPGA实施广泛普及,但使用FPGA仍让人望而生畏。

编者注:随着智能产品设计涌现先进算法,开发者常难以实现能满足相关算法处理需求的嵌入式系统。FPGA能提供所需性能,但FPGA设计长期被视为FPGA编程专家的专属领域。如今,更强大的FPGA和更有效的开发环境使FPGA开发广泛普及。本节选自Jim Ledin著作《架构高性能嵌入式系统》第4章,作者全面回顾FPGA器件、实现语言、开发流程,并详细演示如何在自有设计中实施FPGA。完整节选分以下系列:
1: 硬件资源
2: 实现语言
3: 开发流程
4: 构建项目
5: 实现(本文)
改编自《架构高性能嵌入式系统》,Jim Ledin著。
仿真测试逻辑行为
在FPGA中运行前,必须用仿真测试逻辑行为。因为在仿真环境发现修复问题比在FPGA内部运行逻辑容易得多。Vivado仿真工具极好地呈现电路行为:
- 在Sources子窗口,右键Simulation Sources选Add Sources…:

图4.18 – Simulation Sources的Add Sources…菜单选择
- 在Add Sources对话框,确保选中Add or create simulation sources,点Next。
- 在Add or Create Simulation Sources对话框,点Create File。
- 输入文件名vhdl,点OK。
- 点Finish关闭Add or Create Simulation Sources对话框,在Define Module对话框点OK,询问是否确定使用这些时点Yes。
- 双击Simulation Sources下的Adder4 TestBench (Behavioral) (Adder4TestBench.vhdl)。删除vhdl编辑器窗口自动填充内容,输入以下代码到Adder4TestBench.vhdl编辑器:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity ADDER4_TESTBENCH is end entity ADDER4_TESTBENCH; architecture BEHAVIORAL of ADDER4_TESTBENCH is component ADDER4 is port ( A4 : in std_logic_vector(3 downto 0); B4 : in std_logic_vector(3 downto 0); SUM4 : out std_logic_vector(3 downto 0); C_OUT4 : out std_logic ); end component; signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(3 downto 0); signal s : std_logic_vector(3 downto 0); signal c_out : std_logic; signal expected_sum5: unsigned(4 downto 0); signal expected_sum4: unsigned(3 downto 0); signal expected_c : std_logic; signal error : std_logic; begin TESTED_DEVICE: ADDER4 port map ( A4 => a, B4 => b, SUM4 => s, C_OUT4 => c_out ); TEST: process begin -- 测试所有两个4位加数组合(共256测试) for a_val in 0 to 15 loop for b_val in 0 to 15 loop -- 设置ADDER4组件输入 a <= std_logic_vector(to_unsigned(a_val, a'length)); b <= std_logic_vector(to_unsigned(b_val, b'length)); wait for 1 ns; -- 计算两个4位值的5位和 expected_sum5 <= unsigned('0' & a) + unsigned('0' & b); wait for 1 ns; -- 将和拆分为4位输出和进位位 expected_sum4 <= expected_sum5(3 downto 0); expected_c <= expected_sum5(4); wait for 1 ns; -- 'error'信号仅在出错时置1 if ((unsigned(s) = unsigned(expected_sum4)) and (c_out = expected_c)) then error <= '0'; else error <= '1'; end if; -- 内层循环每次10ns wait for 7 ns; end loop; end loop; wait; end process TEST; end architecture BEHAVIORAL;
该代码通过向Adder4组件的A4和B4输入施加所有4位数组合,验证4位加法器功能。将Adder4的SUM4和C_OUT4输出与相同输入独立计算的期望值比较。每次加法后,若输出匹配期望值,error信号置0,否则置1。
Adder4TestBench.vhdl代码使用嵌套for循环向被测Adder4组件施加所有测试输入组合,类似传统软件代码。仿真模式运行的测试代码不可综合,不纯粹代表硬件逻辑电路,可进行传统软件式操作如for循环迭代执行。
然而如物理电路,测试平台代码中用<=运算符赋值的信号不能在同一时刻用于后续表达式。因为仿真环境反映真实世界传播延迟效应,即使在微小FPGA器件内也显著。测试平台代码中三个wait for 1 ns;语句暂停电路操作以允许传播延迟。这些1ns延迟为紧接wait语句前计算的信号值提供传播时间,以便后续语句使用。内层循环末尾wait for 7 ns;暂停让我们在信号波形显示中清晰看到每次仿真循环迭代结果。
- 右键Simulation Sources下的Adder4 TestBench (Behavioral) (Adder4TestBench.vhdl)选Automatic Update and Compile Order。这设定ADDER4_TESTBENCH为仿真运行的顶层对象:

图4.19 – 设定Automatic Update and Compile Order菜单选择
- 点Run Simulation,再在Flow Navigator窗口选Run Behavioral Simulation进入仿真模式。若未保存编辑器文件,会提示保存。点Save。仿真随即运行:

图4.20 – Run Behavioral Simulation菜单选择
- SIMULATION窗口打开时,点击标题为Untitled 1的仿真输出窗口最大化按钮:

图4.21 – 仿真结果窗口
内层循环每次总仿真时间10ns。Adder4TestBench.vhdl中内层循环256次,仿真运行时间2560ns。
- 顶部工具栏设仿真运行时间2560ns(步骤1),按左向重启按钮(步骤2),再按右向运行按钮跑2560ns(步骤3),最后按Zoom Fit按钮(步骤4)缩放仿真输出数据范围适应窗口:

图4.22 – 仿真运行开始至结束的结果
可用放大镜图标放大任意波形点观察测试期间每次加法操作结果。例如下图显示十进制6和2相加得结果8,进位0。这些值匹配期望值,导致error置0。error信号在所有256测试用例中均为0,表明逻辑电路通过所有测试:

图4.23 – 仿真结果放大视图
- 点蓝色SIMULATION栏上方X关闭仿真模式。询问是否关闭仿真时点OK。
通过行为测试后,我们将定义设计中使用的I/O信号。
定义I/O信号
下一步将电路输入输出连接到Arty板硬件器件。输入为板上拨码开关和按键,输出为LED。
以下步骤创建约束文件,描述FPGA器件使用的I/O引脚及Arty板上连接这些引脚的功能。约束文件扩展名为xdc:
- 在Sources子窗口,右键Constraints选Add Sources…。
- 在Add Sources对话框,确保选Add or create constraints,点Next。
- 在Add or Create Constraints对话框,点Create File。
- 输入文件名Arty-A7-100.xdc(或Arty-A7-35.xdc视器件而定),点OK。
- 点Finish关闭Add or Create Constraints。
- 展开Constraints源树,双击Arty-A7-35.xdc。
- Digilent为Arty A7板提供预填充约束文件。访问https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Arty-A7-35-Master.xdc复制浏览器窗口全部内容到Vivado中Arty-A7-35.xdc编辑器窗口。若器件适用,改用https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Arty-A7-100-Master.xdc。
- 约束文件中所有I/O引脚被#注释掉。通过移除每行开头#字符取消注释。我们将使用以下节列出的Arty-A7-100.xdc文件中的引脚:Switches、RGB LEDs(仅led0_g,第一个绿色LED)、LEDs和Buttons。下图显示取消注释后的这些行:

图4.24 – 约束编辑器窗口
下节将创建顶层VHDL文件,将加法器代码与I/O器件接口化。
创建顶层VHDL文件
我们将创建顶层VHDL文件,将4位加法器组件连接到对应板级I/O信号:
- 在Sources子窗口,右键Design Sources选Add Sources…。
- 在Add Sources对话框,确保选Add or create design sources,点Next。
- 在Add or Create Design Sources对话框,点Create File。
- 输入文件名vhdl,点OK。
- 点Finish关闭Add or Create Design Sources对话框,在Define Module对话框点OK,询问是否确定使用这些时点Yes。
- 双击Design Sources下的vhdl。删除ArtyAdder.vhdl编辑器窗口自动填充内容,输入以下代码到ArtyAdder.vhdl编辑器:
-- 加载标准库 library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity ARTY_ADDER is port ( sw : in STD_LOGIC_VECTOR (3 downto 0); btn : in STD_LOGIC_VECTOR (3 downto 0); led : out STD_LOGIC_VECTOR (3 downto 0); led0_g : out STD_LOGIC ); end entity ARTY_ADDER; architecture BEHAVIORAL of ARTY_ADDER is -- 引用前面定义的4位加法器组件 ADDER4 is port ( A4 : in std_logic_vector(3 downto 0); B4 : in std_logic_vector(3 downto 0); SUM4 : out std_logic_vector(3 downto 0); C_OUT4 : out std_logic ); end component; begin ADDER : ADDER4 port map ( A4 => sw, B4 => btn, SUM4 => led, C_OUT4 => led0_g ); end architecture BEHAVIORAL;
此代码将Arty-A7-100.xdc中命名的I/O器件信号名sw(4拨码开关)、btn(4按键)、led(4单色LED)、led0_g(第一个多色LED绿色通道)映射到ADDER4输入输出。
VHDL不区分大小写,但Vivado处理xdc约束文件区分大小写。xdc文件中定义的I/O器件名称大小写在VHDL文件引用时必须完全一致。具体而言,因约束文件中为小写,本文件VHDL中I/O信号名必须小写。
我们现在准备为Arty板综合、实现并编程设计。
综合实现FPGA比特流
也可选Generate Bitstream,Vivado将执行综合、实现、比特流生成所有必需步骤,无需进一步用户干预。若发生致命错误,过程停止并显示错误信息。执行以下步骤生成比特流:
- 点Generate Bitstream开始构建。可能被问是否保存文本编辑器。点Save。可能被告知无实现结果可用,询问是否可启动综合和实现。点Yes:

图4.25 – Generate Bitstream菜单选择
- Launch Runs对话框将出现。可选Number of jobs值至计算机处理器核心数。用更多核心加快过程,但若想在漫长构建期间继续使用机器可能拖慢系统。点OK开始构建:

图4.26 – Launch Runs对话框
- 构建过程中,Vivado在主窗口右上角显示状态。必要时可点Cancel取消构建:

图4.27 – 编译状态显示
- 构建完成,假设无致命错误,将出现Bitstream Generation Completed对话框。虽提供其他选项,我们直接下载比特流到Arty板。选Open Hardware Manager点OK:

图4.28 – Bitstream Generation Completed对话框
接下来将比特流下载进FPGA。
下载比特流到开发板
执行以下步骤将比特流下载到Arty A7板:
- HARDWARE MANAGER对话框出现,指示No hardware target is open。
- 用USB线连接Arty A7-35或A7-100板到电脑。等几秒板被识别,点Open target,再Auto Connect:

图4.29 – Open target和Auto Connect选择
- 几秒后Vivado应指示板已连接。点Program device下载FPGA比特流到Arty。将提示选择比特流文件。若使用本例相同目录结构,文件位于C:/Projects/ArtyAdder/ArtyAdder.runs/impl_1/ARTY_ADDER.bit:

图4.30 – Program Device对话框
- 点Program下载程序到FPGA器件并启动
- 现可用Arty I/O测试程序操作。将四个拨码开关置off位置(向相邻板边移动),不按四个按键。四个绿色LED应全灭。
- 拨动任意单个开关或按任意单个按键,对应绿色LED应点亮。拨动任意开关组合同时按任意数量按键,将对应4位数相加并点亮LED显示。若有进位(如同时拨动SW3和按BTN3),绿色进位LED将点亮。
此处编程过程将程序存入FPGA RAM。若给FPGA板循环上电,需重复编程过程重载程序。或者,可按下节所述将FPGA配置文件存入板载闪存。
将比特流编程到板载闪存
为使FPGA每次上电都配置,FPGA配置文件必须存入板载闪存。若安装MODE跳线,FPGA上电将尝试从板载闪存下载配置文件。该内存位于Artix-7 FPGA旁边的独立芯片。按以下步骤将配置文件编程到闪存:
- 若Arty板MODE跳线未安装,请安装
- 右键Generate Bitstream选Bitstream Settings…。
- 在Settings对话框,勾选-bin_file旁复选框,点OK:

图4.31 – Bitstream settings对话框
- Vivado主对话框点Generate Bitstream重复比特流生成过程。Bitstream Generation Completed对话框出现时点Cancel
- 在Hardware对话框,右键FPGA部件号(xc7a100t_0)选Add Configuration Memory Device…:

图4.32 – Add Configuration Memory Device…菜单选择
- 在Search输入s25fl127。应出现一个匹配部件号。选中并点OK:

图4.33 – Add Configuration Memory Device对话框
- 将出现对话框询问Do you want to program the configuration memory device now? 点OK。
- 随即出现Program Configuration Memory Device对话框请求配置文件名。点Configuration file右侧…按钮选C:/Projects/ArtyAdder/ArtyAdder.runs/impl_1/ARTY_ADDER.bin. 点OK:

图4.34 – Program Configuration Memory Device对话框
- 编程过程需几秒。文件编程进板载闪存后应收到成功指示:

图4.35 – Program Flash complete对话框
此后,每次循环板电源,4位加法器程序将加载运行。用我们配置文件加载设置,程序加载需很长时间。为避免等待FPGA加载程序,可通过以下步骤提高配置文件加载速度:
- 在Flow Navigator选Open Synthesized Design。
- Vivado主菜单选Tools/Edit Device Properties…。
- General标签,设Enable Bitstream Compression为TRUE。
- Configuration标签,设Configuration Rate (MHz)为33,点OK。
- 再次生成比特流,按前述编程闪存。需移除配置存储器器件并重新添加以显示重新编程选项。
- 关闭Hardware Manager。
- 拔掉Arty板USB线再插入。程序上电几乎瞬间开始运行。
本节展示简单组合逻辑与FPGA I/O引脚信号交互示例。旨在让您熟悉Vivado工具套件,演示工具如何执行完整FPGA开发周期。
总结
本章从FPGA在实时嵌入式系统架构中的有效应用讨论开始,继续描述标准FPGA器件及其包含的低级组件。介绍FPGA设计语言范围,包括HDL、框图方法、C/C++等流行软件编程语言。概述FPGA开发流程。章节以完整FPGA开发周期示例结束,从需求陈述到低成本FPGA开发板上功能系统实现。
完成本章,您应了解FPGA如何在实时嵌入式系统架构中有效应用,理解FPGA集成电路内部组件。学习FPGA算法设计用编程语言、FPGA开发周期步骤,理解FPGA开发流程步骤序列。
下章将扩展FPGA开发流程,提供包含FPGA的实时嵌入式系统架构完整方法。也将开始开发原型高性能嵌入式系统——数字示波器,作为后续章节示例。
经Packt Publishing许可转载。版权所有©2021 Packt Publishing

Jim Ledin是Ledin Engineering, Inc. CEO。Jim精通嵌入式软硬件设计、开发、测试,也擅长嵌入式系统网络安全评估和渗透测试。爱荷华州立大学航空航天工程学士,佐治亚理工学院电子计算机工程硕士。加州注册专业电气工程师,CISSP、CEH、CPT认证。
相关内容:
- FPGA嵌入式设计:硬件资源
- FPGA嵌入式设计:实现语言
- FPGA嵌入式设计:开发流程
- 开源工具助简化FPGA编程
- 在FPGA或ASIC中实现浮点算法
- 利用FPGA进行深度学习
- 软件工具将GPU代码迁移至FPGA用于AI应用
订阅Embedded周报,获取更多嵌入式内容。
嵌入式
- 蜡笔给3D打印件上色:创新后处理技法
- 专访ANSYS首席技术专家:仿真软件如何赋能金属3D打印成功
- 先进增材制造软件助力产能最大化
- 嵌入式系统设计:步骤、原则与现实应用
- 利用嵌入式AI将大数据转化为可执行智能洞察
- 掌握USB-C:高速数据与电力传输的设计挑战与实用方案
- 重塑技术未来的嵌入式设计趋势
- Foundries.io志做IoT界Red Hat:处理器无关Linux与Zephyr方案
- Clientron PST650:一体化 POS 终端,集成热敏打印机,面向酒店与零售
- MAXREFDES220#:基于光学传感器的无袖带血压监测参考设计
- FPGA 实现语言:从 VHDL、Verilog 到高层 C/C++
- 高性能嵌入式系统的 FPGA 硬件资源详解