简介:面向使用 Cadence Allegro 进行高速 PCB 设计与约束管理的硬件工程师及学习者,这份 docx 文档围绕在高速信号约束中加入 PIN_delay 的完整流程展开,重点解决 FPGA 引脚延时数据从 Vivado 导出后如何换算、整理并导入 PCB 的实操问题,也涉及约束管理器中相对传播延迟与等长匹配的基础设置。压缩包共 1 个 docx 文件,大小约 805KB,内容以步骤说明配操作截图为主,适合作为设计过程中的流程笔记随手查阅。正文覆盖 PIN_delay 文件获取、PS 到 mil 的单位换算与 Excel 平均值处理、导入 Allegro、SIGXplorer 拓扑设置、Match Group 建立,以及用 VLOOKUP 比对导出数据等环节,并给出 xcvu440 器件的实例与空格字符等常见报错处理思路;对于从 Vivado 到 Allegro 的数据链路,关键参数和操作位置交代得比较清楚。已有 9089 人学习,适合需要快速跑通高速信号等长约束流程、补齐拓扑设置与数据验证细节的读者参考。
1. 为什么高速并行链路非要补 PIN_delay:从 ps 到 mil 的一次账
板子跑到 10 Gbps 以上,等长绕得再漂亮,约束管理器里也可能报出几十 mil 的偏差;问题常常不在走线,而在芯片内部从焊球到管芯的那段延迟没被算进去。Allegro 高速信号添加 PIN_delay,本质是把 FPGA 侧导出的 ps 级封装延时,换算成 PCB 能认的 mil,再用匹配组和拓扑回写到约束里。它适合正在做高速并行总线、DDR 类接口或 SerDes 多路径约束的 PCB 工程师;如果你只做低速板,这套流程可以先放着。
2. 从 FPGA 侧导出 PIN_delay:Tcl 命令、字段含义与最小可用 CSV
2.1 先确认导出对象和边沿口径
PIN_delay 描述的是器件封装内部从焊球到硅片的那段延时,不是 PCB 走线延时。它跟器件型号、封装、速度等级以及管脚所在的 bank 都有关系,所以导出前先把工程里的完整 part number、封装、速度等级抄下来,别拿另一块板的表凑。常见翻车是把不同封装器件的 PIN_delay 混进同一块 PCB,导入也能成功,数值却完全对不上。
原始表一般会给出 max/min 两列延时,有些版本还会带 rise/fall 或不同 corner。先确认你要的是单值补偿还是 min/max 分列:这份流程用 max/min 平均,适合单值 match group;如果后面要做严格时序,建议保留原始两列,不要只留平均值。管脚命名也要提前看,FPGA 侧常见的A1、B2与 PCB 里的网络名、管脚对格式不一定完全一致,后面用 VLOOKUP 对账时这里最容易出问题。
2.2 Tcl 导出与原始表结构
在 FPGA 实现工具的 Tcl 控制台里,先link_design把器件和设计上下文载入,再write_csv导出。命令里的 part number 不是随便写器件族,常见要写工程里的完整型号;如果提示找不到 part,先回工程属性里复制,别手敲。输出文件名建议带日期和版本,避免第二天覆盖掉昨天的 raw 表。
# 1) 载入器件和设计;part_number 换成工程里的完整型号 set part_number "你的完整器件型号" link_design -part $part_number # 2) 导出 PIN_delay 原始表;文件名带日期,避免覆盖旧版本 write_csv pin_delay_raw_20250101.csv逻辑说明:link_design建立当前器件和网表的设计上下文,write_csv把当前设计里的 pin delay 信息写成 CSV。参数说明:part_number必须和 PCB 上实际器件一致;输出文件名不要用中文和空格,导入器对路径和编码的容忍度没你想的那么高。命令拼写也要注意,常见错误是把write_csv拼成wirte_csv,控制台直接报 invalid command。
原始表常见字段如下,不同工具版本列名会略有差异,但核心就这几类:
| 原始字段 | 含义 | 处理动作 |
|---|---|---|
| Pin / Pin Pair | 管脚或管脚对 | 保留,作为后续匹配键 |
| Max Trace Delay (ps) | 封装最大延时 | 与 Min 取平均,或单独保留 |
| Min Trace Delay (ps) | 封装最小延时 | 与 Max 取平均,或单独保留 |
| Avg Delay (ps) | 平均延时 | 新增列,用于单值补偿 |
| Delay (mil) | PCB 单位延时 | 乘换算系数后保留 3 位小数 |
拿到 CSV 后先另存一份 raw 文件,不要直接在原表上删列。后面回读对账、查版本差异、复现问题时,raw 表就是黑匣子;只留处理后的导入表,出了偏差你连原始 max/min 都找不回来。
2.3 把原始 CSV 变成可导入的三列
导入表不需要把所有字段都带进去,最小可用结构通常是三列:管脚对、延时值、匹配组。管脚对分隔符按导入器要求来,常见是:或-,不要一半用冒号一半用短横线。先拿 10 行做小样导入,确认格式再全量,比一次性灌几千行再排查要省事。
| 导入列 | 来源 | 注意 |
|---|---|---|
| Pin Pair | 原始 Pin / Pin Pair | 与 PCB 管脚命名统一 |
| Delay | 换算后的 mil 值 | 数值列不要带mil字符串 |
| Match Group | 按总线手工填 | 可导入后建,也可以先留空 |
CSV 编码建议用 UTF-8 无 BOM 或纯 ASCII,表头不要合并单元格,数值不要写成6mil这种带单位的字符串。导入器读不进去时,先看它报的是列数不对、编码不对还是管脚找不到;这三种错误的修法完全不一样,别一股脑怪文件格式。
3. 把 ps 换算成 mil:平均值、单位与表格清洗的具体做法
3.1 为什么取最大/最小平均值
单值 match group 只能吃一个延时值,所以这份流程把 max/min 取平均,作为折中补偿。这样做的优点是表结构简单,导入后每个管脚对一个数,建组和核对都直观;缺点是丢掉了 max/min 的时序含义。严格做 setup/hold 分析时,max 和 min 的敏感度不同,能分列就分列,别为了表格好看把原始信息压掉。
我一般会保留三列:max_ps、min_ps、avg_ps,导入只用avg_mil,回读对账再用 raw 表。这样既能让约束管理器吃到单值,又能在出问题时回溯到原始 max/min。平均值的公式不复杂,难的是确认 E/F 两列到底是不是 max/min;列选错一次,后面所有换算都是白算。
3.2 换算系数怎么定:169.5 ps/in 到约 6 mil/ps
器件手册里常给出封装延时速度,例如 169.5 ps/in。1 in 等于 1000 mil,所以 1 ps 对应的长度是:
1 ps = 1000 / 169.5 ≈ 5.8997 mil
工程上常取1 ps = 6 mil,也就是把 5.8997 四舍五入到 6。这个取整看着很小,放到长延时上并不小:
| 项目 | 数值 |
|---|---|
| 手册延时速度 | 169.5 ps/in |
| 1 in | 1000 mil |
| 1 ps 对应 | 约 5.8997 mil |
| 工程取整 | 6 mil/ps |
| 500 ps 多算 | 约 50 mil |
| 1000 ps 多算 | 约 100 mil |
注意:1 ps=6 mil 是工程近似,不是精确值;板级余量只有几十 mil 时,这个误差不能忽略,建议保留 5.8997 或按器件手册重算。
3.3 用表格公式整理导入列
假设原始表里 E 列是 Max Trace Delay (ps),F 列是 Min Trace Delay (ps),A 列是管脚对。先在 G 列算平均,再在 H 列转 mil,最后在 I 列拼导入行。列号只是示例,实际按你的表头调整,别照抄列号不看表。
' G2:最大/最小延时取平均 =(E2+F2)/2 ' H2:ps 转 mil;6 是工程近似,精确值用 5.8997 =G2*6 ' I2:拼成导入器常见的两列格式,分隔符按你的模板改 =A2&","&TEXT(H2,"0.000")逻辑说明:G 列把两个延时口径压成一个单值,H 列完成 ps 到 mil 的单位换算,I 列把管脚对和数值拼成导入器能读的一行。参数说明:6可以换成5.8997;TEXT(H2,"0.000")控制小数位,导入器对小数位敏感时统一成 3 位更省事。下拉填充后先筛一遍空值、#VALUE!和负值,负延时通常说明列选错或表头错位。
如果数据量大,用 Python 批处理更稳,列名按你的原始 CSV 改:
import pandas as pd # 读取原始导出表;列名要和实际 CSV 对上 raw = pd.read_csv("pin_delay_raw.csv") # 计算平均延时并换算成 mil;5.8997 可替换成 6 raw["avg_ps"] = (raw["Max Trace Delay (ps)"] + raw["Min Trace Delay (ps)"]) / 2 raw["delay_mil"] = raw["avg_ps"] * 5.8997 # 只保留导入需要的列,统一保留 3 位小数 raw[["Pin", "delay_mil"]].to_csv( "pin_delay_import.csv", index=False, float_format="%.3f" )逻辑说明:先按列名取 max/min,避免靠列号硬编码;换算后再裁列,减少导入器读错列的概率。参数说明:float_format="%.3f"控制小数位,index=False防止把行号写进 CSV。原始表列名不同时,先把raw.columns打出来看一眼,别直接套。
4. 在 Allegro 里导入并让约束管理器认账:match group、拓扑与 Update CM
4.1 导入路径和字段映射
Allegro 里走File -> Import -> Pin Delay,选中处理好的 CSV,先备份 brd 再点导入。导入器对表头和列顺序有要求,不同版本字段名可能不一样,最稳的办法是先导出一份空模板或看导入对话框里的字段映射,再对照自己的表改。
| 导入器字段 | 来源列 | 注意 |
|---|---|---|
| Pin / Pin Pair | A 列 | 必须和 PCB 管脚命名一致 |
| Delay | H 列 | 单位是 mil,数值列不要带单位 |
| Match Group | 可选列 | 可以先留空,导入后建组 |
导入成功不等于约束生效。打开 Constraint Manager,在Relative Propagation Delay下看 PIN_delay 是否出现;看不到先查显示开关,再查是否建了 match group。导入日志只说明文件被读进去了,不代表每个管脚都映射对了,后面一定要回读对账。
4.2 单路径与多路径的 match group 差别
单路径信号可以直接在 Constraint Manager 里建 match group:选中信号,建组,命名,设好 tolerance,再把成员加进去。多路径信号不能这么干,因为同一个信号有多条拓扑路径,工具不知道你要比哪一条。直接选信号建组,常见现象是报错、组里成员为空,或者 PIN_delay 显示不出来。
多路径信号要先做拓扑。拓扑名称建议带总线名和路径编号,比如BUS_A_PATH1,别用Topology1这种过两天自己都看不懂的名字。match group 也不是越大越好,按同方向、同速率、同拓扑的总线分组,组内成员越干净,后面排查越轻松。
4.3 SIGXplorer 拓扑设置与回写
打开拓扑编辑器 SIGXplorer,新建 topology,填名称、选路径、设误差范围,点添加和 OK。回到拓扑第一页后点Update CM回写,这一步不是保存,是让约束管理器吃到新拓扑;没点它,Constraint Manager 里还是旧状态。
操作顺序可以按下面走:
- 在拓扑编辑器里新建 topology,命名与信号/总线一致。
- 选择实际路径,设置误差范围,确认路径方向没有选反。
- 点添加和 OK,回到 topology 第一页。
- 点
Update CM,回写约束管理器。 - 在 Constraint Manager 里把对应的 PPR 加到 match group,不要直接选整个多路径信号。
如果Update CM是灰的,先看 topology 是否关联当前 design、有没有未保存修改,再看当前用户权限和设计状态。多路径信号建组失败时,先别删组重建,回到拓扑页确认路径和名称,很多问题出在拓扑没回写,不是 match group 本身。
5. PIN_delay 导入后的对账与常见问题排查:五类翻车现场
5.1 导出回读与 VLOOKUP 对账
导入完必须回读。在 PCB 里走File -> Export -> Pin Delay,选中芯片,导出到新文件,命名带日期。打开回读表,把之前导入的 delay 列贴到后面,用 VLOOKUP 按管脚对查找,不要按行号对比,导出顺序不一定和导入表一致。
' J2:按管脚对精确查找回读延时;第 4 列改成你的延时列 =IFERROR(VLOOKUP(TRIM($A2),'回读'!$A:$D,4,0),"未匹配") ' K2:计算导入值与回读值差值 =IFERROR(H2-J2,"")逻辑说明:TRIM($A2)去掉管脚对前后的空格,'回读'!$A:$D是查找区域,4表示延时值在区域第 4 列,0表示精确匹配。参数说明:回读表第一列如果有两个空格,VLOOKUP 会大量返回#N/A,先用查找替换把空格干掉,或者加辅助列=TRIM(A2)再查。IFERROR只是让表好看,真正要看的还是差值和未匹配行。
5.2 常见问题排查:五类翻车现场
现象一:导入成功,但 Constraint Manager 里看不到 PIN_delay。
原因:PIN_delay 显示开关没开,或者没有建 match group,多路径信号还没设拓扑。
解决:先打开 PIN_delay 显示,再按单路径/多路径分别建组;多路径回到拓扑编辑器确认Update CM已回写,最后把 PPR 加进 match group。
现象二:数值明显偏大或偏小。
原因:ps 没换成 mil、换算系数用错、表头错位,或者把 max 当成了 avg。
解决:抽 3 个管脚手算一遍,确认avg_ps * 5.8997与导入值一致;余量紧的链路不要用 6 粗算,改用 5.8997 或手册值。
现象三:多路径信号直接建 match group 报错。
原因:同一信号有多条路径,工具无法确定比较基准。
解决:先在 SIGXplorer 建 topology,选路径、设误差、Update CM,再在 Constraint Manager 里把 PPR 加到组里,不要直接选整个信号。
现象四:VLOOKUP 大量#N/A。
原因:回读表管脚对带空格、大小写不一致、分隔符不同,或者管脚名格式被工具改过。
解决:用TRIM清空格,统一:和-,必要时把两边管脚名都转成大写再查;不要只改一边。
现象五:回读值和导入值对不上。
原因:拿旧版本 raw 表导入、器件型号或封装不一致,或者导入的是平均值、回读的是 max/min。
解决:文件名里写清 part number、日期和阶段,raw/import/readback 三张表成套保存;对账时确认两边是同一个口径,别拿 avg 去比 max。
6. 把 PIN_delay 流程压成模板:三张表、一个阈值和一次回读
我现在不再每次从零做表,而是固定三张表:raw保留原始 max/min 和导出命令,import只留管脚对和 mil,readback存 PCB 回读结果。三张表都带版本号,命名规则是pin_delay_<part>_<date>_<stage>.csv,这样过两周还能说清哪张表对应哪次导入。
| 表 | 关键列 | 用途 |
|---|---|---|
| raw | Pin、Max、Min、part number | 回溯原始数据 |
| import | Pin Pair、Delay(mil) | 给 Allegro 导入 |
| readback | Pin Pair、Delay(mil) | 回读对账 |
阈值我一般设两个:绝对值超过 1 mil,或相对超过 0.5%,就标黄。先查管脚对是否匹配,再查换算系数,最后查器件版本。多路径总线我会把路径编号写进 topology 名称,比如BUS_A_PATH1,免得 match group 里把两条路径混在一起。最后一步一定是回读,导入日志显示 success 只说明文件被读进去了,不代表数值映射对。
从那以后我每次做高速板,导入 PIN_delay 前都强制走一遍 raw→import→readback,少一步都不签字。这套三张表的空模板和检查项我放在同一份工程笔记里,需要直接套用的按页面提示取。希望帮到你。
本文还有配套的精品资源,点击获取