说真的,刚接触Allegro Xnet那会儿,我一度很困惑:明明原理图里一个电阻两端就是两个网络,为什么做等长布线时非要搞出一个“看不见”的网络来?直到后来做一块DDR3板卡,数据线DQ0~DQ7全部经过33欧姆串联电阻连接到控制器,我在约束管理器里折腾了大半天,怎么都没法让这8根线服从一个长度约束——后来才反应过来,软件压根不知道电阻两端是连通的。从那之后我才算真正弄明白,Xnet、电阻模型、Match Group这三样东西,是所有高速数字板卡设计的必修课。
这篇文章我把从电阻模型创建到Match Group设置、再到Tuning绕线的完整流程串一遍,中间会带上我在实际项目里踩过的坑和排查方法,希望能帮你把这条路走顺。
1. Xnet到底是什么,为什么要跟它较劲
1.1 从一次DDR等长翻车聊起
先还原一下当时的场景。控制器U1的DQ0引脚出来,先经过一颗33欧姆串联电阻R1,再走到DDR颗粒U2的DQ0引脚。原理图里,这里其实是两个物理网络:U1上拉到R1左端这段叫U1_DQ0,R1右端到U2这段叫U2_DQ0。如果只做网络级的等长约束,你要么约束U1_DQ0,要么约束U2_DQ0,但信号从U1出发,经过电阻再到U2的总长度,才是真正影响时序的路径。你不可能只把前半段绕到一样长,而后半段不管。
Xnet的作用就是把这两个物理网络合并成一个逻辑网络,软件在算总长度、做等长Match Group的时候,自动把电阻前后两段加在一起。简单理解:Xnet就是告诉Allegro“那两颗电阻是透明的,你们把它们两端的线当成一根线来看”。
1.2 解决了哪类真问题
Xnet在高速设计里几乎无处不在,典型场景包括:
- DDR、LPDDR的数据线、地址线、控制线,为了匹配阻抗和抑制振铃,通常会串联合适阻值的电阻。
- 高速SerDes、PCIe等差分信号,很多板卡会经过AC耦合电容,电容两端网络也需要做Xnet处理。
- 某些接口信号经过磁珠、共模电感再到接插件,同样存在多段网络合并的需求。
在这些场景里,如果不用Xnet,等长约束就只能分段做。问题是分段做的总长度并不可控,因为每个分段的基准是各自的网络,而整条通路上的误差会累积起来。用了Xnet之后,约束管理器里直接看到的就是整条链路的长度和时延,做Match Group才有意义。
1.3 不用Xnet会怎么样
说实话,不做Xnet也能把板子画出来,但结果往往很痛苦。比如DDR3的DQ组内等长要求是正负20mil左右,你分两段分别控长度,每段误差正负10mil,两段加起来误差就到正负20mil,还没算电阻焊盘和封装带来的额外偏差。更麻烦的是,你先绕了前半段,再去绕后半段的时候,前半段已经锁定了,总长度的误差只能靠后半段硬吃。每次改版都要重新分配两段的预算,来回折腾。
所以,只要是带串联电阻的高速总线,从原理图阶段就要把Xnet做出来,这是成本最低的做法。
2. 电阻模型创建:Xnet的第一步
2.1 模型分配前要理清的三个问题
在动手之前,先确认三件事:
第一,哪些器件需要参与Xnet。通常就是串联电阻、0欧姆电阻、磁珠、交流耦合电容这些信号路径上的两端口器件。电源滤波电容不要乱加,否则会把电源网络和地网络合并出麻烦。
第二,器件的模型怎么定义。Allegro不是真的去做电气仿真,它只需要知道这个器件是“直通”的,也就是信号从一个引脚进去,从另一个引脚出来,中间没有逻辑翻转。电阻和磁珠默认就是直通器件,耦合电容严格来说有直流隔离作用,但在高速交流信号通路里,Xnet仍然把它当直通处理,这是业界普遍做法。
第三,用哪个版本的软件流程。我这里以Cadence 17.4为例,OrCAD Capture CIS里做模型分配,Allegro PCB Editor里做约束和布线。老版本比如16.x,菜单名称略有差异,但原理完全一致。
2.2 在Capture里给电阻批量分配模型
打开OrCAD Capture CIS,找到需要处理的原理图页。我的习惯是先做窗口选择,框住这一页所有串联电阻,不用一个个点。
具体步骤:
- 框选所有要创建Xnet的电阻器件。
- 菜单栏选择Tools -> Model Assignment,打开模型分配窗口。
- 在窗口左侧会列出当前选中的器件列表,右侧是模型类型和参数。
- 器件的Value值通常已经填了33或者0这些阻值,但模型类型还是空的。在Model Type里选择Resistor,然后点Assign。
- 分配完成后,关闭窗口看原理图,器件上会带上一个模型属性。
这里有个很容易忽略的点:Model Assignment分配的是SI模型,它决定了器件在约束管理器里能不能被正确识别为串联器件。只填阻值是不够的,必须让软件知道这是一个电阻模型。
2.3 Xnet属性到底加不加
有的工程师会问,是不是分配完模型就够了?不够。在OrCAD Capture里,还需要给器件添加Xnet属性。具体操作:
- 选中所有需要创建Xnet的电阻。
- 右键选择Edit Properties,打开属性编辑器。
- 在属性列里找到Xnet这一项,如果没有就手动添加一列,名称就叫Xnet。
- 把所有选中器件的Xnet值改为TRUE,保存并关闭。
很多教程只说加模型,不提这个属性,结果实际更新到PCB之后怎么都不出Xnet。我自己最早也栽在这上面,后来把Xnet属性设为TRUE之后,PCB端立刻就能看到Xnet了。
需要注意的是,如果你用的Capture CIS版本较新,Model Assignment完成后有可能会自动把Xnet属性带上,但为了稳妥,建议手动检查一遍,批量选中确认Xnet列都是TRUE。
2.4 从网表到PCB:更新流程不能省
模型和属性都设置完之后,保存原理图,重新生成网表。我的习惯是:
- Capture里执行Design -> Create Netlist,在配置里选择Allegro,生成
netlist.dat等文件。 - 回到Allegro PCB Editor,选择File -> Import -> Logic。
- 在Logic Type里选Netlist,指定网表路径。
- 执行Import,软件会对比原图和新网表,提示你哪些网络变了、哪些元件变了。
这里有个细节:第一次导入Xnet相关网表的时候,Allegro可能会弹出一个提示,说检测到了Xnet定义,询问是否启用Xnet模型。一定要选Yes。如果之前没分配模型,这一步就不会有任何提示,Xnet自然也不会出现。
3. 在PCB端确认Xnet并理顺网络结构
3.1 怎么确认Xnet真的生成了
导入网表之后,别急着布线,先打开约束管理器确认一下。
打开方式:Setup -> Constraints -> Constraint Manager,或者在命令行输入cm回车。进入约束管理器后,在左侧目录树里找到Net -> Routing -> Total Length。右侧表格里看到的网络列表如果包含Xnet,那么它的名字通常会以XNET_开头,或者带有一段器件名,比如XNET_DQ0_R1。最直观的判断方式是看行首有没有“+”号,点开之后能看到电阻两端的物理网络被折叠在里面。
如果Total Length表里没有看到Xnet,但在网络列表里有一大堆用_R1_连接的奇怪名字,那大概率是模型分配出了问题,或者导入网表时没有启用Xnet识别。
3.2 Xnet没生效的排查顺序
按照我的经验,Xnet不出现或者只出现一部分,按下面顺序排查:
- 检查原理图里所有串联电阻是否都分配了电阻模型,漏一颗整条链路就断了。
- 检查Xnet属性是否都为TRUE,尤其是从库调出来的电阻,有些库文件属性被锁定,你改了但没保存成功。
- 检查是否重新生成了网表并正确导入PCB,有时候只改了原理图没更新网表,白忙活。
- 检查是不是混合了不同层级的原理图结构,比如某个电阻在顶层原理图,某个在子图里,网表传递有时会丢属性。
有个土办法可以快速定位是哪颗电阻没有模型:在约束管理器里展开某个Xnet,如果发现某个网络段没有归并进来,就去原理图里把那一段串接的电阻找出来,十有八九是它没加模型。
3.3 在PCB端手工创建Xnet的应急路径
如果原理图已经定稿、不方便改,Allegro PCB Editor本身也提供手工创建Xnet的功能。记住这只是应急,不是常规做法。
我印象比较深的一次,客户发来的原图库里电阻模型信息全是乱的,重新分配又怕影响原图结构,只好在PCB端处理。PCB Editor里可以找到Model Data相关菜单,选择创建Xnet,然后按提示依次选择串联器件、起始引脚和结束引脚,软件就会根据你选的两端口自动合并网络。生成之后,约束管理器里同样能看到这个Xnet。
不过手工创建有个问题:后期重新导入网表时,手工创建的信息可能被覆盖。所以如果你用这个应急方案,最好在原理图定版之前把根因修掉,别留隐患。
4. 约束管理器里的等长基础配置
4.1 先把Net、Xnet、Pin Pair的关系理清楚
做等长之前,脑子里必须有一张清晰的图。
一个Xnet内部包含多个物理Net,物理Net之间靠串联器件的引脚衔接。而Pin Pair指的是信号路径上的两个端点,比如DQ0信号从U1引脚出发,经过R1引脚,最终到U2引脚,那么U1.DQ0到U2.DQ0就是一个Pin Pair。长度约束真正作用的对象是Pin Pair,因为它是总长度的完整表达。
明白了这个关系,再看约束管理器就会清晰很多。Total Length表里针对每个Xnet或者Pin Pair显示总长度。Relative Propagation Delay表里显示的则是相对某个基准网络的长度差,也就是Match Group的核心数据。
4.2 创建ECSet并分配给Xnet
等项目里几十组等长网络都准备做约束的时候,不要一个个去填数值,而是先建好电气约束集ECSet,再批量分配。
在约束管理器左侧目录树里找到Electrical Constraint Sets节点,右键选择创建ECSet,名字起得直白一点,比如DDR_DQ_100,意思是对应100欧姆阻抗、DQ组等长约束。创建好之后,在Routing分类下找到Total Length和Relative Propagation Delay,把需要的数值填进去。
然后回到Net表里,选中需要应用这一组约束的Xnet行,右键选择分配ECSet。这一步做完,约束管理器里的这些网络行会带上约束集的名字,后续检查DRC时也方便追溯。
4.3 相对传播延迟为什么是Match Group的理论基础
很多人只知道Match Group是“把一组网络放进同一个组”,但不知道它背后其实是对相对传播延迟的控制。相对传播延迟不考虑信号具体的飞行时间,只关心同一时刻从源端发出的信号,到达各自负载端的时延差有没有超过阈值。
这个时延差和长度差直接相关。普通FR4板材上,外层走线信号速度大约是6mil/ps,内层大约是5.5到6mil/ps。换算过来,1ps的时延差对应约6mil的长度差。假设芯片手册要求DQ组内各信号相对时延不超过±5ps,那长度差就是±30mil左右。实际工程里,DDR3的DQ组内等长经常直接给到±20mil,就是因为时序预算里还要留一部分给供电噪声和串扰。
在约束管理器里,相对传播延迟表就是你实现这个目标的工具。Delta代表这条线和基准线之间的目标差值,Tolerance代表允许的误差范围。这两个值设置好之后,Match Group才算真正有约束力。
5. Match Group设置的完整流程
5.1 定位到对应的约束表
在约束管理器左侧目录树中,依次展开Electrical -> Net -> Routing -> Relative Propagation Delay。右侧会列出所有网络,包括Xnet。这一列的数据在设置Match Group之前是空的或者灰色的。
我通常先切到Total Length,把每组DQ线段的长度观察一遍,心里有个数,再回到Relative Propagation Delay去建组。这样设置Delta和Tolerance的时候,知道基准线大概在什么水平,不会设一个离谱的目标值。
5.2 创建Match Group的两种路径
第一种路径是在Relative Propagation Delay表里操作。找到你要设为一组的第一个Xnet,在它的Relative Propagation Delay单元格上右键,选择Create Match Group。软件会弹出对话框,让你给Match Group起名,比如MG_DDR_DQ0_7。确认后,这一行就变成组里的一员。
第二种路径是在菜单栏里操作,选择Objects -> Create -> Match Group,然后在弹出的窗口里勾选要加入的成员网络。这种方式适合成员特别多的情况,比如地址线一组十几根,用第一种方法一个个右键反而慢。
我个人偏好第一种,因为它直接从当前行创建组,选择的成员时还可以继续配合Ctrl和Shift键多选,视觉上更直观。
5.3 Delta和Tolerance到底怎么填
这是新手最容易懵的地方。我用一个具体例子说明。
假设DQ0这条Xnet布完之后,总长度是1980mil,其余DQ1到DQ7的长度在1900mil到2010mil之间。你想让它们都以DQ0为基准,长度差控制在±50mil以内。
那么基准行选DQ0,Delta设0,Tolerance设50。意思是其余每条线相对DQ0的长度差,正负50mil之内都算合格。
如果某一组网络规划长度是2000mil,但是基准网络DQ0走完只有1900mil,你不想让DQ0当基准,而是想让它们统一趋向2000mil。这时可以把基准设成DQ0,Delta设成100,Tolerance设50。意思就是每条线要相对DQ0长出100mil,允许正负50mil误差,也就是最终长度在1950mil到2050mil之间。注意这里Delta的单位是mil,和约束管理器里显示的长度单位一致。
我的建议是:除非有特殊时序需要,否则Delta就设0,让最自然的那条线当基准,其他线去追它。这样软件实时计算偏差时最简单,也不容易出现整组长度整体偏移的情况。
5.4 基准线怎么选,成员怎么加
创建Match Group之后,组里会有一行被标记为Reference,通常就是最先创建组的那一行。如果你想换基准,在目标行上右键选择Set as Reference即可。
基准线的选择有讲究。单纯从等长角度,选最短的那条当基准,其他线加长绕线,是常见做法。但从布局空间看,如果最短的那条线在板边、周围空间又小,让所有线都去追它,可能会导致部分线绕线空间不足。这时可以选一条长度居中、周围绕线空间充裕的线当基准,其他线有增有减,整体压力更小。
加成员的时候,别忘了检查所有相关Xnet是否都进了组。DDR数据线一组8根,有时候会漏掉一两根,尤其当你在原理图中给DQ网络命名不规律时,特别容易看漏。我习惯建组之后,双击Match Group名称,把成员列表展开,数一遍数量对不对。
6. 等长布线与Tuning实操
6.1 布线顺序和策略比手法更重要
设置完Match Group,接下来就是实际走线和绕线。这里我想先说策略,再讲操作,因为顺序搞错了,后面返工能把你心态搞崩。
我的经验是三部曲:先布通,再优化,最后Tune。布通阶段不需要追求等长,把信号连通、过孔数量合理、走线尽量避免跨分割,就可以。优化阶段再做长度调整,此时配合约束管理器的实时显示,逐根调整蛇形绕线。千万不要一边连一根线一边就在那里Tune,因为前期布线长度还没定,Tune出来的结果一改版就全废。
DDR这类总线还有一个建议:同一组信号尽量走同一层,至少同一个方向。这样它们的阻抗环境、过孔stub、参考平面都是一致的,等长控制才有意义。如果你一根线走在表层,另一根线走在内层,就算长度完全相等,实际时延也会差不少。
6.2 Tuning工具参数面板逐项讲解
Allegro里做等长绕线的工具是Tuning,可以通过菜单Route -> Tuning打开,也可以在工具栏里找到那个像弹簧一样的图标。
启动命令之后,看右侧Options面板,需要关注的参数有:
- Style:绕线风格。常用的是Rosin(波浪形)和Accordion(手风琴形)。Rosin适合空间宽松的局面,Accordion适合长条形区域。Differential Pair有专门的Differential Pair Tuning风格。
- Max Amplitude:蛇形绕线的最大振幅,也就是绕线凸出去的高度。振幅越大,单次能补偿的长度越多,但占用空间也越大。
- Spacing:绕线之间的间距。这里要特别注意:间距不能小于3倍线宽,否则相邻走线之间串扰会明显增加。DDR3数据线按5mil线宽算,间距至少15mil以上,我一般给到20mil。
- Target Length:目标长度。可以直接填一个值,软件会根据当前Tuning走线的总长度自动判断需要补偿多少。
- Delta和Tolerance:这两个和约束管理器里的值保持一致,Tuning工具会自动读取,不需要重复填。
开始绕线的时候,沿着原来的走线路径走一遍鼠标,软件会实时根据目标长度调整绕线密度和形状。走完之后,走线上会显示当前总长度和偏差,绿色代表达标,红色代表还没到,黄色代表超出。
6.3 蛇形线怎么绕才不容易翻车
首先是绕线区域的选择。复位电阻、配置电阻附近不要放蛇形线,因为那些网络通常还有其他信号绕过去的可能,干扰源越少越好。其次是绕线尽量靠近信号接收端,也就是靠近DDR颗粒一侧,这样能减少源端到绕线段的反射影响。
第三是绕线的进出线方式。如果空间允许,尽量让蛇形线的两段进出线平行且等距,并在拐角处使用135度倒角,不要用90度直角。直角会带来阻抗突变,高速信号下反射会更明显。Allegro里Tuning工具默认会处理拐角形式,一般不用额外操心,但如果你把Max Amplitude设得过大,绕线形状容易变得局促,拐角间距不够,DRC会报错。
还有一点要提醒:绕线补偿的是“目标长度和当前长度的差”,不是越多越好。绕线过多会导致信号路径变长、延迟变大,甚至超过时序预算。所以别看到绕线工具觉得好玩就多绕几个波浪,够用就行。
7. 实战避坑手册:我踩过的坑和排查技巧
7.1 电阻模型相关的坑
我列几个高频问题,都是实际项目中遇到过或帮别人排查过的情况,直接按表格对照即可:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| Xnet完全没有生成 | Capture里没分配电阻模型 | Tools -> Model Assignment批量分配 |
| 部分Xnet生成,另一部分没有 | 个别电阻漏选或库属性被锁定 | 按网络逐段排查缺失器件 |
| 导入网表后Xnet消失 | 手工创建的Xnet被覆盖 | 回到原理图修好模型再重新导入 |
| Xnet生成了但总长度异常大/小 | 电阻模型类型被误设成其他器件 | 检查模型类型必须是Resistor或对应直通模型 |
排查Xnet相关问题时,我的土办法是:在约束管理器里展开Xnet,看它包含哪几个物理网络。如果发现某个电阻两边网络没有合并,直接在原理图里搜那颗电阻,打开属性编辑器检查Model和Xnet两列。这个流程非常快,比盲目重导网表有效得多。
7.2 Match Group相关的坑
关于Match Group,新手最容易犯的错误是把Delta和Tolerance填反,或者把基准行选错。填反的后果是:目标值变得非常苛刻,比如本来想允许±50mil误差,结果Delta填50、Tolerance填0,整组线全部标红,布线根本没法收敛。
基准行选错的后果更隐蔽:所有线都朝着一个非目标长度去追,明明组内差异不大,但每根线都显示偏差巨大。这时候只要右键换一下Reference,整个组的显示立刻恢复正常。
还有个坑是忘记把新加的Xnet分配ECSet。有些网络是后补的,比如DDR8根DQ线你已经建好约束,后来又加了一根ECC数据线,直接往Match Group里拖是不行的,必须先把ECSet分配给那个新网络,否则软件不认。
7.3 等长布线结果验证的两板斧
布线完成后,不能只看走线颜色。我每次会做两件验证:
第一,在约束管理器里打开Relative Propagation Delay表,确认所有Match Group成员的偏差都在Tolerance范围内。这比肉眼检查可靠得多。
第二,生成一份约束报告。Allegro里有报告功能,可以导出包含Xnet、Match Group、总长度、相对偏差的汇总表。我习惯把这份报告存成PDF,发给硬件工程师确认时序余量,也方便自己后期对照。
如果你还想做更细致的SI验证,可以把Xnet模型导出到Sigrity或者HyperLynx里做时域仿真。不过那是另一个话题,日常等长布线的验收做到上面两步就够了。
8. 一些还没写进教程但很实用的小经验
最后分享几个散装经验,不算系统教程,但关键时刻真能救命。
第一,原理图里给网络命名一定要有规律。比如DQ0到DQ7,命名用DQ0_P、DQ0_N这种,而不是NET0158。因为建Xnet和Match Group的时候,你需要在满屏的网络列表里迅速找到目标。网络名混乱,光是对应关系就能耗掉你半小时。
第二,做等长之前先确认单位。Allegro的约束管理器和PCB Editor虽然用的是同一套数据库,但显示单位可能不同。有人Constraints Manager里看图是mil,实际输入的时候却是mm,数值差了25倍,整个Match Group全乱套。统一用mil,并且在Setup -> Design Parameter Editor里把显示单位确认一遍。
第三,手动Tune的时候,如果目标长度发生变化,不需要删掉已有的蛇形线重画,直接用Tuning工具重新走一遍原来的蛇形线段,软件会基于新的目标长度重新调整绕线形状。这个节省时间的技巧,我是用了大半年之后才发现的。
第四,也是最重要的一条经验:Xnet不是建完就一劳永逸的。每次原理图有改动、重新导入网表之后,都养成习惯去约束管理器里扫一眼Xnet和Match Group是否完整。版本迭代里最常见的返工事故,就是改了一颗电阻之后,Xnet没重新生成,整组等长约束其实已经失效了,但布线和DRC看起来都正常,直到投板打样回来测试才发现时序不对。
PCB设计这行,很多功夫都在这些看不见的细节里。Xnet这个功能说难不难,但真正用顺、用得稳,需要靠项目一板一板喂出来。希望这篇东西能让你少走一点我当年走过的弯路。