大数跨境

RTL 阶段 PPA 约束前移:基于相对反馈的设计风险闭环方法

RTL 阶段 PPA 约束前移:基于相对反馈的设计风险闭环方法 ai算法芯片与系统
2026-11-01
7
导读:一种在RTL阶段用工艺无关的相对结构指标(latch、存储推断、组合深度、MUX/DFF数量、高扇出等)快速体检RTL的方法。它不替代后端签核,而是把时序、面积、布线风险前移到写代码当天,指导改结构、

 

📑 目录

  1. 1. 定位:PPA 约束前移不是前端签核
  2. 2. 必要性:为什么必须在 RTL 阶段前移
  3. 3. 收益:可量化与不可量化的回报
  4. 4. PPA 约束如何转成 RTL 可执行代理指标
  5. 5. 轻量工具组合与反馈时延分级
  6. 6. 结构健康度:从缺陷检查到硬门禁
  7. 7. 时序潜力评估:拓扑深度与路径分布
  8. 8. 面积效率评估:无库相对门数与资源共享
  9. 9. 可综合性评估:存储推断与状态机展开
  10. 10. 调试辅助:可视化、网表导出与等价性检查
  11. 11. 高扇出专题:全局信号的 RTL 侧治理
  12. 12. 同库相对映射:趋势校准与边界控制
  13. 13. 面向后端的四类信号组织
  14. 14. 持续集成中的 QoR 轨迹与门禁
  15. 15. 报告信号到 RTL 设计动作的映射
  16. 16. 可信边界:相对反馈的适用范围
  17. 17. 面向 NPU 数据通路的 PPA 检查清单
  18. 18. 落地路径与总结

一、定位:PPA 约束前移不是前端签核

😵‍💫 RTL 工程师在前端阶段最容易被 两种极端 带偏。

第一种极端:“等功能仿真过了再说。” 只要仿真跑通、case 过了,就认为 RTL 没问题。

问题是,功能正确 ≠ 结构健康。一个不完整 if/case 推断出的 latch、一个没推成 RAM 的大数组、一个优先级译码形成的长 MUX 链、一个高扇出复位,仿真阶段都可能完全正常,但到了综合和后端就会变成 时序、面积和布线灾难。

第二种极端:“前端就把时序签核做了。” 拿一个工艺库、一组约束跑一次综合,看到 slack 和面积就当成最终结论。

这同样危险。通用综合工具 不是 时序驱动签核工具,轻量映射引擎也 不是 多角、OCV、串扰、时钟树感知的签核引擎。没有真实布线寄生、没有时钟树、没有多工艺角,绝对 ns 和绝对面积都 没有签核意义。

正确的定位是:PPA 约束前移不是把后端约束照搬到前端,而是把不可见的后端代价转成 RTL 可观测、可 diff、可门禁的结构代理指标,形成“设计—评估—修正”的快速闭环。

💡 核心一句:PPA 约束前移的关键,不是提前拿到绝对 PPA 数字,而是把 PPA 目标翻译成 RTL 可执行的结构预算,用相对反馈驱动代码设计。


二、必要性:为什么必须在 RTL 阶段前移

🎯 后端修复成本远高于 RTL 修复成本,这是 行业公认的量级差异,不是经验夸张。理解这一点,才能理解为什么“等后端发现问题再回头”是不可承受的返工路径。

2.1 🧱 修复成本随阶段指数上升

  • • ✍️ RTL 阶段:改几行代码,重跑仿真,小时级。
  • • 🔧 综合阶段:改 RTL 或约束,重跑综合,天级。
  • • 🗺️ 布局布线阶段:改 RTL 触发重新综合 + 布局 + 布线,周级。
  • • ⏱️ STA/ECO 阶段:结构性灾难无法用约束调优解决,可能已错过根治窗口。
  • • 🏁 流片后:不可逆。

⚠️ 关键认知:latch、memory 退化、高扇出、MUX 树过深、组合链过长,这些是 结构性问题,不是约束问题。后端加 buffer、调约束、换驱动强度,只能缓解,不能根治。越晚发现,代价越大。

