这一篇在干嘛?
这一篇带你把 FPGA 工程从「接到一个想法」到「板上跑起来」的完整九步流程走一遍。我们以移远 FPGA 大赛实际使用的安路 EG4S20 器件和安路 TD(Tang Dynasty)开发工具为参照,把每一步「做什么、为什么、跳过会怎样、在工具里点什么」都讲透。第一次做完整工程的同学,建议先通读本篇建立全局观,再动手开工。
九步总览
先看一眼全景。FPGA 开发和写单片机程序最大的不同,在于它不只是「写代码」,而是一条从抽象到物理的流水线:你写的 Verilog 代码只是起点,最终要变成 FPGA 芯片内部成千上万个查找表(LUT,Look-Up Table)、触发器(Flip-Flop)和金属连线的真实配置。这条流水线共九步:


| 步骤 | 干什么 | 输入 → 输出 | 对应 TD 操作 | 不做会怎样 |
|---|---|---|---|---|
| ① 需求分析 | 想清楚要做什么 | 想法 → 需求清单 | 纸面工作 | 做到一半发现功能/资源对不上,推倒重来 |
| ② 器件选型、框架划分 | 选芯片、搭模块框图 | 需求清单 → 方案框图 | 新建工程时选定器件 | 资源不够或严重浪费;模块写成一锅粥 |
| ③ 设计文本输入 | 写 Verilog / 画框图 / 用 IP | 框图 → RTL 代码 | 添加设计文件(.v) | 没有输入,一切免谈 |
| ④ 功能仿真 | 验证逻辑对不对 | RTL + Testbench → 波形 | 借助 ModelSim 等仿真器 | 逻辑错误带进硬件,浪费下板调试时间 |
| ⑤ 分析综合 | 语法检查 + RTL→门级 | RTL → 门级网表 | Synthesize(综合) | 无法进行后续流程 |
| ⑥ 布局布线 | 网表落到芯片资源上 | 网表 → 物理布局 + 时序报告 | Place & Route(布局布线) | 生成不了比特流 |
| ⑦ 时序仿真 | 带真实延时的再验证 | 网表 + 延时 + Testbench → 波形 | 布局布线后仿真 | 高速设计中「仿真对、上板错」 |
| ⑧ 时序分析、约束 | 告诉工具速度目标并检查 | SDC 约束 → 时序报告 | 添加 .sdc 时序约束 | 工具盲目布线,时序违例悄悄埋雷 |
| ⑨ 板级验证 | 下载到真板子实测 | .bit 比特流 → 实测结果 | Programmer 下载 | 永远不知道设计到底行不行 |
几点初学者常见疑问,先在这里说清:
- 这九步必须严格按顺序走吗? 大方向是的——综合必须在仿真之后、布局布线必须在综合之后,这是工具链的数据依赖。但它是循环迭代的:板级验证发现问题,往往要回到③改代码,甚至回到①重新审视需求。真实工程就是在「③→④→⑤→⑥→⑨」这条主循环里转好几圈。
- 每一步都要做吗? ①②③⑤⑥⑨ 是必做的骨架;④强烈建议做;⑦⑧在大规模、高速度的项目里才严格要求,入门阶段的小设计可以简化(第⑧步会详细说)。
- TD 工具包办哪些? 安路 TD 负责综合、布局布线、生成和下载比特流这条「实现链路」;功能仿真和时序仿真通常搭配第三方仿真器(如 ModelSim)完成。所以你会看到,九步里有一半是在 TD 里点按钮,另一半在纸面和仿真器里完成。
常见坑:把 FPGA 开发当成「写完代码直接下板」
很多初学者从单片机转过来,习惯改一行代码就烧录实测。在 FPGA 里这样做效率极低:编译一次(综合+布局布线)可能要几分钟到几十分钟,而板上的问题你根本看不到内部信号。正确的姿势是:先仿真后下板,让问题在波形里暴露,而不是在杜邦线上猜。
① 需求分析

