编译器硬件仿真EDA【免费下载链接】iverilogIcarus Verilog项目地址https://gitcode.com/gh_mirrors/iv/iverilog点击查看免费下载Icarus Verilog 的-tblif目标把精化elaborate后的设计转换为 BLIFBerkeley Logic Interchange Format网表文件供伯克利大学开发的 ABC 综合与验证系统通过read_blif命令直接读取。本文从官方文档 tgt-blif.rst 出发结合 tgt-blif/ 目录下的真实源码与 ivtest/blif 回归测试完整讲解该目标的命令行用法、输入约束、输出网表结构、底层发射逻辑、支持单元清单与已知限制帮助你快速上手用 Icarus Verilog 驱动 ABC 做逻辑综合。1. BLIF 目标是什么定位与应用场景BLIF 是 ASIC 设计流程中常见的一种门级网表交换格式。Icarus Verilog 的 BLIF 代码生成器即-tblif目标把精化后的设计输出为.blif文件这个文件可以被 ABCA System for Sequential Synthesis and Verification伯克利大学开发的时序综合与验证工具通过其read_blif命令读入。也就是说这条路径的核心价值在于用 Icarus Verilog 做前端解析与精化把 HDL 设计变成 ABC 能消费的门级网表随后交给 ABC 做逻辑综合与优化。需要强调的是该目标主要服务于 ASIC 设计场景文档原话为 “This package contains tools sometimes used by ASIC designers”它与 Icarus Verilog 自带的仿真目标-tvvp用途完全不同它不生成可执行仿真代码而是生成面向综合工具的文本网表。2. 基本用法一条命令完成转换BLIF 目标的调用方式与其他目标一致通过-t开关选择目标、用-o指定输出文件。官方文档给出的命令格式为iverilog -tblif -opath.blif source files...其中-tblif选择 BLIF 代码生成目标-t后跟目标名blif见 Documentation/targets/index.rst 对-t开关的说明-opath.blif指定输出网表文件路径-o与路径之间不需要空格也可以写作-o path.blifsource files...一个或多个源文件可以是 Verilog、SystemVerilog、VHDL——凡是 Icarus Verilog 支持的 HDL 都可以前提是它们能精化elaborate到该代码生成器支持的有限子集。在源码层面-o参数的解析位于 tgt-blif/blif.cc 的target_design()入口函数首先通过ivl_design_flag(des, -o)取得输出文件路径随后定位设计的根作用域并最终调用emit_blif()把网表写入该文件若-o缺失程序会以assert(blif_path)的方式直接终止因此输出路径是必填参数。2.1 综合前的预处理链functor 链值得关注的是-tblif目标并不是直接把精化结果原样吐出而是在发射网表之前运行一组综合优化 functor。这一点记录在目标的配置文件 tgt-blif/blif.conf及其精简版 tgt-blif/blif-s.conf两个文件内容一致中functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLLblif.tgt其中functor:synth2/functor:synth执行逻辑综合synth与synth2分别位于仓库根目录的 synth.cc 和 synth2.cc把高层表达式转换为门级逻辑functor:syn-rules应用综合规则syn-rules.yfunctor:cprop做常量传播cprop.cc化简带常量的逻辑functor:nodangle移除悬空节点nodangle.ccflag:DLLblif.tgt加载blif.tgt动态库作为代码生成器。也就是说你的 HDL 源码会先经过 Icarus Verilog 的标准精化再经上述综合链优化为门级结构最后由 BLIF 发射器写出。这也是为什么文档要求输入必须是“结构化的”structural——顶层行为如进程无法被该目标处理详见第 6 节。3. 输入要求结构化设计的边界文档明确指出“This code generator is intended to process structural Verilog source code.” 即本目标面向结构化源码。具体约束如下源文件可以是 Verilog、SystemVerilog、VHDL只要最终能精化到该生成器支持的有限子集设计必须能降级为**显式逻辑门explicit logic gates与连续赋值continuous assignments**的组合——这是当前支持的全部内容顶层模块root module会被实例化出的子模块递归展开最终以单一扁平模型输出。从 tgt-blif/blif.cc 的target_design()可以印证这一约束的实现方式函数遍历设计的所有根作用域只接受类型为IVL_SCT_MODULE的模块作用域对于IVL_SCT_PACKAGESystemVerilog 包会打印 “Skipping package scope …” 并跳过遇到其他未知类型则报 “Dont know how to handle root scope …”。随后调用ivl_design_process()扫描设计中的进程任何进程都会触发错误输出%s:%u: sorry: BLIF: Processes not supported yet.对应源码见 tgt-blif/blif.cc 的process_scan_fun()。因此always/initial等行为代码initial块在精化后同样可能形成进程无法通过该目标输出这与文档“仅支持显式逻辑门与连续赋值”的说明完全一致。4. 输出模型特性扁平化与位展开BLIF 目标输出网表有三个结构性特征理解它们有助于读懂生成的文件单一根模块设计只能有一个根模块。该根模块的名字成为 BLIF 模型中.model记录的名字.model name。如果设计包含多个根模块生成器会列出所有找到的根模块并报错退出见 tgt-blif/blif.ccBLIF: The BLIF code generator requires that there be only one root module scope. Found these root modules: ...完全扁平化根模块可以实例化子模块子模块再嵌套子模块但输出模型会被完全展开flattened不产生任何子电路subcircuit调用。从 tgt-blif/blif.cc 的emit_scope()可以看到发射器从根模型出发递归遍历每个子作用域ivl_scope_childs()把所有逻辑门与 LPM 器件平铺写入同一个.model内最后统一以.end收尾。位向量展开bit explosionBLIF 和 ABC 处理的是“位”而不是“向量”因此模型的端口和内部所有位向量都会被拆解成一个个独立的位。在端口层面print_signal_bits()见 tgt-blif/blif.cc把每个信号按宽度逐个打印到.inputs/.outputs行在内部层面每个连接点nexus经由blif_nex_data_t见 tgt-blif/nex_data.h分配符号名并维护“规范位索引 → 信号位号”的映射get_name_index()。4.1 顶层模型骨架综合以上机制一个典型输出文件的结构为.model 根模块名 .inputs 所有输入位空格分隔 .outputs 所有输出位空格分隔 若干 .names / .latch / .subckt 记录 .end端口方向由ivl_signal_port()决定tgt-blif/blif.ccIVL_SIP_INPUT归入.inputsIVL_SIP_OUTPUT归入.outputs特别地IVL_SIP_INOUT双向端口会同时报错 “Model port … is bi-directional.” 并同时计入输入与输出两侧——BLIF 模型不支持双向端口。5. 源码级剖析网表如何被发射发射流程emit_blif()tgt-blif/blif.cc按顺序完成写.model头 → 收集并写出.inputs/.outputs→ 递归遍历作用域发射逻辑门与 LPM 器件 → 发射常量 → 写.end。下面逐类说明各类元件的发射细节。5.1 逻辑门.names 记录逻辑门由 tgt-blif/logic_gate.cc 的print_logic_gate()发射为 BLIF 的.names表格truth table记录。每个门的每一位都单独写出一条.names格式为.names 输入位1 输入位2 ... 输出位 输入组合 输出值支持的逻辑类型与对应真值表由ivl_logic_type()分派如下Icarus 逻辑类型发射的 .names 记录IVL_LO_AND所有输入为 1 时输出 1111… 1IVL_LO_OR任一输入为 1 输出 11- 1、-1 1两输入IVL_LO_XOR10 1、01 1两输入IVL_LO_NAND0- 1、-0 1两输入IVL_LO_NOR所有输入为 0 时输出 1IVL_LO_XNOR00 1、11 1两输入IVL_LO_BUF1 1IVL_LO_NOT0 1IVL_LO_PULLDOWN单输出、恒 00IVL_LO_PULLUP单输出、恒 11IVL_LO_BUFZ与 BUF 相同1 1任何未覆盖的逻辑类型会在网表中写入# ERROR: Logic type N not handled并累计错误计数rc 1。5.2 LPM 器件算术与时序单元精化后的较高层结构如加法器、比较器、触发器、多路选择器、移位等以 LPMLibrary of Parameterized Modules器件形式存在由 tgt-blif/lpm.cc 的print_lpm()按ivl_lpm_type()分派到各自处理函数。当前覆盖的 LPM 类型包括IVL_LPM_ADD/IVL_LPM_SUB加法/减法器lpm_add.ccIVL_LPM_CMP_EQ/IVL_LPM_CMP_EEQ/IVL_LPM_CMP_NE/IVL_LPM_CMP_NEE/IVL_LPM_CMP_GE/IVL_LPM_CMP_GT比较器lpm_cmp_eq.cc、lpm_cmp_gt.ccIVL_LPM_CONCAT/IVL_LPM_CONCATZ位拼接逐位用.names缓冲实现IVL_LPM_FF触发器lpm_ff.ccIVL_LPM_MUX多路选择器lpm_mux.ccIVL_LPM_PART_VP向量部分选择lpm_part_vp.ccIVL_LPM_RE_AND/OR/XOR/NAND/NOR/XNOR归约逻辑lpm_re_logic.ccIVL_LPM_SHIFTL/IVL_LPM_SHIFTR移位lpm_shift.ccIVL_LPM_SIGN_EXT符号扩展lpm_sign_ext.cc。以加法器为例tgt-blif/lpm_add.ccHDL 写法assign Q A ^ B ^ Cin; assign Cout AB | ACin | BCin;会被逐位展开为一系列.names真值表最低位Q[0] A[0] ^ B[0]逐位进位Cout通过/cout后缀命名的内部连接传递1 位加法器则只发射一条 XOR 记录并在文件头部以# file:line: IVL_LPM_ADD: widthN注释标明来源位置。5.3 触发器.latch 记录时序单元由 tgt-blif/lpm_ff.cc 发射为 BLIF 的.latch记录。最简单的上升沿触发器输出为.latch D位 Q位 re 时钟位 3其中re表示上升沿触发末尾的3是 BLIF 规定的 latch 初始化值编码。若存在时钟使能clock-enable发射器会先做一次等价变换把always (posedge C) if (CE) Q D;改写成always (posedge C) Q CE? D : Q;注释中说明 “In ASIC-land, this is probably OK”用一条.names与一条.latch组合实现。此外异步清零async clear与异步置位async set当前未实现遇到时会分别打印 “sorry: blif: Asynchronous clear not implemented yet” / “Asynchronous set not implemented yet” 并累计错误。5.4 常量.names 恒值记录设计中的常量由 tgt-blif/constants.cc 的emit_constants()统一发射它遍历设计中所有常量通过scope_is_in_model()tgt-blif/blif.cc只保留属于当前模型作用域之下的常量然后逐位写出。位值为 1 时输出.names 位名 # const 1加1行位值为 0 时输出只有头的.names 位名 # const 0空表即恒 0其他值如 x/z则以注释形式记录。6. 已知限制一览根据文档与源码-tblif目标当前的限制可以归纳为仅支持显式逻辑门与连续赋值行为级代码进程不支持遇到进程直接报 “Processes not supported yet”tgt-blif/blif.cc 的process_scan_fun()只能有一个根模块多个根模块会导致生成器报错并列出所有根模块名SystemVerilog 包作用域会被跳过不支持双向inout端口会报 “Model port … is bi-directional.” 错误触发器不支持异步清零/异步置位对应 LPM 触发器的 async clear/set 均未实现tgt-blif/lpm_ff.cc模型必须完全扁平化、位展开不产生子电路引用向量一律拆位。所有错误都会累加到全局blif_errors声明于 tgt-blif/priv.h最终由target_design()返回给上层作为退出码因此在命令行上可以通过退出状态判断转换是否成功。7. 回归测试如何验证转换正确性仓库在 ivtest/blif 目录下提供了完整的回归测试集包含 27 个.v源文件与对应的.v测试平台testbench并登记在 ivtest/blif.list 中条目blif01ablif02k、blif_shift、blif_sign_ext。这些测试由 ivtest/regress 回归框架驱动测试策略很有代表性源设计如blif01a.v用iverilog -tblif生成 BLIF 网表同时同一份文件在TEST_BENCH宏下编译为普通仿真逐位比对行为确保综合出的网表语义与 RTL 一致。以 ivtest/blif/blif01a.v 为例它定义了一个参数化宽度parameter WID 4的加法器addN内部用genvar生成循环实例化单比特加法器add1每个add1由两条连续赋值实现assign Q A ^ B ^ Cin; assign Cout AB | ACin | BCin;其测试平台用initial穷举所有A/B组合比较Q与adxbdx失败即打印FAILED。这个例子恰好同时覆盖了文档强调的两类受支持结构显式逻辑门add1内部的连续赋值与模块实例化addN实例化add1最终会被扁平化展开。如果你在自己机器上复现可以按第 2 节的命令对该文件单独执行iverilog -tblif -oaddN.blif ivtest/blif/blif01a.v并观察生成的.model addN、.inputs/.outputs位展开结果再尝试用 ABC 的read_blif addN.blif读入验证。8. 端到端工作流小结综合来看使用-tblif目标的完整工作流是编写结构化的 Verilog/SystemVerilog/VHDL 源码显式门、连续赋值、可精化的模块实例化执行iverilog -tblif -opath.blif source files...Icarus Verilog 完成精化经synth2 → synth → syn-rules → cprop → nodangle综合链优化tgt-blif/blif.confBLIF 发射器写出单一扁平.modeltgt-blif/blif.cc含.inputs/.outputs、.names真值表、.latch触发器与常量记录将.blif交给 ABC用read_blif命令读入做后续逻辑综合与验证。这条链路让 Icarus Verilog 可以扮演“HDL 前端 综合预处理器”的角色把行为语义稳定的结构化设计无缝送入 ASIC 界常用的 BLIF/ABC 生态是学习门级综合流程时一套轻量、可复现的本地工具链。赞分享编译器硬件仿真EDA【免费下载链接】iverilogIcarus Verilog项目地址https://gitcode.com/gh_mirrors/iv/iverilog点击查看免费下载相关推荐Icarus Verilog 网表Netlist格式全解析从解析、编译到代码生成的核心数据结构指南Icarus Verilog 网表Netlist格式全解析从解析、编译到代码生成的核心数据结构指南 导读 本文基于 Icarus Verilogiver编译器硬件仿真EDAOpenDesign Design System 2.0 Source Evidence 机制Token 溯源契约与派生输出治理实践OpenDesign Design System 2.0 Source Evidence 机制Token 溯源契约与派生输出治理实践 design syste编译器硬件仿真EDAIcarus Verilog VHDL 代码生成器-tvhdl实战指南从 Verilog 到 VHDL 的自动翻译Icarus Verilog VHDL 代码生成器 tvhdl实战指南从 Verilog 到 VHDL 的自动翻译 导读 Icarus Verilog 内编译器硬件仿真EDA上一篇如何轻松使用Outfit字体设计新手的终极资源指南下一篇CC组件生命周期管理如何正确处理Fragment、View等对象的跨组件传递创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考