2.2 🧪 功能仿真无法暴露结构风险

仿真验证的是 行为正确性,不是 结构健康度:

  • • ✅ 功能仿真能证明:给定输入,输出正确。
  • • ❌ 功能仿真不能证明:latch 有没有推断出来、数组有没有推成 RAM、MUX 树有多深、复位扇出有多大。

💡 一个功能完全正确的 RTL,可能在后端是 面积爆炸、时序崩溃、功耗失控 的。功能仿真和结构评估是 两条正交的验证线。

2.3 ⏳ 签核工具反馈周期太长

真实时序签核工具的反馈周期是 小时级甚至天级:需要完整综合、布局、布线、寄生提取、多角分析。日常迭代需要的是“分钟级甚至秒级”反馈,不是“周末才能看到的签核报告”。

2.4 🎯 RTL 工程师需要“当天可行动”的信号

真正有用的信号必须满足:

  • • ⚡ 快:秒级到分钟级,能嵌入日常提交。
  • • 🎯 准:直接指向结构根因,不是“某条路径差 20ps”。
  • • 🔧 可行动:能对应到具体的 RTL 改动。

💡 这就是为什么 工艺无关的结构代理指标 是 RTL 阶段最合适的反馈形式:它快、它准、它能直接指导代码修改。


三、收益:可量化与不可量化的回报

💰 PPA 约束前移的收益,既有可量化的,也有不可量化但同样重要的。

可量化收益:

  • • ⏱️ 减少返工轮次:结构性 bug 在 RTL 阶段修复,避免完整返工循环。
  • • 📐 面积收敛:memory 推断成功 vs 退化,面积差异可达 数倍到数十倍。
  • • 🚀 时序收敛速度:组合深度提前优化,后端时序迭代次数减少。
  • • 🔋 功耗优化空间:高扇出、无使能大块逻辑提前治理。

不可量化但关键的收益:

  • • 🎯 设计意图显性化:DFF 预算、流水级数、memory 推断率变成可 review 的指标。
  • • 🤝 前后端协作改善:后端接手时看到的是一份能定位到结构根因的 QoR 档案。
  • • 📈 设计风格演化可见:两周的趋势曲线能暴露“是不是 MUX 越写越多”。
  • • 🛡️ 风险前移:把“后端才发现的结构灾难”变成“写代码当天就能看见的门禁”。

🎯 一句话:PPA 约束前移不是为了让前端“算得更准”,而是为了让 结构性风险在成本最低的窗口被发现和修复。


四、PPA 约束如何转成 RTL 可执行代理指标

🎯 PPA 约束前移要遵循 三条原则:可观测、可 diff、可门禁。

时序约束的 RTL 代理:组合拓扑深度、流水级均衡度、关键路径类型(宽加法/MUX 树/优先级译码/比较器)、高扇出网清单。

面积约束的 RTL 代理:DFF 总量与并行度匹配、memory 推断率、MUX/pmux 数量、乘法器/加法树/比较器结构占比。

功耗约束的 RTL 代理:使能/门控候选、memory 访问结构、高活动率网络、复制控制带来的额外活动率。

⚠️ 没有 VCD/SAIF 活动率之前,绝对功耗数字没有意义。RTL 阶段只做结构同比。


五、轻量工具组合与反馈时延分级

🧰 工具链尽量轻,报告尽量“工艺解耦”。更重要的是,不同指标的反馈时延差异很大,必须按“快环 / 校准环 / 映射环 / 签核环”分层使用。

5.1 ⚡ 快环:亚秒到秒级

  • • 🚀 check -assert / hierarchy -check:毫秒到亚秒级,适合 pre-commit hook。
  • • 📊 stat / stat -width / select -count:秒级,适合每次 push。
  • • 📏 ltp -noff:秒级到十几秒(取决于设计规模),适合每次 push。
  • • 💾 memory -show / fsm_info:秒级,适合每次 push。