做什么。 幻灯片给出的正式定义是:通过访谈、问卷调查、需求研讨会等方法,收集、分析、整理用户对项目的期望和要求,最终形成详细、明确、可验证的需求规格说明书(Requirement Specification)或用户故事(User Stories)。翻译成学生竞赛的话:把「我要做一个 XXX」写成一份清单——实现哪些功能、输入输出是什么、性能指标是多少。
为什么需要。 幻灯片里那句「用我们自己的话来说」非常实在:对想设计的项目做总体分析,明确用户需求,确定要实现的功能、需要多少资源、I/O 口的使用量、接口电平和系统功耗等,在此基础上才能进行 FPGA 选型。需求分析是后面所有步骤的输入——第②步靠它选芯片,第③步靠它划模块,第⑨步靠它定测试标准。它同时还是在为「验收」立法: later 板级验证时,判断你做没做成的依据就是当初写下的这份清单。
具体要写清哪些东西? 给参赛者的最小模板:
- 功能列表:例如「 HDMI 输出 720p 测试图案 + 按键切换图案」;
- 接口清单:每个外设用什么协议接(HDMI、UART、SPI、按键 GPIO),速率多少、电平多少(3.3V 还是 2.5V?这直接决定 IO Bank 的电平约束);
- 性能指标:系统时钟多少 MHz、像素时钟多少、响应延迟要求;
- 资源估算:大概多少 LUT、多少 BRAM(块存储器)、要不要 DSP 乘法单元——不必精确,量级对即可。
跳过会发生什么。 典型惨案:代码写了一半才发现 EG4S20 的 BRAM 不够放两帧图像缓存;或者画完原理图才发现按键接的引脚和原计划的 LED 复用了。这些事故的根源都是第①步没数清楚 I/O 和资源。需求分析阶段返工的成本是「改一段话」,到了板级验证阶段再返工,成本就是「改一个工程」。
在 TD 工具里对应什么操作? 这一步是纯纸面工作,TD 里没有按钮。但它的产出会直接决定你在 TD「新建工程」对话框里选哪个器件、建多少引脚约束——可以说这一步的输出,就是第②步的输入。
组队参赛的补充建议: 需求分析也是分工的依据。把功能清单逐项排优先级(必须实现/争取实现/锦上添花),时间不够时先保「必须项」。一个只实现了核心功能但稳定运行的作品,在评审台上远比一个功能全开但频频死机的作品更有说服力。清单写完贴在工位上,每次改动需求都更新版本号——需求漂移(Requirement Creep)是竞赛项目烂尾的头号原因。
常见坑:需求写成「愿望」而不是「规格」
「做一个炫酷的显示系统」不是需求,「720p@60Hz、按键切换 3 种测试图案、UART 可调颜色」才是。不可验证的需求等于没有需求——你到了板级验证阶段会发现根本没法判断「炫酷」达没达标。
② 器件选型、系统框架划分

这一步其实是两件事,幻灯片也是分开讲的。
器件选型:硬件设计的基础。 幻灯片指出,选型直接影响产品的性能、成本、可靠性以及后续的生产维护,要根据系统的功能和复杂度,在工作速度、器件资源、成本、连线可布性之间权衡。对大赛选手来说,这步常常已经被「钦定」——比赛统一提供基于安路 EG4S20(约 20K 级 LUT4、内置 BRAM 和 DSP、支持 LVDS 等多种电平标准的国产 FPGA)的开发板,配安路 TD 工具链开发。但「被钦定」不等于「不用分析」:你仍然要在 EG4S20 的资源预算内审视自己的需求——它跑不跑得动你要的时钟频率、BRAM 装不装得下你的缓冲、引脚够不够接你的外设。如果估算下来明显超资源,就该在第①步砍功能,而不是硬着头皮写到一半发现放不下。
系统框架划分:硬件设计的核心。 幻灯片说得很准:框架决定了系统的整体结构和功能实现方式,一般采用**自顶向下(Top-Down)**的设计方法——把系统分成若干基本单元,再把每个基本单元划分为下一层次的基本单元,一直分到可以直接使用 EDA 元件库为止。
展开讲就是一棵模块树:
顶层 top.sv(负责连线与对外接口)
├── 时钟/复位管理(PLL 生成像素时钟等)
├── 显示驱动模块(HDMI 时序产生)
├── 图案生成模块(测试图形逻辑)
├── 按键消抖模块
└── UART 命令解析模块
每划出一个模块,就明确了它的输入输出端口和职责边界。分到最底层时,每个小模块应该简单到「一眼能写出、单独能仿真」。这也是后面写 Testbench 的基础——每个底层模块都能独立验证。
跳过会发生什么。 不做框架划分的工程,通常长成这样:一个几千行的 top.v,所有逻辑揉在一起,改一处崩全身,仿真没法分层做,组队时两人没法分工。框架划分本质上是把「一个大难题」换成「一堆小难题」,这是工程能力和「堆代码」的分水岭。
在 TD 工具里对应什么操作? 选型对应 TD 新建工程向导中的器件选择页(Family 选 EG4S20、Package 选具体封装如 BG256、Speed Grade 按板卡手册填)。框架划分本身在纸上或画图工具里完成,产出模块框图和端口约定,供第③步逐个实现。
③ 设计文本输入

