FPGA 入门 25:XDC 管脚与时序——时钟、管脚、电平三件事
更新时间:2026-09-12。本文是
fpga/入门层第 27 篇。XDC 入门见 XDC 约束入门,时序怎么算见进阶 静态时序分析 STA,约束实战见 约束实战。
本文要回答的问题
- XDC/SDC 约束到底分哪几类,为什么「代码写完了」还必须写约束才能可靠上板?
create_clock命令每个参数是什么含义?周期单位是什么、100MHz 该写几、波形参数什么时候才需要?- 工具怎样从一个时钟约束出发,自动算出建立时间、保持时间和 slack?为什么没约束时钟的设计等于没验收标准?
- 管脚号和 IOSTANDARD 从哪里来,为什么不能自己编?Bank 电压 Vcco 和电平标准是什么关系?
- WNS、WHS、TPWS、unconstrained paths 分别怎么读?WNS 为负时的排查顺序是什么?
set_false_path、set_clock_groups什么时候才该用,乱用会掩盖什么问题?- 主时钟、PLL 派生时钟、差分时钟、异步外部信号的约束各有什么不同?
一、三类约束
| 类别 | 作用 | 典型命令 |
|---|---|---|
| 时序 | 定义时钟、做 STA | create_clock |
| 物理 | 绑管脚、设电平 | set_property PACKAGE_PIN/IOSTANDARD |
| 例外 | 告诉工具哪些路径别按默认分析 | set_false_path、set_clock_groups |
二、最小 XDC 模板
# ① 主时钟:100MHz 晶振 -> 周期 10ns
create_clock -name sys_clk -period 10 [get_ports clk]
# ② 管脚 + 电平(管脚号来自开发板原理图/官方 master XDC)
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports clk]
set_property -dict { PACKAGE_PIN T21 IOSTANDARD LVCMOS33 } [get_ports {led[0]}]
set_property -dict { PACKAGE_PIN T22 IOSTANDARD LVCMOS33 } [get_ports {led[1]}]
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 PULLUP true } [get_ports key]
# ③ 差分时钟示例(按板卡)
# create_clock -name clk_p -period 5 [get_ports clk_p]
# set_property IOSTANDARD LVDS [get_ports {clk_p clk_n}]三、电平与 Bank
- 管脚号照抄原理图/官方 XDC,不能自己编;
IOSTANDARD由该 Bank 的 Vcco 决定:3.3V→LVCMOS33,1.8V→LVCMOS18;- 差分信号(LVDS/HDMI/高速时钟)必须用差分对引脚 + LVDS;
- 同 Bank 注意供电一致;可选 PULLUP/SLEW/DRIVE。
四、时序报告速览
| 指标 | 含义 | 要求 |
|---|---|---|
| WNS | 最坏建立裕量 | ≥0(负=频率太快/逻辑太深) |
| WHS | 最坏保持裕量 | ≥0(多由偏斜,工具常自修) |
| unconstrained | 未约束时钟/路径 | 必须清零 |
WNS 为负时排查:先查时钟约束对不对 → 看失败路径逻辑级数 → 插寄存器/retiming/物理优化/降频;CDC 路径用 clock_groups 正确切分。
五、为什么必须告诉工具时钟:STA 直觉
Verilog 代码里只有「在时钟沿做什么」,并没有一句话告诉工具这个时钟有多快。综合布线工具需要一个明确的目标周期,才能回答关键问题:信号从一个触发器出发,经过布线和组合逻辑,到达下一个触发器时,能不能赶在它下次采样之前稳定下来?回答这个问题的方法就是静态时序分析(STA)。它不需要仿真激励,而是穷举所有寄存器到寄存器的时序路径,按你声明的时钟周期逐条计算裕量。
建立时间检查的直觉是「下一拍数据必须到得够早」:一个时钟周期内,发射触发器在沿后输出,经过时钟树延迟、逻辑延迟、布线延迟,到达捕获触发器;数据到达时刻必须比捕获沿提前至少一个建立时间。周期减去这些延迟和建立时间要求,剩下的就是建立裕量(slack)。保持时间检查则是「新数据不能来得太快冲掉旧值」,要求数据在捕获沿之后还稳定一小段保持时间。两者都为正,电路才能在该频率下每一拍都正确采样。若不写 create_clock,工具没有目标周期,这些检查全部无法成立,报告里会出现 unconstrained 时钟和成百上千条未约束路径——此时布线是否能工作纯属偶然。深入推导见进阶 STA。
约束周期要写你真正要跑的频率,而不是晶振最大频率或随便写个宽松值:写太松,工具不会努力优化关键路径,上板可能失败;写得过紧远超器件能力,则会产生无法收敛的负裕量并拖长编译时间。通常按目标频率声明,需要时再略收紧约 5%~10% 留裕量。频率单位换算务必心算一遍:周期纳秒数等于 10 亿除以频率赫兹,即 100MHz 对应 10ns、50MHz 对应 20ns、125MHz 对应 8ns,这是 XDC 里最高频的低级错误来源。
六、create_clock 完整写法与波形参数
一条完整主时钟约束形如「create_clock -name 时钟名 -period 周期值 -waveform {第一个上升沿时刻 第一个下降沿时刻} 作用对象」。作用对象用 get_ports 取顶层输入端口。多数情况下时钟是标准 50% 占空比、0 时刻上升沿,-waveform 可以省略,工具默认上升沿在 0、下降沿在半个周期处;只有在需要描述非 50% 占空比或特定相位的外部时钟时才显式写出,例如周期 10ns、上升沿在 2ns、下降沿在 7ns,就写 -waveform {2 7}。时钟名是内部标识符,便于报告和后续命令引用,和端口名不必相同但建议相关。
几类时钟的约束策略要分清:
- 板载晶振单端时钟:直接在输入端口 create_clock,最常见;
- 差分时钟(clk_p/clk_n):物理上按 LVDS 差分对约束两个管脚,时序上只在正端创建一个时钟,负端是互补的物理引脚,不再另建时钟;
- PLL/MMCM 输出时钟:不要手写 create_clock,工具识别时钟向导生成的 IP 后会自动创建 generated clock,并正确建立与输入时钟的相位、倍分频关系;手动再约束反而可能冲突(PLL 见 时钟向导);
- 门控或分频产生的时钟:用逻辑给时钟「分频」会产生不进全局时钟树、偏斜严重的伪时钟,正确做法是保持一个时钟、用时钟使能(见 计数器篇);确需新时钟域时走 PLL 或按 generated clock 约束。
约束文件可多个、按顺序读入,管脚和时序约束可分成不同 XDC(便于在不同板卡间只替换管脚文件)。综合用 XDC 和实现用 XDC 也可分离,但入门阶段一个文件足够。
七、管脚与电平:从原理图到 PACKAGE_PIN
物理约束回答「这个逻辑端口连到芯片哪只脚、用什么电气规范说话」。管脚号没有任何规律可推,唯一合法来源是开发板原理图或板卡厂商提供的主约束文件:在原理图找到网名(如 sys_clock、led、key、uart_txd),顺着连线看到芯片封装脚号(字母加数字,如 U19、T21),照抄进 PACKAGE_PIN。官方 master XDC 通常已按网名写好全部管脚,只需取消注释并保证网名与你的顶层端口一致。自己编脚号的后果包括:信号出现在完全无关的排针上、与板载芯片冲突、甚至让 DRC 直接拒绝生成比特流。
IOSTANDARD 必须和该引脚所在 I/O Bank 的供电 Vcco 匹配:Bank 供 3.3V 才能声明 LVCMOS33,供 1.8V 用 LVCMOS18,2.5V 用 LVCMOS25;很多板子的 Bank 电压是固定的,查原理图电源页即可。差分标准(LVDS 等)还要求正、负信号落在器件规定的差分对上,并配对应 Bank 电压。常用附加属性有:PULLUP/PULLDOWN 内部上下拉(按键默认电平常用)、SLEW 压摆率(高速或噪声敏感时调整)、DRIVE 驱动强度、PULLNONE 关闭默认上下拉。三态 inout 端口除管脚电平外,还要在 RTL 里正确控制输出使能,方向逻辑错会表现为总线冲突(三态概念见 Verilog 数据类型)。
工程上强烈建议把「可移植部分」和「板级部分」分离:时序约束(时钟、例外)与具体板卡无关,管脚约束一份板卡一个文件,换板子时只替换管脚 XDC,时序约束原样保留。顶层端口名保持稳定,还能让官方 XDC 几乎零修改直接使用。
八、时序报告怎么读:WNS/WHS 与失败路径
实现完成后打开 Timing Summary,先看三个总览数字:
- WNS(Worst Negative Slack):所有建立检查里最差的裕量。为正表示所有路径都满足目标周期;为负表示至少一条路径跑不到目标频率,报告列出具体失败路径。
- WHS(Worst Hold Slack):所有保持检查里最差的裕量。保持违例通常意味着数据传得太快、在同一拍内冲过下一级,布线工具一般会自动加延迟修复;持续为负要查时钟偏斜和异步设计。
- 未约束路径数与未约束时钟数:必须为零。只要这里非零,前面的 WNS/WHS 就不能代表整个设计,因为还有路径根本没被验收。
点开一条失败路径,重点看四个字段:起点(Source Clock、发射触发器)、终点(Destination Clock、捕获触发器)、数据路径延迟分解(逻辑级数 Logic Levels、布线延迟)、以及要求到达时间和实际到达时间之差。逻辑级数过大(例如十几级 LUT 的宽比较、if 链、大 mux)是建立违例的典型原因;这类路径在你的 RTL 里往往对应「一个时钟沿里做了太多组合运算」。时钟偏斜(skew)异常大则要查时钟是否走了局部布线而非全局时钟树、是否混入了分频时钟。
WNS 为负时按固定顺序处理:第一步核对约束本身(周期、端口、派生时钟),统计上很多「时序不过」是约束错误而不是设计错误;第二步确认违例路径类型,是正常同步路径还是本该切分的异步路径;第三步对同步长路径做微结构优化——插流水线寄存器拆分组合深度、减少宽 mux、把关键运算移到 DSP/BRAM 专用资源(见 DSP48、BRAM);第四步提高综合/实现努力度或打开重定时(retiming,让工具自动平衡寄存器);最后才考虑降低目标频率。方法论见进阶 时序收敛、时序报告入门。
九、时序例外:false_path、clock_groups 与 max_delay
默认情况下,工具假设所有时钟之间同源可相、所有路径都必须按时收敛。这在两种情形下不成立,需要用例外约束纠正,但每一条例外都是在「替某些路径签字免责」,必须用对地方。
- set_false_path:声明某条路径不做时序检查。典型对象是复位信号(已经做异步复位、同步释放设计时的复位分发路径)、以及只在初始化时写一次、运行中永不变的静态配置。用法上要精确指定 from/to 对象,避免一条宽松命令把不该豁免的路径也屏蔽。
- set_clock_groups:声明时钟组之间完全异步、互不分析。最典型是两个独立晶振域,或设计中已经按 CDC 规范 用同步器/异步 FIFO 处理的跨域接口。它比逐条 false_path 更干净:一句命令切断两个时钟组之间全部路径,但前提是 RTL 里这些跨域信号确实都经过了正确的同步电路。
- set_max_delay / set_min_delay:给特定路径指定固定延迟上限或下限,常用于异步信号经过两级同步器时——你关心的是「别让两级触发器被布得太远」,而不是按某个时钟周期检查,因此给一个较小的最大延迟而不按时钟关系分析。
危险用法要特别警惕:看到时序失败就把失败路径设成 false_path,报告变绿但硬件照样错——这等于关掉报警器而不是灭火。正确流程是先判断该路径的硬件性质:同步路径必须真正收敛;只有电气上异步、且 RTL 已用同步器保护的路径才用例外。每条例外建议写注释说明依据,评审时逐条能讲清「为什么这条路径不需要时序保证」。
十、片外时序的直觉:输入/输出延迟
管脚约束只规定物理位置和电平,create_clock 只描述芯片自己的时钟,而芯片与外部器件(ADC、SRAM、PHY)之间的数据交换还涉及「外部芯片的时钟到数据相位关系」。工业约束里用 set_input_delay / set_output_delay 描述数据在引脚处相对于某个时钟提前或滞后多久到达/离开,工具才能把片外时间也算进建立保持检查。入门实验(按键、LED、UART)外部器件没有严格同步关系,通常不写这类约束,相应路径按 false_path 处理或依赖同步器;但要知道它们的存在,等接到有同步接口手册时序图的外设时,数据手册给出的 setup/hold、clock-to-output 数字就是填这些约束的素材,进阶 约束实战 会完整展开。
对「普通异步输入」的推荐组合是:RTL 里先打两拍同步(按键、UART RX 都如此),约束上对进同步器前的那段路径 set_false_path 或 set_max_delay 忽略同步关系;这样工具不会要求一个本质异步的信号满足不可能的建立时间,而同步器本身的两级寄存器仍会被布在合理距离内。软件可以用约束向导按图形界面勾选生成这些命令,理解含义后再用,避免复制来路不明的约束片段。
十一、约束自查清单与上手路径
每次添加或修改约束后过一遍:
- 主时钟是否在正确的顶层端口声明,周期与板载晶振一致(ns 与 MHz 换算了吗);
- 是否还存在 unconstrained clock 或 unconstrained internal path,数量必须为零;
- PLL 输出是否由工具自动派生,没有重复手写时钟;
- 每个顶层端口是否都有 PACKAGE_PIN 和与 Bank Vcco 一致的 IOSTANDARD,脚号全部来自原理图或官方 XDC;
- 差分对是否用成对管脚和差分电平标准,只创建了一个时钟;
- 每条 false_path / clock_groups 是否能指出对应 RTL 里的同步器,理由是否写了注释;
- 实现后 WNS、WHS 是否都为正,失败路径是否已逐条分析处理;
- 换板卡时是否只需替换管脚文件,时序约束能否原样复用。
推荐的练习路径:先给「LED 闪烁 + 按键 + 数码管扫描」工程写一份最小 XDC(一个 create_clock 加若干管脚电平),实现后打开 Timing Summary 找到 WNS,体会「约束即验收标准」;再故意把周期从 20ns 改成 4ns,观察失败路径和逻辑级数报告如何变化;接着加入一个 PLL 输出双时钟,观察自动生成的派生时钟;最后给经过两级同步的异步按键写正确的 false_path,并故意写错(豁免一条同步路径)体会报告「假绿」的风险。把约束文件和 RTL 一样纳入版本管理、随设计评审,你就具备了从「能跑」走向「能保证跑」的关键习惯——XDC 不是上板前的填表步骤,而是你对电路时序提出的正式规格。
十二、换到 Intel/Altera:SDC 与 QSF 的对应关系
约束思想是厂商中立的,只是文件和命令名不同,理解了 XDC 再看 Quartus 工程不会陌生。Quartus 把两类约束分别放在两种文件里:时序约束写 SDC(Synopsys Design Constraints,和 XDC 同源同语法,create_clock、set_false_path、derive_pll_clocks 等命令几乎一致);管脚与电平放在 QSF(Quartus Settings File)设置文件里,用 set_location_assignment 绑定管脚、set_instance_assignment 设电平标准,形式类似「set_location_assignment PIN_U19 -to clk」。工程中通常图形界面的 Pin Planner 改完管脚后自动写回 QSF,时序约束则在 TimeQuest/Timing Analyzer 界面或手工编辑 SDC。
概念对应关系很直接:create_clock 两边完全同名同义;PLL 派生时钟在 Quartus 里用 derive_pll_clocks 一条命令自动派生;管脚对应 PACKAGE_PIN 变成 PIN_ 加脚号的 location assignment,IOSTANDARD 变成电平 assignment(如 3.3-V LVTTL、3.3-V LVCMOS);时序报告同样给出 slack、fmax 和未约束路径汇总。注意一个易混点:Xilinx 的 LVCMOS33 在 Quartus 里常见写法是「3.3-V LVTTL」,电平标准名称必须按各自软件下拉框里的确切字符串填。无论工具如何,验收标准永远是三件事:没有未约束时钟、所有同步路径 slack 为正、管脚电平与原理图一致。
十三、一个完整的约束工作流实例
把前面各节串成一个可照做的流程,假设新工程是「50MHz 晶振、4 个 LED、2 个按键、一路 UART、内部例化一个 PLL 产生 100MHz 主处理时钟」:
- 建工程先写时钟:综合出网表前就在 XDC 里为晶振端口写 create_clock,周期按 50MHz 算为 20ns,名字取 sys_clk;这样每一次实现都在真实约束下评估,避免最后才发现大问题。
- 照搬板级管脚:从官方主 XDC 复制时钟、LED、按键、UART 的 PACKAGE_PIN 与 IOSTANDARD,核对端口名;按键打开内部上拉。
- 例化 PLL 后不手写输出时钟:实现后在时钟报告确认 sys_clk 及其派生时钟都已识别,时钟关系树完整。
- 处理异步输入:UART RX 和按键 RTL 内已两级同步,给这两类端口到第一级同步器的路径写精确的 false_path(或 max_delay),并注释「异步输入,同步器在 rtl 某模块」。
- 首次实现后读报告:确认未约束路径为零;看 WNS/WHS。若 100MHz 下 WNS 为负,打开最差路径,可能是某个宽比较或除法没有流水化,先改 RTL 再谈降频。
- 迭代并记录:每次改约束或 RTL 后重新实现,观察关键路径变化;把「目标频率、最终 WNS、剩余未约束数」记在工程笔记里。
- 上板确认:时序收敛后再烧写;用 ILA 验证跨域握手和 UART 收发(见 ILA 第一次用)。
这个流程体现了一条核心纪律:约束先于实现、时序先于上板。很多初学者把 XDC 留到「点灯不成功」时才补,此时管脚错误、时钟未约束、伪时钟、CDC 问题混在一起极难分辨。按上面顺序,每一步只引入一类新变量,出问题也能立刻定位是脚位、时钟、外部电平还是内部时序。养成这个习惯后,约束文件会从「抄来的神秘咒语」变成你自己写的、每条命令都能解释的工程规格书;等到进阶阶段接触 DDR、高速收发器、多板卡项目时,你会感谢入门时建立的这套秩序。最后再强调一次三句话口诀:时钟不约束,一切时序结论都无效;管脚不靠原理图,点灯全靠运气;例外命令只发给真正异步且已同步的路径,绝不用来给失败报告「刷绿」。把这三句刻进工作流,时序问题就再也不会成为上板前的玄学。
十四、管脚交换、Bank 电压与 PCB 协同
约束管脚不只是"把信号名对应到一个引脚号"这么简单,它本质是 FPGA 逻辑设计与 PCB 硬件设计之间的契约,理解这层协同能避免大量"改板才能解决"的事故。第一个要点是 I/O Bank 与电压(VCCO)约束。FPGA 的引脚按 Bank 分组,同一个 Bank 的 IO 通常共用一个供电电压 VCCO,因此一个 Bank 里不能随意混用要求不同电压的电平标准——不能让一部分脚是 3.3V LVCMOS33、另一部分脚是 1.8V LVCMOS18,除非该 Bank 是支持多电压的特殊结构或拆到不同 Bank。分配管脚时先要拿到原理图,确认每个外设的电平、每个 Bank 的 VCCO 供电,再把同电压标准的信号放进同一 Bank;在 XDC 里既要写 set_property PACKAGE_PIN,也要写 set_property IOSTANDARD,两者缺一生成比特流时就会报错。差分对(LVDS、TMDS)还要求使用器件规定的 P/N 配对引脚,不能任意挑两个普通脚。
第二个要点是管脚交换(pin swap)与设计冻结时机。PCB 投板前,管脚约束可以自由调整以配合布线走顺;一旦板子做出来,引脚的物理连接就固定了。好消息是同性质资源之间常有一定的可交换余地:很多 FPGA 允许在兼容引脚之间通过工具重新分配(甚至部分支持在已布线 PCB 上利用 P-block 内等价脚),但跨 Bank、跨电压、跨特殊功能(时钟-capable 脚、收发器、VREF、配置脚)的交换往往不可行。因此正确流程是:原理图阶段由 FPGA 工程师输出初版管脚表并标注哪些是"必须固定"(时钟输入、DDR、高速收发器、配置脚)、哪些"可调整",PCB 布局布线后回填最终管脚表生成 XDC,并在投板前双方会签冻结。第三个要点是特殊引脚不可随意占用:时钟信号应进时钟-capable(MRCC/SRCC)引脚以接入全局时钟网络和 BUFG/PLL;配置引脚(PROGRAM、INIT、DONE、JTAG)即使在配置后想当普通 IO 用也要确认模式设置;模拟(XADC)、VREF、双用途脚各有约束。把"Bank 电压一致、差分配对、时钟专用脚、配置脚、冻结流程"这五件事在约束阶段就核对清楚,配合一张与原理图一致的管脚 CSV 表做评审,能把绝大多数管脚类硬件事故消灭在投板之前。
十五、读懂时序报告:从 WNS 到关键路径
写完约束、跑完实现,工具会给出时序报告,能不能读懂它决定了你是"碰运气等绿勾"还是"能主动收敛时序"。最核心的几个指标是:**WNS(Worst Negative Slack,最差建立时间裕量)**和 WHS(最差保持时间裕量)。Slack(裕量)= 要求时间 − 实际到达时间。以建立时间为例,一个信号从源触发器出发,经过时钟到输出延迟、中间组合逻辑、布线,到达目的触发器的 D 端,必须在下一个时钟沿到来之前至少提前一个建立时间稳定;如果算出来还早了 2ns,slack 就是 +2ns(满足),若晚了 0.5ns,slack 就是 -0.5ns(违例)。WNS ≥ 0、WHS ≥ 0 是时序收敛(timing met)的硬标志,报告里只要有任何一条路径为负,就不能认为设计可靠,哪怕功能仿真正常。
报告里每条关键路径都会列出:源时钟和目的时钟(含周期、不确定性 uncertainty、时钟偏斜 skew)、数据路径的各级延迟(逻辑延迟 logic levels 与布线延迟 route),以及起止寄存器名。定位时序问题的标准动作是:先点开最差路径,看它从哪个模块到哪个模块、穿过了多少级逻辑(logic levels 很大说明组合链太深)、延迟主要耗在逻辑还是布线上。对症的手段也由此分两类。若逻辑级数多、组合链长(例如一个大加法器、大 case 译码、乘法结果直接比较再控制),应插流水线寄存器把长链切开,让每一级在一个周期内轻松完成,用多一拍延迟换频率;若路径跨了很远的物理位置、布线延迟占大头,则要靠 floorplanning/物理约束把相关逻辑拉近,或减少高扇出信号(用 max_fanout、复制寄存器、手动加 BUFG)。还要检查是否有路径被漏约束(unconstrained)、跨时钟域路径是否用了正确的例外约束(false path、异步时钟组),这些会让报告"假装收敛"或"假报违例"。初学阶段先养成三个习惯:每次实现后必看 timing summary 确认 WNS/WHS 全正;违例了先读最差路径而不是乱改;优先用流水线和低扇出这两招解决八成问题。这样时序收敛就从玄学变成有明确读数、有确定对策的工程环节,也为中级阶段的 STA 深入打下最实在的基础。
常见坑对照
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 不写 create_clock | STA 无基准、未约束 | 主时钟必约束 |
| 管脚号瞎填 | 功能不出/冲突 | 抄原理图 master XDC |
| IOSTANDARD 与 Vcco 不符 | DRC 报错/不工作 | 按 Bank 电压选 |
| 时序不过还上板 | 偶发难复现错误 | 收敛 WNS/WHS 均非负 |
| CDC 路径不切分 | 假时序失败 | set_clock_groups |
| 约束目标频率太松 | 留不下裕量、上板翻车 | 按目标频率略紧声明 |
| 手写 PLL 输出时钟 | 派生时钟冲突、关系错乱 | 用工具自动派生 |
| 抄约束不看注释来源 | 板卡不匹配、电平冲突 | 一切以本板原理图为准 |
相关与延伸
入门:XDC 约束入门、开发全流程。 深入:进阶 STA 静态时序分析、约束实战 generated clock/IO delay、时序收敛方法。
一句话总结
XDC 约束做三件事:用 create_clock 声明主时钟(-period 单位 ns,100MHz 就是 -period 10)作为静态时序分析的基准,用 set_property PACKAGE_PIN 把 RTL 端口绑到原理图指定的物理管脚、IOSTANDARD 按 Bank 供电设电平(LVCMOS33/LVDS 等),用时序例外(set_false_path/set_clock_groups)告诉工具哪些跨域路径别按同步分析。管脚号必须照抄开发板原理图或官方 master XDC、不能编,电平标准要和所在 Bank 的 Vcco 一致。不约束时钟,工具就不知道目标频率、无法算裕量,时序报告出现 unconstrained——上板等于赌运气。实现后看 Timing Summary 的 WNS/WHS:必须 ≥0,WNS 为负先查约束、再看失败路径逻辑级数,用插流水线/retiming/物理优化/降频收敛;时序不过就上板会出偶发难复现的 bug。
上一篇:27 仿真看波形(Testbench/读波形) | 下一篇:29 FPGA 时钟与复位(时钟树/PLL/异步断言同步释放) | FPGA 系列目录