💡 快环是日常迭代的主力。它不追求签核精度,追求 当天可行动。RTL 工程师改完代码几秒内就能看到结构指纹变化,这是整个流程能“活”起来的关键。

5.2 🔁 校准环:十秒到分钟级

  • • ⚡ abc -fast:逻辑化简,十几秒。
  • • 🔗 share / opt_expr -fine:资源共享和常量传播,十几秒到一分钟。
  • • 🔁 miter + sat:等价性检查,分钟级甚至更久,按需使用。

🎯 校准环不是每次提交必跑,适合 PR 门禁或重构验证。

5.3 📅 映射环:分钟级

  • • 🧱 dfflibmap + abc -liberty + stat -liberty:分钟级,适合 每周或里程碑。
  • • 📉 看面积趋势和 slack 过不过。
  • • 🎯 看关键路径起点/终点。

⚠️ 映射环的数字是 相对尺子,不是签核数字。换库数字全变,但同库趋势可信。

5.4 🏁 签核环:小时级

  • • 🔵 OpenSTA / OpenROAD / PrimeTime:小时级甚至天级。
  • • 🎯 真实时序、多角、OCV、串扰。
  • • 🚫 不参与日常迭代,后期再接。

🎯 分层原则:快环负责日常门禁,校准环负责重构验证,映射环负责趋势校准,签核环负责最终确认。不同层级回答不同问题,不能混用。

5.5 🧭 综合流水线全景:每个报告命令在流水线的哪一段

前面按“反馈时延”分了层,这里再从 单次综合的 pass 顺序 串一遍,帮助定位每条报告命令在流水线的哪个位置产生。理解这条流水线,才能理解为什么 stat 在无库和有库阶段报的是 不同形态的结构。

各 pass 的职责:

  • • 📖 read_verilog:读源码,建立语法树。
  • • 🏗️ hierarchy -check:细化(elaboration),检查顶层、子模块、端口位宽。
  • • 🔄 proc:把 always 块转成 FF + 组合逻辑。此后 process 数量应为 0。
  • • 🧹 opt:常量传播、死代码消除、冗余清理。
  • • 💾 memory:推断 RAM/ROM。大数组是否推成 memory,这一步决定。
  • • 🔍 fsm:提取状态机,识别状态数、编码方式。
  • • 🧱 techmap:把 $add / $mux 等通用算子转成 $_AND_ / $_MUX_ 等 通用门。到这一步,stat 看到的是工艺无关的门级结构。
  • • 🗺️ abc -liberty:技术映射到标准单元库(调用 yosys-abc)。只有到这里才需要 .lib。
  • • 📊 stat:无库阶段看通用门和 DFF;有库阶段看映射后的面积和 slack。

💡 关键理解:stat 在 techmap 之后跑,看到的是 通用门结构($_AND_、$_MUX_、$_DFF_*),这是无库阶段最核心的报告;stat -liberty 在 abc -liberty 之后跑,看到的是 标准单元映射结果,这是映射环的相对尺子。两者回答不同问题,不能互相替代。


六、结构健康度:从缺陷检查到硬门禁

🩺 结构健康度是 门禁级信号。latch 不为 0、多驱不解决,不要进入下一阶段。

6.1 🚦 综合一致性检查:把隐性 bug 变成硬失败

check -assert 的价值是 把隐性 bug 变成 CI 硬失败。主要抓:

  • • 🔁 多驱动:多个 assign 驱动同一 wire。
  • • 🔌 未连接端口:模块端口悬空。
  • • ♻️ 组合反馈环路:combinational loops。
  • • 🚨 隐含 latch:$_DLATCH_ 出现。
  • • 🌫️ 悬空/未使用信号。

🛡️ 建议:CI 里把 check -assert 作为 门禁。不要只看 warning —— warning 很容易被淹没。断言式检查让明确结构错误 直接失败。

latch 检查 要结合结构统计:进程下推后如果出现 latch 相关 cell,目标数量是 0。不完整 if/case 是最常见来源。后端最怕 latch —— 对时序、测试、功耗都不友好。RTL 阶段补 default / else 成本最低。