做什么。 幻灯片说,设计输入就是代码编写和原理图设计的过程,方法有三种:原理图输入、硬件描述语言输入、IP 核输入。这三种方式今天的主次地位要讲清楚:
- 硬件描述语言(HDL,Hardware Description Language)输入——绝对主力。用 Verilog 或 VHDL 以文本方式描述电路行为和结构。本篇后续教程都以 Verilog 为例。你写的
always @(posedge clk)不是「程序」,而是对一组触发器和组合逻辑的描述,这个心智转换是初学者的第一道坎。 - 原理图(Schematic)输入——把与门、或门、模块符号像画电路图一样连起来。直观但难以维护、难以版本管理,现在只适合顶层把几个大模块「连线」的场合,或教学演示。
- IP 核(IP Core)输入——使用厂商或第三方封装好的成熟模块,如 PLL 时钟管理、FIFO、RAM 等。TD 里集成了 IP 生成器,配置几个参数就能生成一个 PLL 模块,比自己手搓可靠得多。原则是:通用且关键的基础模块用 IP,业务逻辑用 HDL 自己写。
为什么需要。 这一步产出 RTL(Register Transfer Level,寄存器传输级)代码,是整条工具链的原料。第②步框图里的每一个底层模块,在这里变成一个 .v 文件。
给初学者的三条工程建议:
- 模块化:按第②步的框图一模块一文件,文件名=模块名,别偷懒全塞一个文件;
- 可综合意识:你写的每一行都要问「这会综合成什么电路」。
assign出组合逻辑,always @(posedge clk)出触发器;而#10延时、初始大数组这类东西是给仿真用的,别写进可综合代码; - 同步设计:全工程尽量使用统一时钟沿,复位策略想清楚(EG4S20 常用异步低有效复位,按板卡原理图来),这会让后面第⑧步的时序分析干净很多。
跳过会发生什么。 这步没法跳过——没有设计输入,综合器无米下锅。真正会发生的「事故」是输入质量差:不可综合的语句、悬空端口、位宽不匹配,这些都会在下一步综合时以 error 或 warning 的形式还给你。
在 TD 工具里对应什么操作? 在 TD 的工程管理器中右键添加设计文件(Add Design File),把 .v 文件逐个加入工程,并把顶层模块设置为 Top。注意 TD 对文件编码敏感,建议源码用 UTF-8 或 GBK 之一并保持全工程统一,注释乱码 often 从这里开始。
④ 功能仿真

