7.1 可综合性检查清单


7.1 可综合性检查清单

本节摘要:综合器只接受 VHDL 的一个子集。本节给出可综合性自查清单——能综合、慎用、不能综合三档,逐条讲清"为什么",并演示如何从综合日志里揪出 latch 与多驱动两类最隐蔽的警告。

三档清单:能、慎、禁

VHDL 语言为仿真而生,综合器实现的是其中一个"可综合子集"。把常用构造按三档分类:

档位 构造 说明
可综合 if/case/loop(定次数)、进程、并发赋值、实体架构、generate、泛型(常量类) 日常主力,放心用
慎用 整型信号、初始值、移位(变量移位量)、乘法 能综合但要注意资源与可移植性
禁止 after 延迟、wait until(在综合视角)、动态索引分配、文件读写、real 类型、无限循环 仿真专属,综合直接报错或忽略

禁用档逐条给理由。after 10 ns 是仿真调度语义,真实延迟由布线决定,综合器直接忽略——写了不报错但绝不生效,是最坑的"静默忽略"。动态分配(new)与指针在硬件里没有对应物。文件读写是测试台的特权。real 类型无法映射成位。无限 while 循环无法展开成有限电路。这份清单的通用规律:综合要的是"结构可确定"——位宽可定、次数可定、存储可映射,凡是运行时才揭晓的信息,综合器都无能为力。

慎用档的两个注意点

整型信号(integer、natural)可以综合,综合器按 range 推断位宽——range 0 to 9 推出四位。风险在于忘写 range:裸 integer 默认三十二位,占五个触发器还可能触发不必要的比较逻辑。工程习惯:端口用向量类型,内部确需整型时永远带 range。初始值也值得斟酌:FPGA 触发器支持初始值上电生效(这是与 ASIC 的重要区别),signal r : std_logic := '1' 能综合;但若依赖初始值而放弃复位,代码的可读性与 ASIC 可移植性都受损——复位策略要成套考虑,不要靠散落的初始值拼凑。

从日志里揪出两类隐蔽警告

综合日志的警告区比成功信息重要百倍,其中两类必须清零。第一类 latch 警告

WARNING: [Synth] inferred latch for signal y

含义是组合逻辑里存在不完整赋值,综合器造了锁存器补窟窿(第 3 章、第 4 章反复讲过成因)。定位方法:日志通常给出信号名与相关进程,回到代码补全分支或加默认值。第二类多驱动警告

WARNING: signal cnt has multiple drivers

同一信号被两个进程(或两条并发赋值)驱动。仿真里表现为 'X',综合器各建一套驱动再粗暴合并。定位:全局搜索该信号名,检查所有赋值点是否收敛到一个进程。两类警告的共同点:不阻断综合、只在报告里小声提醒,放过它们就等于把 'X' 和锁存器带到板子上。

图:可综合性判断的决策路径

图:可综合性判断的决策路径

动手:把一份"有病"代码治到全绿

拿一个故意埋了三处病灶的小设计做综合练习:一处 after 延迟、一处组合分支缺失、一处双进程驱动同一信号。跑综合,收集日志:after 被忽略(有警告)、latch 警告出现、多驱动警告出现。逐个修复——删 after(要延迟就打一拍)、补 else 分支、把第二处驱动合并进唯一进程——每修一个重跑一次,观察警告逐条消失。修复后的日志应该只剩常规信息。这个练习的价值在于建立"日志—代码"的条件反射:看到警告语句,脑中直接浮现代码位置。

⚠️ 常见坑:把综合警告当背景噪音。综合器的致命问题会直接报错,但 latch、多驱动、初始值忽略这类问题只以警告形式存在——上板后它们就是"偶发死机""输出打架""上电状态随机"的元凶。纪律:警告清单逐条过目,认领或修复,不允许无视

💡 关键直觉:可综合子集的边界不是语法限制,是"电路存在性"的边界。写代码时脑子里过一遍"这段对应多少门、多少触发器",过不去的写法自然不会出现。

本节要点回顾

  • 三档清单:能综合放心用、慎用注意位宽与复位配套、禁用是仿真特权;
  • 结构可确定是可综合性的总纲:位宽、次数、存储、时间四问定去留;
  • 整型必带 range,初始值可综合但要与复位策略成套考虑;
  • latch 与多驱动警告必须清零:前者补分支,后者收敛驱动点;
  • 逐条过目警告清单:认领或修复,不许当背景音。

实战延伸:Vivado 综合的 8 大禁令

  1. 不要在进程中调用 wait for(除了 clock process 内的固定时间)——综合工具会忽略非周期等待。
  2. 不要使用文件 I/O(TEXTIO)——只能用于仿真,不能综合。
  3. 不要用 initial 块给信号赋初值——除了一些工具支持,全局 reset 更可靠。
  4. 不要假设信号延迟(transport delay vs inertial delay)——综合后没有延迟语义。
  5. 不要用动态数组访问(access type)——综合需要静态边界。
  6. 不要在组合逻辑里用 after 子句——综合时会被忽略。
  7. 不要在实体端口用未约束的 std_logic_vector 范围——必须明确 downtoto
  8. 不要在时钟进程里读异步信号作为敏感源——必须先同步到本时钟域。

工具辅助

Vivado 的"综合检查报告"会列出所有不可综合的代码位置。Quartus 的"Analysis & Synthesis"消息分 info/warning/error。ModelSim 的 -lint 选项在编译阶段就报告。

写代码时遵循这 8 条,工程上 90% 的可综合性问题都消失了。

实战延伸:综合前自检的 3 步法

第一步:语法检查——ghdl -s file.vhdlmodelsim vcom file.vhdl。GHDL 的 -s 选项做语法+语义分析,捕获 80% 错误。

第二步:可综合性扫描——Vivado 的"Open Synthesized Design"前会自动跑可综合性检查;Quartus 的 Analysis & Synthesis 也会报告。看 Messages 窗口里的 error/warning 列表。

第三步:资源预估——Vivado 的 report_utilization、Quartus 的 Fitter Summary。资源超 90% 时即使综合成功也跑不稳(布线拥塞)。

工程上:CI 跑前两步,第三步定期看趋势。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U