6.2 🏗️ 模块层级完整性:hierarchy 检查

hierarchy -check -top top 检查:

  • • ✅ 顶层模块是否存在。
  • • ✅ 所有引用的子模块是否都已读取。
  • • ✅ 端口连接是否正确(位宽匹配)。
  • • ✅ 层次名是否还能定位。

💡 层次检查是 综合前的第一道防线。如果顶层找不到、子模块缺失、端口位宽不匹配,后面的统计和深度报告都不可信。

6.3 🔢 快速统计特定元素:select 计数

select -count 可以快速统计特定元素数量,作为 stat 的补充:


   
   
   
   
    
   
   
   
   select -count t:$dff       # DFF 数量
select -count t:$_DLATCH_  # latch 数量
select -count t:$_MUX_     # MUX 数量
select -count %co          # 组合逻辑输出数量
select -count w:*          # wire 总数

⚠️ 不同 Yosys 版本的 cell 类型名可能略有差异(如 $dff、$dffe、$adff、$sdff),正则要按你们日志 微调。

6.4 📊 结构构成统计:数量趋势与结构指纹

结构统计的重点 不是总面积,而是 结构构成和数量趋势。重点关注:

  • • 📦 cell 总量:总量趋势。
  • • 🔢 DFF / adff 数量:和手写状态位、流水级数是否匹配。
  • • ⚖️ 组合门占比:AND / OR / XOR / MUX / NOT。
  • • 🌳 MUX / pmux 数量:MUX 树深度预警。
  • • 💾 memory 数量 / memory bits:数组是否被推成 RAM。
  • • 🔄 process 数量:进程下推后应为 0。

💡 关键技巧:改 RTL 前后跑两次结构统计,diff 单元格数量。比如乘法器从普通阵列改成部分积压缩树,XOR 数从 156 掉到 80,说明压缩树真的简化了。

6.5 📐 位宽分布:找最大位宽信号

stat -width 按位宽列出寄存器信号,是 定位 DFF 异常集中点 的最快方式。重点看:

  • • 🔍 最大位宽的前 10 个寄存器信号。
  • • 🚩 出现远超预期的位宽(如 1024 位)。
  • • 💾 该信号在 RTL 中本应是数组还是寄存器。
  • • 🧩 是否和 memory 推断失败相关。

💡 如果 stat 显示 DFF 总数异常,而 stat -width 显示某个 1024 位信号占了绝大部分,基本可以锁定 memory 退化。

🧷 顺手提示:MUX 数量占比异常、DFF 数量远超预算,也是结构健康度要盯的两类信号。MUX 过多或位宽过大,往往同时推高深度、扇出、面积和布线拥塞;DFF 异常膨胀,常见根因是数组未推成 RAM、状态机 one-hot 过度、流水级数超出必要、手工寄存器堆展开。处理方向在“报告信号到 RTL 动作映射”一节统一给出。


七、时序潜力评估:拓扑深度与路径分布

⏱️ 时序潜力评估不依赖工艺库,看的是 拓扑深度和路径分布,不是绝对 ns。

7.1 📏 最长组合路径:ltp -noff

ltp -noff 输出 从输入到输出最长是几级门。不穿过触发器,只看 纯组合路径。

经验阈值只作相对参考:

  • • 🟢 ≤ 8 级:健康。
  • • 🟡 8~15 级:盯一下,看关键路径落在哪个操作。
  • • 🔴 15 级以上:大概率要流水或重构。

补充用法:


   
   
   
   
    
   
   
   
   ltp -all                    # 列出所有路径长度
ltp -noff -threshold 10     # 只显示超过 10 级的路径

⚠️ 不同模块阈值不同。控制逻辑 12 级可能已经很深,数据通路加法树 10 级可能正常。真正有价值的是 纵向对比:同一模块改完后从 17 降到 11,说明重构方向对了。

7.2 ⚡ 快速逻辑化简:abc -fast

abc -fast 在不做工艺映射的情况下,用 ABC 的内置算法简化布尔表达式,降低逻辑深度。之后再看 ltp 看改善幅度。