做什么。 幻灯片说,功能仿真就是常说的 RTL 仿真,是在理想状态下对设计实现的功能进行验证,把描述变为 RTL 级行为。展开讲:功能仿真不加载任何真实延时,假设导线零延时、寄存器零延时,只回答一个问题——你的逻辑功能对不对?
怎么仿真? 关键概念是 Testbench(测试平台):一个「不打算综合、只用来给被测模块喂激励」的 Verilog 文件。它实例化你的被测模块(DUT,Design Under Test),产生时钟和复位,按协议打出一串输入,再用 $monitor/波形窗口观察输出。初学者模板:
module tb_counter;
reg clk, rst_n;
wire [7:0] cnt;
counter u_dut(.clk(clk), .rst_n(rst_n), .cnt(cnt));
always #5 clk = ~clk; // 100MHz 时钟
initial begin
clk = 0; rst_n = 0;
#20 rst_n = 1; // 复位 20ns 后释放
#500 $finish;
end
endmodule跑完仿真,在波形里逐项核对:复位后计数值清零了吗?计数到 255 会正确回绕吗?每个使能信号到来的下一拍行为符合设计吗?
为什么需要。 仿真是 FPGA 开发里性价比最高的一步:波形里每个信号的每一拍都看得见,改一次仿真只要几秒钟。同样的错误,仿真里 3 秒定位;带到板子上,你可能拿着示波器查一下午——而且板上你根本看不到内部信号(除非加 ILA 之类的调试核,那是后话)。
跳过会发生什么。 逻辑错误流进综合和下板环节。最难受的是那种「十个模块对了一个」的系统——板上表现为时好时坏、毫无规律,而你没有任何内部可见性。竞赛时间紧,省下的半小时仿真往往要在板级调试中加倍还回去。
在工具链里对应什么操作? TD 本身不带仿真器,搭配第三方仿真器使用:常用 ModelSim(或其入门版)、开源的 iverilog+GTKWave 等。流程是:写好 Testbench → 在仿真器里编译 RTL 与 Testbench → 运行仿真 → 看波形。TD 与 ModelSim 可以联动配置,也可以完全独立操作。对初学者,先用 iverilog 这类轻量工具把 counter、状态机这些小模块仿明白,性价比极高。
仿真要看到什么程度才算过关? 给一个可操作的标准:Testbench 覆盖需求清单里的每一条功能项,并额外加上 3 类边界激励——复位在运行中途打入、计数/缓存到达最大值后的回绕、快速连续的输入切换。每一条在波形里亲眼确认过,这个模块才有资格进入综合。坚持这个标准,你会发现板级调试的时间大幅缩短。
常见坑:Testbench「自欺式验证」
只验证「正常路径」的 Testbench 是最常见的假验证:从不测复位中途打进来、计数器溢出回绕、异步输入抖动这些边角。写 Testbench 时请刻意「使坏」——你的任务是找到设计的错,而不是证明它对。
⑤ 分析综合

做什么。 幻灯片说,分析综合是对代码的基本语法进行错误检查,并将 RTL 级行为变为基本的门级电路。这两件事分别是:
- 分析(Elaboration/语法检查):编译你的 Verilog,揪出语法错误、端口连接不匹配、位宽问题。这一步过的代码才谈得上「是个电路」。
- 综合(Synthesis):把 RTL 描述翻译成由目标器件基本单元组成的门级网表(Netlist)。对安路 EG4S20 来说,基本单元是 LUT4(4 输入查找表)、触发器、BRAM、DSP 等。例如你写
c = a & b | d;,综合器会把它映射进某个 LUT4 的真值表;你写一个 8×8 乘法,它可能被安排到 DSP 单元里。
为什么需要。 综合是从「人类语言」到「电路语言」的翻译器,没有它,你的代码对 FPGA 而言只是一段文本。综合还有一个重要副产物:资源利用率报告——用了多少 LUT、多少 FF、多少 BRAM。这份报告是第②步资源估算的「事后对账」,如果利用率超过 80%,就要警惕布线困难了。
看懂综合结果的两个要点:
- Warning 不要无视。 综合器的 warning 常常预告着板上的诡异行为:「信号 xx 被优化掉了」往往意味着你忘了接输出;「检测到组合环」(combinational loop)则几乎一定是设计错误。
- 综合不保证时序。 综合只保证「逻辑功能等价」,不考虑连线延时。你 100MHz 的设计能不能跑,要等第⑥步布完线才知道——这也是为什么仿真和综合都通过还不够。
跳过会发生什么。 无可跳过,它是实现链路的第一环。但初学者常犯的错是「综合通过就当万事大吉」——语法正确和逻辑正确是两回事,和时序正确更是三回事。
在 TD 工具里对应什么操作? 在 TD 中点击 Synthesize(综合)按钮(或在流程栏双击对应步骤)。综合完成后在 Message 窗口查看 error/warning,在报告里查看资源占用。注意:修改任何源文件后都要重新综合,TD 的增量编译会只重跑受影响的部分。
⑥ 布局布线