💡 这不是工艺映射,只是 逻辑化简。它回答的是“这版 RTL 的组合逻辑能不能被更紧凑地表达”,不是“这版能跑多快”。

7.3 🔁 等价性检查:miter + sat

miter 配合 sat 可以检测两个版本的 RTL 是否行为等价,常用于重构验证:


   
   
   
   
    
   
   
   
   miter -equiv gold rev
sat -verify

⚠️ 等价性检查验证的是 功能行为,不是“组合逻辑深度分布”。它适合回答“我重构后功能有没有变”,不适合替代 ltp 看深度。


八、面积效率评估:无库相对门数与资源共享

📐 面积效率评估在无库阶段看的是 相对门数和结构冗余,不是精确面积。

8.1 🧮 按技术库类型统计:stat -tech

stat -tech cmos 输出按 CMOS 原语(AND、OR、XOR、MUX、DFF)统计,不依赖 .lib。适合比较不同 RTL 实现的 “门数”相对大小。

💡 这是无库阶段最接近“面积代理”的指标。它不告诉你多少平方微米,但告诉你这一版比上一版多了多少门、少了多少门。

8.2 🔗 资源共享分析:share

share 会让工具自动尝试共享相同运算的逻辑(如两个加法器输入相同),减少面积。可以用 stat 前后对比看减少了多少 cell。

🎯 资源共享是 面积优化的重要手段。如果两个加法器在互斥条件下使用,share 可能把它们合并成一个。RTL 阶段主动写清互斥条件,比事后让工具猜更可靠。

8.3 🧹 常量传播优化:opt_expr -fine

opt_expr -fine 移除无用逻辑(常数赋值、死代码),优化后 stat 可以看到 cell 数下降。

💡 这不是“让工具帮你擦屁股”,而是 验证你的 RTL 有没有留下死逻辑。如果优化后 cell 数大幅下降,说明 RTL 里本来就有大量冗余。


九、可综合性评估:存储推断与状态机展开

🧩 可综合性评估回答的是 “工具有没有正确理解我的 RTL”,而不是“功能对不对”。

9.1 💾 存储推断:memory -nomap / memory -show


   
   
   
   
    
   
   
   
   memory -nomap
memory
 -show

显示所有被识别为 memory 的结构及其端口。如果预期是 SRAM 但没出现,说明 RTL 写法有问题。

常见退化原因:

  • • ❌ 组合 always 块里异步写数组。
  • • ❌ 动态索引混合、非对齐访问。
  • • ❌ 复位逻辑干扰存储推断。
  • • ❌ 读写端口模式不标准。

💡 一个 1024×32 的数组,推成 RAM 是一块存储;退化成 flop 阵列就是 三万多个触发器。每次看到大数组,都要看 memory 报告和 stat 的 memory bits。

9.2 🔍 状态机展开:fsm -expand


   
   
   
   
    
   
   
   
   fsm -expand
show -prefix fsm_graph -format dot

生成状态转移图(dot 格式),可以直观看到状态数、转移复杂度。

🎯 状态机编码对后端影响很大。大状态机用 binary 可能译码深,用 onehot 可能 DFF 多但组合浅。没有绝对好坏,要结合拓扑深度和结构统计看趋势。


十、调试辅助:可视化、网表导出与等价性检查

🔧 调试辅助不是日常门禁,但 定位问题时非常有用。

10.1 🖼️ 图形化电路结构:show


   
   
   
   
    
   
   
   
   show -prefix my_design -format svg

生成 SVG 格式的原理图,适合肉眼观察关键路径上的 MUX 树、加法器链。

💡 当 ltp 显示深度很大,但你看不出是哪条链时,show 可以帮你 肉眼定位。配合 fsm -expand 还能看状态机转移图。

10.2 📄 导出网表:write_verilog


   
   
   
   
    
   
   
   
   write_verilog -noattr synth_netlist.v

导出门级网表,可以用其他 EDA 工具进一步分析。

🎯 导出网表后,可以用脚本统计每个 net 的负载连接数,作为 高扇出检测 的补充手段。

10.3 🔁 等价性检查:miter + sat

前面已提到,miter 配合 sat 验证重构前后功能等价。这是 重构安全网,不是日常必跑项。


十一、高扇出专题:全局信号的 RTL 侧治理

🌐 高扇出 的本质不是“fanout 数字大”,而是 单点驱动大量负载,导致负载电容、transition、buffer 树、拥塞和功耗失控。

RTL 侧高扇出候选清单:

  • • 🔁 全局复位 / 置位:rst_n 驱动全设计寄存器。
  • • 🚪 全局时钟使能:en 连接数千个寄存器使能端。
  • • 🎛️ 全局模式选择:mode[1:0] 覆盖全芯片模块。
  • • 🌐 配置总线:顶层配置寄存器分发到各模块。
  • • 📊 valid/ready 反压:跨模块握手信号扇出累积。
  • • 🧪 测试模式:scan_en、test_mode 等全局信号。
  • • 🎚️ 大位宽选择信号:sel 驱动宽 MUX 选择端。

RTL 侧治理动作:

  • • 🔂 显式复制:顶层把复位、使能、模式信号复制多份,每份驱动一个模块或区域。
  • • 🕐 局部同步复位:减少全局异步复位扇出。
  • • 🚪 时钟门控:长时间保持使能的模块用 ICG 代替全局 enable。
  • • 🧱 模块边界寄存器化:模块输入先打一拍再使用。
  • • 🧩 分散组合条件:避免全局组合逻辑条件。
  • • 📦 配置信号分层分发:顶层复制后分发。

检测方式与边界:

  • • 📊 综合后看 buffer/inverter 占比:占比异常升高,排查高扇出。
  • • 📄 导出网表统计负载:脚本统计每个 net 的负载连接数。
  • • 🏷️ 命名审查:对已知全局信号重点排查。

⚠️ stat 和 ltp不直接报 fanout。select -count 可做粗略连接数统计,但 不要当成精确 fanout 工具。真正可靠的 fanout 数字来自综合后网表统计或后端报告。

🧷 关联提示:大位宽 MUX 是另一个典型的“扇出放大器”——选择信号要驱动所有位宽的所有选择器,位宽 512 时 sel 扇出可达 512。MUX 同时还是深度、面积和布线拥塞的放大器。处理方向:用选择计算代替选择数据、流水线拆开、互斥输入用 OR 树。DFF 异常膨胀则优先查 memory 推断、状态机编码、流水级数、手工寄存器堆,用 stat -width 和 memory 报告定位。


十二、同库相对映射:趋势校准与边界控制

🗓️ 工艺无关阶段日常每次提交都跑。轻量映射阶段 挂一个固定库,每周或里程碑跑。建议 锁死一个库,选定后不要频繁换。


   
   
   
   
    
   
   
   
   # 接无库阶段脚本
dfflibmap -liberty sky130_fd_sc_hd__tt_025C_1v80.lib
abc -liberty sky130_fd_sc_hd__tt_025C_1v80.lib -D 5000
stat -liberty sky130_fd_sc_hd__tt_025C_1v80.lib

重点看:

  • • 📉 同约束下 面积变化:改 RTL 后面积是涨是跌。
  • • 🚦 slack 趋势:只看过不过、趋势好不好,不读绝对 ps 值。
  • • 🎯 关键路径起点/终点:定位到具体模块,回头改 RTL。

⚠️ 再次强调:这里的面积/slack 是 相对尺子,不是 12nm 真实数字。换库数字全变,但趋势不变 —— A 改法比 B 改法好,在任何库下通常都好。


十三、面向后端的四类信号组织

🎁 后端同学真正关心的是 四类信号。

结构健康度:latch 目标 0、多驱/悬空目标 0、组合/时序比例正常、模块层次可定位。

时序风险:最大组合深度、关键路径落在哪个模块哪类操作、高扇出网清单、大 MUX 树位置。

面积风险:DFF 总数 vs 预期、memory 是否成功推断、MUX/乘加/比较器占比、大 MUX/优先级链。