做什么。 幻灯片说,布局布线是对器件的引脚配置等极性进行检查,并且将门级电路转变为具体的物理电路,便于后续的下板验证。术语拆开看:
- 布局(Placement):把网表里的成千上万个 LUT4、触发器,分配到 EG4S20 芯片内部具体物理位置——哪个 LUT 坐落在哪一格、那个 BRAM 放哪个位置。布局好坏直接影响连线长度,进而影响速度。
- 布线(Routing):用芯片内部的金属连线资源把摆好的单元连接起来。FPGA 内部连线是分层的开关矩阵,布线器要在此中找到既通又不至于太慢的路径。
- 引脚配置检查:你在约束文件里指定的引脚(哪个信号从芯片哪个引脚进出、电平标准是什么)会在这里被核对——引脚写错、电平不匹配、违反 Bank 规则,都会在这一步报错。
为什么需要。 这是「抽象电路」变成「芯片里的真实配置」的一步。第⑨步要下载的比特流文件,就是布局布线结果的最终打包——布局布线不做,.bit 就无从谈起。布线完成后,工具还掌握了一个关键信息:每条连线的真实延时。这既是第⑦步时序仿真的输入,也是第⑧步时序分析的输入。
跳过会发生什么。 流程直接断链:没有布局布线就没有比特流,没有比特流就下不了板。此外,引脚约束错误也只有在布局布线时才被彻底检查出来——这是把「LED 接在非保留引脚」这类事故拦在上板前的最后一道闸。
在 TD 工具里对应什么操作? 在 TD 中点击 Place & Route(布局布线)按钮。此前需要完成引脚约束:TD 提供 Floorplan/IO 约束界面(图形化分配引脚、设置电平标准,存为物理约束文件),也可以手写约束。完成后查看时序摘要报告(第⑧步细讲),确认没有未收敛(不满足)的时序路径。布局布线耗时通常远超综合,大工程可能要等几分钟,改一次代码就重跑一次是常态——再次说明第④步仿真的重要性:能不出板的错,就别出。
常见坑:引脚约束照抄别人的
网上教程的引脚分配是「对应作者那块板」的。你手上的板子(如大赛统一的 EG4S20 开发板)原理图才是唯一权威:晶振接哪个脚、LED 接哪个脚、复位是高有效还是低有效,都必须从板卡原理图上逐个核对。抄错一个引脚,轻则功能不动,重则电源引脚冲突。
⑦ 时序仿真

做什么。 幻灯片讲得很完整:FPGA 时序仿真是在设计实现并经过布局布线后,使用布局布线后器件给出的模块和连线的延时信息,对电路的行为进行实际估价,验证电路在加入线延迟信息后是否仍然满足设计构想,确保设计的正确性和可靠性。
和第④步功能仿真对比着理解最清楚:
| 功能仿真(④) | 时序仿真(⑦) | |
|---|---|---|
| 时机 | 综合/布局布线之前 | 布局布线之后 |
| 输入 | RTL 代码 | 门级网表 + 延时文件(SDF) |
| 延时 | 零延时(理想) | 真实布线延时 |
| 回答的问题 | 功能对不对 | 时序够不够快 |
| 速度 | 快 | 慢得多 |
打个比方:功能仿真证明「菜谱是对的」,时序仿真验证「按这家厨房的炉灶火力,菜能在开席前出锅」。逻辑对但跑不到目标频率的电路,同样是废品。
为什么需要。 组合逻辑的传输延时 + 长连线的延时,可能让你的信号在时钟沿到来之前没来得及稳定,触发器锁到错误数据——功能仿真完全看不到这类问题,因为它假设所有延时为零。时序仿真把布局布线后每条路径的真实延时(工具会输出 SDF 标准延时文件)反标到仿真里,是「上板前最后一次全真演练」。
跳过会发生什么。 对低频小设计,往往真能侥幸跳过(工具的静态时序分析也覆盖了大部分风险,见第⑧步)。但对高速接口、多时钟域交错的设计,「仿真通过、上板跑飞」的经典事故就来自跳过时序仿真又没做时序分析。表现通常是:同样一份 bit 文件,这块板正常那块板花屏,或温度一高就出错——典型的边界时序问题。
在工具链里对应什么操作? 流程是:TD 完成布局布线后输出网表与延时信息 → 在仿真器(ModelSim 等)中用同一个 Testbench 重新仿真,只是这次编译的是布线后网表 + SDF 延时。Testbench 复用正是它设计良好的回报:同一份激励,既验过功能又验过时序。
⑧ 时序分析、时序约束