可维护性:同约束下面积/深度变化曲线、baseline diff、功能回归是否通过。


十四、持续集成中的 QoR 轨迹与门禁

⚙️ 把上面脚本存成固定 QoR 脚本,构建文件可以这样写:


   
   
   
   
    
   
   
   
   qor:
    yosys -q -s rtl_qor.ys | tee reports/qor_$(shell date +%Y%m%d).log

qor-struct:

    yosys -q -s rtl_qor_struct.ys | tee reports/struct_$(shell date +%Y%m%d_%H%M%S).log

qor-map:

    yosys -q -s rtl_qor_map.ys | tee reports/map_$(shell date +%Y%m%d_%H%M%S).log

lint:

    verilator --lint-only -Wall top.v

sim:

    verilator --binary -j 0 top.v tb_top.v --top-module tb_top
    ./obj_dir/Vtb_top

CI 分 三档:

  • • 🔁 每次 push:快环结构检查 + Lint/功能回归。
  • • 📅 每周/里程碑:映射环,记录面积和 slack 趋势。
  • • 🏁 后期:签核环,不参与日常迭代。

💡 轨迹沉淀:把每次的 cell、DFF、latch、组合深度、memory bits、MUX 数量抽成结构化记录,画趋势线。关键不是解析脚本多复杂,而是 每次提交都留痕。


十五、报告信号到 RTL 设计动作的映射

🔧 报告信号 不是 让你直接改后端约束,而是让你 回到 RTL 找结构根因。

  • • 🚨 latch > 0 → 补 default / else,检查敏感列表。
  • • 💥 DFF 数 ≫ 预期 → 改 memory 访问模式,简化读写端口。
  • • 📐 某信号位宽异常大 → 查 memory 报告,改同步 RAM 模板。
  • • 📏 组合深度 > 15 → 插流水、拆阶段、用流水乘法/加法树。
  • • 🌳 MUX 占比高 → 改 one-hot 选择、并行编码、预译码。
  • • 🧱 MUX 位宽大且在关键路径 → 选择计算代替选择数据、流水线拆开、互斥输入用 OR 树。
  • • ⚖️ 宽比较器在关键路径 → 换减法/前缀结构、预计算、分段比较。
  • • 🌐 高扇出复位/enable/sel → 显式复制、寄存器打拍、局部使能。
  • • 🚦 slack 为负 → 先降组合深度,再谈后端优化。
  • • 💾 memory bits = 0 但 DFF 爆炸 → 检查动态索引、复位、读写模式。

十六、可信边界:相对反馈的适用范围

🚧 必须把边界 说清楚,避免误用。

  • • 🟢 工艺无关阶段:完全工艺无关,只看结构,趋势可信。
  • • 🟡 同库相对映射阶段:同库相对值,跨库 不能横向比 绝对数字。
  • • 🔵 线延迟、时钟树、OCV、串扰:前端结构统计 完全不知道。
  • • 🟣 功耗:没有 VCD/SAIF 活动率之前,数字 没意义,只做同比。
  • • ⚪ 绝对面积/绝对频率:不是 这套流程的目标。

16.1 ⚠️ 跨工艺反转风险

结构级“A 比 B 健康”大概率跨工艺成立,比如 memory 推断成功、组合深度更浅、latch 为 0、MUX 树更浅。

但 映射级“A 比 B 面积小/slack 好”只在同库可信。140nm 下 A 更好,到 12nm 可能反转,常见原因:

  • • 📏 线延迟占比不同:140nm 门延迟占比高,12nm 线延迟和拥塞占比高。
  • • 🧱 标准单元库比例不同:驱动强度、VT 种类、MUX/加法器实现差异大。
  • • 🌐 高扇出代价不同:140nm buffer 便宜,12nm 高扇出和时钟树代价更贵。
  • • 💾 memory compiler 不同:推断边界、端口限制不一样。
  • • 🔥 功耗密度和拥塞:12nm 下 DFF 多、MUX 大可能先撞功耗/布线。