幻灯片开头就给了定位:时序分析、时序约束在进行大规模项目时才采用,一般设计可以不用进行这两个操作。这句话要正确理解——不是「永远不用学」,而是入门小设计可以简化;一旦你的设计上了规模(比如大赛里做完整的数据采集显示系统),这两步就从「选修」变「必修」。
时序分析(STA,Static Timing Analysis,静态时序分析)是检查什么? 幻灯片说,它检查设计中所有触发器(D 触发器)能否正常工作:同步端口(数据输入端口)的变化是否满足**建立时间(Setup Time)和保持时间(Hold Time)的要求;异步端口(如异步复位端口)的变化是否满足恢复时间(Recovery Time)和移除时间(Removal Time)**的要求。
翻译一下这几个词。触发器像一扇按节拍开关的门:数据必须在关门之前一段最小时间就位(建立时间),并在关门之后一段最小时间内保持不动(保持时间),否则锁存到亚稳态。工具会沿每一条「触发器→组合逻辑→触发器」的路径累加延时,和数据到达时刻比一比,得出时序余量(Slack):Slack 为正是通过,为负就是时序违例(Timing Violation)——意味着这条路径在目标频率下真的会出错。
时序约束是什么? 幻灯片说,它是设计者根据实际系统功能,通过约束文件提出时序要求,以便 FPGA 编译工具据此进行布局布线和时序分析。这里有个初学者最容易懵的点:工具不会读心术。你的晶振是 50MHz、你的 HDMI 像素时钟是 74.25MHz,工具并不知道——除非你在约束文件里告诉它。没有约束,工具按默认(甚至无目标频率)去布线,时序报告自然无从谈起「满不满足」。
约束文件通常写成 SDC(Synopsys Design Constraints)格式,最核心的一句是:
create_clock -name sys_clk -period 20.000 [get_ports {clk}] ;# 50MHz → 周期 20ns再加派生时钟(PLL 输出)、伪路径(set_false_path)、多周期路径等高级约束。请养成习惯:综合之前就写好 SDC,让约束全程参与综合与布局布线,而不是布完线再补——补写的约束无法改变已经发生的布线决策。
两个操作合起来是一条闭环:约束定义「要多快」→ 布局布线朝这个目标努力 → 时序分析报告「达到了没有」。看报告只需盯一个结论:所有 clock 摘要里 Setup/Hold 的 Slack 是否全部为正(Worst Slack ≥ 0)。全正,安心下板;有负数,回头改设计(流水线切级、减少扇出、降频)或改约束。
跳过会发生什么。 小设计不做约束,工具默认目标宽松,多数情况能跑——这正是幻灯片说「一般设计可以不用」的原因。但风险是静默的:你不知道余量是多少,换批次芯片、温度变化后可能突然翻车。竞赛建议:至少写一行 create_clock,让 TD 给你一份正经的时序报告,成本十分钟,买一个「时序达标」的确定结论。
在 TD 工具里对应什么操作? 在工程中添加 SDC 约束文件并加入工程;布局布线完成后查看 TD 的时序分析报告(Timing Analysis),逐项核对 Setup/Hold Slack。若需更细致的路径分析,可使用 TD 内的时序报告界面按路径排查最差的若干条。
⑨ 板级验证

做什么。 幻灯片说,板级验证是 FPGA 开发流程的关键步骤之一:将设计下载到实际的 FPGA 板上,在实际硬件环境中测试和验证,检验功能、性能和时序的正确性;过程通常包括下载比特流文件(.bit 文件)、配置 FPGA 板、搭建测试环境、运行测试向量以及分析结果等步骤。
按大赛的实际环境展开:
- 生成比特流:布局布线通过、时序达标后,在 TD 中生成 EG4S20 的比特流文件(.bit);
- 连接下载:用 USB 线连接板卡的 JTAG/下载口,打开 TD 的 Programmer 下载工具,识别到芯片;
- 下载配置:EG4S20 是 SRAM 工艺 FPGA,断电即失配。两种下载方式——JTAG 在线下载(立即生效、断电丢失,调试首选)和固化到板载 Flash(上电自动加载,演示交付用);
- 搭建测试环境并实测:对照第①步的需求清单逐项验证——HDMI 出不出图?按键切换灵不灵?UART 命令回不回包?边界条件(长按、快速连按、非法命令)过不过?
- 分析结果:功能不符就回到对应环节排查——逻辑问题回④改代码重仿,时序问题查⑧的 Slack 报告,电气问题查引脚约束和电平配置。
为什么需要。 前面八步再完善,本质上都在「模型」里打转——仿真是理想模型,时序分析是数学模型。只有板级验证把设计放进真实世界:真实的电源纹波、真实的晶振偏差、真实的外设时序、真实的长导线串扰。它是整个流程的最终裁判,也是唯一能验证「板卡和设计协同是否正确」的步骤。
跳过会发生什么。 不做板级验证的工程等于没做完——需求清单上每一项都还是「理论上成立」。反过来,板级验证也不是终点:发现问题时,你会沿着「⑨→⑧→⑦→④→③」的链条逐层回溯,改完再走一轮。FPGA 开发的真实形态,就是这条九步流水线上的循环往复,直到板上的表现与需求清单完全吻合。
在 TD 工具里对应什么操作? 打开 TD 的 Programmer:扫描设备 → 加载 .bit 文件 → 选择 JTAG 下载(调试)或写 Flash(固化)→ 执行。下载成功后 FPGA 立即开始运行你的设计。板上调试进阶手段是添加嵌入式逻辑分析仪(类似 SignalProbe/ILA 的调试核),把内部信号抓到电脑看波形——相当于给板内装了行车记录仪,后续教程再展开。
常见坑:一板不灵就狂改代码
板上现象异常时,先按「⑨→⑧→⑦→④→③」的顺序定位问题在哪一层:时序报告正不正常?约束对不对?仿真复现得出来吗?没有证据链的盲目改码,只会把一个 bug 改成三个。
本篇通关标准:
- 能不看资料,按顺序默写九步流程,并说出每步的「输入→输出」各是什么;
- 能向同学解释清:功能仿真和时序仿真的区别(何时做、输入什么、回答什么问题);
- 能在 TD 里独立走完一遍「建工程→综合→布局布线→下载 .bit」并知道 SDC 约束文件该在哪个阶段加入。
1. 为什么功能仿真通过了,还可能在上板后出错?
功能仿真是零延时的理想模型,不包含布线延时和器件延时。布局布线后,信号路径有了真实延时,可能出现建立/保持时间不满足的情况,导致触发器锁存到错误数据;此外引脚约束错误、电气特性问题也只在真实硬件上暴露。所以还需时序仿真/时序分析把关时序,板级验证把关整体。
2. 综合和布局布线的本质区别是什么?
综合(Synthesis)是把 RTL 代码翻译成由 LUT、触发器等基本单元构成的门级网表,解决「逻辑功能等价」问题,不涉及芯片上的具体位置;布局布线(Place & Route)是把这张网表落实到芯片内部具体的物理单元和连线上,解决「物理实现」问题,并由此产生真实延时信息。前者输入是代码,后者输入是网表。
3. 时序约束文件(SDC)为什么要在综合之前就写好?
因为约束是工具工作的「目标」:综合和布局布线都会根据约束(如
create_clock定义的目标频率)来优化和努力收敛时序。如果布完线才补约束,布线决策早已在无目标状态下做出,此时约束只能用来「检查」而无法改变结果,很可能得到大片时序违例。先有约束,工具才能朝着正确的频率目标优化。
4. JTAG 下载和固化到 Flash 各适合什么场合?
JTAG 在线下载直接把 .bit 写入 FPGA 的 SRAM 配置单元,立即运行但断电丢失,适合反复调试的日常迭代;固化是把比特流写入板载配置 Flash,上电后由 FPGA 自动加载,适合演示、交付和脱机运行场景。调试阶段用 JTAG,验收演示前记得固化。
5. EG4S20 资源有限,开工前怎么避免「写了一半放不下」?
在第①②步做资源预估算:列出功能所需的 LUT 量级(如一个 32 位计数器约几十个 LUT)、BRAM 需求(帧缓存按分辨率×位深计算)、DSP 需求(有无乘法密集运算),与 EG4S20 的资源表对账;综合后再用资源利用率报告复盘。若估算超出约八成,应先在第①步砍功能或优化方案,而不是硬写到底。