🎯 正确用法:日常看工艺无关结构指标,跨工艺方向性可信;每周锁一个库看同库趋势;跨工艺结论最好在 目标工艺或近似节点 上复核一次。


十七、面向 NPU 数据通路的 PPA 检查清单

🧠 NPU 数据通路常见结构包括 MAC 阵列、部分积压缩树、加法树、累加器、激活/量化、MUX 选择、双缓冲 SRAM、权重/激活地址生成。

  1. 1. ✖️ MAC 阵列:乘加是否被识别为乘加结构?部分积压缩树是否合理?XOR/AND 数量是否符合压缩树预期?
  2. 2. ➕ 加法树:累加链是否过长?组合深度是否集中在加法树?是否需要分两级累加或流水?
  3. 3. 🌳 MUX 选择:权重/激活选择是否形成大 pmux?MUX 位宽是否过大?能否改 one-hot、预译码、选择计算或 OR 树?
  4. 4. 💾 SRAM/数组:权重、激活、输出 buffer 是否成功推断 memory?memory bits 是否与预期一致?
  5. 5. 📍 地址生成:地址计算是否在关键路径?能否预计算或打拍?
  6. 6. ⚖️ 量化/激活:比较器、饱和运算是否在关键路径?能否并行或分段?
  7. 7. 🌐 复位/使能:全局复位、enable、sel 是否高扇出?是否需要局部复位或复制?
  8. 8. 📏 流水级:每级组合深度是否均衡?有没有一级 18 级、下一级 3 级?
  9. 9. ✅ 功能回归:改结构后回归是否全过?
  10. 10. 🔄 baseline diff:cell、DFF、MUX、组合深度、memory bits 是否按预期变化?

十八、落地路径与总结

🌙 今晚就能跑 的五个动作:

  1. 1. 📦 装好 结构综合环境 —— 一键安装包最省事。
  2. 2. 📝 写一个固定 QoR 脚本,只放工艺无关阶段那几条命令。
  3. 3. ▶️ 对 正在写的模块 跑一遍,记下 五个数:cell 数、DFF 数、MUX 数、最大组合深度、latch 告警数。
  4. 4. 🔧 改一版代码,再跑一遍 diff。
  5. 5. 🎯 趋势对了,流程就活了。

推荐固定“体检套餐”:


   
   
   
   
    
   
   
   
   check -assert
hierarchy -check
ltp -noff
stat
stat -width
memory
 -show
fsm_info
show -prefix qor_view -format svg

分层使用建议:

  • • ⚡ 快环(秒级):check、stat、ltp、memory -show,每次提交都跑。
  • • 🔁 校准环(分钟级):abc -fast、share、miter+sat,PR 门禁或重构验证。
  • • 📅 映射环(分钟级):固定库映射,每周看趋势。
  • • 🏁 签核环(小时级):真实时序分析,后期再接。

🏁 这套流程 不追求前端签核,也 不追求工具堆料。它追求的是在写 RTL 的当天,用 轻量、工艺解耦的相对反馈,把 PPA 约束前移成 RTL 可执行的结构预算,提前发现后端最讨厌的结构问题:

  • • 🚨 latch。
  • • 🚨 多驱。
  • • 🚨 悬空。
  • • 💾 memory 推断失败。
  • • 📏 组合链过深。
  • • 🌳 MUX 树过重、位宽过大。
  • • 🔢 DFF 数量异常。
  • • 🌐 高扇出复位/使能/选择。

🎯 一句话收尾:PPA 约束前移的本质,不是提前算出芯片多大、跑多快,而是把后端最贵的结构风险,变成写 RTL 当天就能看见、能 diff、能门禁的设计反馈。

 


【声明】内容源于网络
0
0
ai算法芯片与系统
长期关注ai领域,算法,芯片,软件(系统,框架,编译器,算子库)等联合设计
内容 245
粉丝 0
ai算法芯片与系统 长期关注ai领域,算法,芯片,软件(系统,框架,编译器,算子库)等联合设计
总阅读7.4k
粉丝0
内容245