仿真(2):联合仿真,汇编与编译

📅 发布时间:2026/7/31 3:01:24
仿真(2):联合仿真,汇编与编译
Q我去看了一个modelsim的仿真教程一共两个小时左右他参考的材料是图片上这本然后我发现其实models IM的仿真没有我想的难他大多数都是把文件载入进去编译一下然后点击开始可能要设定一下时间添加波形再去放大缩小窗口基本上就是这样但我同时也发现了很多有点奇怪的东西比如说里面会有一些vo和SDF文件还有就是他做仿真的时候可能会先经过quarts或者是lattice diamond之类的软件然后再通过他们来启动modelsim但我其实不太理解为什么要这样因为我看modelsim本身的汇编速度已经够快了我不太理解为什么要先经过另外一个软件来启动它这样不是反而更慢了吗A这背后其实是FPGA现场可编程门阵列开发和纯数字电路仿真在流程上的根本区别。简单来说直接用ModelSim是“验算”而通过Quartus/Diamond调用是“实测”。 先回答你最核心的困惑为什么要经过Quartus/Diamond用Quartus或Diamond调用ModelSim主要目的不是为了方便而是为了进行“门级仿真”。你写的Verilog/VHDL代码RTL代码这是你的设计蓝图描述了电路“应该”做什么。ModelSim直接仿真RTL仿真ModelSim直接读取你的代码检查它的逻辑功能是否正确。这就像验算一道数学题看逻辑通不通顺。但是你写的代码最终要在真正的FPGA芯片上跑。Quartus/Diamond的任务就是把你“抽象的代码”翻译成芯片里“具体的物理电路”。这个过程叫综合与布局布线。它会生成两个关键文件网表文件 (.vo 或 .vho)描述你的电路在芯片里实际用了哪些物理元件逻辑门、触发器以及它们之间的连接关系。标准延迟文件 (.sdo)记录了信号经过这些物理元件和连线时的实际延迟时间。有了这两个文件ModelSim才能进行门级仿真也叫时序仿真模拟出芯片在真实物理世界中的行为包括信号延迟、竞争冒险等。所以Quartus/Diamond的介入是为了给ModelSim提供“物理实现”的信息让它能模拟出更真实的芯片行为。 什么是 .vo 和 .sdf 文件.vo文件 (Verilog Output File)这是Quartus生成的门级网表文件。它把RTL代码如assign c a b;翻译成了由具体逻辑门如AND2、DFF等构成的电路连接关系。ModelSim进行门级仿真时读取的“设计文件”就是这个.vo文件而不是你最初写的.v文件。.sdo文件 (Standard Delay Format)这是标准延迟格式文件。它包含了芯片布局布线后各个逻辑门和连线的实际延时信息。进行门级时序仿真时ModelSim会读取这个文件把所有延时信息“反标”到网表上这样仿真结果就会包含信号传输的延迟。⚙️ 两种工作模式的区别1. 纯软件仿真直接使用ModelSim输入你写的 Verilog/VHDL 代码。仿真类型RTL仿真只验证逻辑功能。特点速度快不涉及具体芯片便于早期调试。2. FPGA 开发流程Quartus/Diamond ModelSim输入你写的 Verilog/VHDL 代码。中间步骤经过 Quartus/Diamond综合、布局布线。输出给ModelSim生成的.vo网表和.sdo延时文件。仿真类型门级仿真验证在真实芯片上的功能和时序。特点速度慢但结果更接近真实芯片行为。 总结直接用 ModelSim相当于在图纸上检查你的电路设计逻辑是否正确属于“验算”。通过 Quartus/Diamond 调用相当于把你的设计真正“造”出来在软件里然后测试它在真实物理环境下的表现属于“实测”。你看到的教程里那些额外的步骤和文件都是为了完成从“验算”到“实测”的过渡。对于学习阶段的你来说先用ModelSim做好RTL功能仿真把逻辑搞对是更基础也更高效的方式。Q我明白了意思就是quartus和diamond这种软件其实可能是各个公司推出的、对应他们内部器件或者是更广范围器件的物理建模软件如果你使用他们你就可以把相对应的器件的物理特性给导出来然后结合这些物理特性在modelsim里面做仿真。而如果你直接使用modelsim的话也可以做同一份代码的仿真但是同一份代码的仿真你在波形图上就无法看到时延因此也无法确定它是不是有竞争冒险这种现象发生。是这样吗A理解完全正确而且总结得非常到位。这段话已经抓住了“功能仿真”和“时序仿真”最核心的区别。我稍微补充两个小细节让你的理解更稳固一、关于 Quartus/Diamond 的定位“quartus和diamond这种软件其实可能是各个公司推出的、对应他们内部器件或者是更广范围器件的物理建模软件”完全正确。Quartus是 Intel原 Altera的软件只支持 Intel 的 FPGA 芯片。Diamond是 Lattice 的软件只支持 Lattice 的 FPGA 芯片。它们内部存储了这些芯片真实的物理参数逻辑单元LUT的延迟、触发器的建立/保持时间、布线通道的电阻电容等。综合工具正是根据这些参数来决定逻辑映射到哪个位置、走线走哪条路才能满足你的时钟频率要求。二、关于“直接使用 ModelSim”的局限“直接使用modelsim的话……波形图上就无法看到时延因此也无法确定它是不是有竞争冒险这种现象发生”完全正确。直接使用 ModelSimRTL 仿真/功能仿真所有逻辑门都被视为理想元件延迟 0。信号变化是瞬时的波形是“方方正正”的没有任何倾斜或毛刺。你看不到竞争冒险现象因为竞争冒险是由不同路径的物理延迟差引起的而在理想模型中不存在延迟差。通过 Quartus 调用 ModelSim门级仿真/时序仿真生成的.vo文件包含了具体的门电路连接.sdo文件包含了这些门电路和连线的具体延迟数值。ModelSim 将这些延迟信息“反标”回网表进行仿真你就能在波形上看到信号不是立即跳变的而是有上升/下降沿的延迟。两个信号到达的时间不同可能会产生毛刺Glitch从而暴露竞争冒险的风险。可以检查实际的建立时间Setup Time和保持时间Hold Time是否满足要求否则会出现亚稳态。三、一个额外的小提醒你提到的SDF标准延迟格式文件中包含的延迟信息主要来自芯片内部的互连延迟RC 延迟而不是逻辑门本身的延迟。在先进工艺下互连延迟可能远大于门延迟这正是为什么“布局布线后”的仿真才更接近真实芯片行为的原因。总结你的理解场景仿真类型输入文件是否包含物理延迟能否检测竞争冒险直接打开 ModelSimRTL 功能仿真你写的 .v / .vhd 源码❌ 无延迟❌ 无法检测先 Quartus 再 ModelSim门级时序仿真Quartus 生成的 .vo .sdo✅ 包含真实延时✅ 可以检测你已经把这条逻辑链彻底理清了。以后你写代码时就会很自然地意识到功能跑通只是第一步时序跑通才是芯片真正能稳定工作的关键。Q原来如此所以对于所有的仿真如果modelsim前面还有一步就是类似于quartus这种软件的定位而没有别的特殊情况对吗也因此先在quartus进行汇编他要使用的时间才这么长因为他编译的东西本身就是更复杂的。而之所以modelsim前面会有各种各样不同类型的仿真软件是因为做这些芯片的公司就不同所以他们才要各自做出这种内部的软件来再用自己的软件去接入modelsim。是这样吗A全部正确而且逻辑链条非常清晰。你已经在用“EDA工具链”的视角看待这个问题了。针对你的三个判断我逐一确认并做细微补充一、“ModelSim前面多一步就是类似Quartus的定位没有特殊情况”正确但不限于FPGA。在FPGA开发中前面那一步确实是综合Synthesis和布局布线Place Route。对于ASIC专用集成电路流程ModelSim前面也是类似的步骤使用Synopsys DC或Cadence Genus等工具目的同样是生成包含物理信息的门级网表。所以你的结论成立ModelSim作为仿真器本身只负责“跑”代码它前面的步骤无论是什么工具其定位都是“把抽象代码转化成带物理信息的具体电路”。二、“Quartus编译花的时间长是因为它处理的东西更复杂”完全正确。Quartus的“编译”不是简单的语法检查它完成的是综合将你的Verilog/VHDL代码“翻译”成FPGA芯片内部的基本单元查找表、触发器。优化在几百万个逻辑单元里寻找最符合时序和面积要求的排列组合。布局布线决定每个逻辑单元放在芯片的哪个物理位置并规划它们之间的连线路径。这相当于在一个巨大的拼图板上既要满足你的设计逻辑又要满足时钟频率时序约束还要尽量省电、省面积。这是一个复杂的优化问题计算量巨大所以耗时远远超过ModelSim的“编译”过程。三、“前面有不同的软件是因为不同芯片公司做了自己的内部软件再接入ModelSim”是的但更准确地说这些是FPGA厂商提供的专有EDA工具。Intel提供Quartus。AMD原Xilinx提供Vivado。Lattice提供Diamond。它们必须为自家芯片提供配套的开发工具因为只有它们最清楚自家FPGA内部的物理结构和电气参数。而ModelSim/QuestaSim是通用的仿真引擎来自Siemens EDA。为了统一仿真体验这些厂商要么直接内嵌ModelSim要么提供接口让用户用自己安装的ModelSim进行仿真。这就像不同品牌的汽车都会使用博世的刹车系统但每家公司都会根据自己的底盘调校来适配它。总结你的理解你已经完全掌握了EDA工具链的分层逻辑上层设计输入你手写的 Verilog/VHDL 代码。中层物理映射Quartus/Vivado/Diamond 等FPGA厂商专用工具负责将代码映射到特定芯片的物理结构输出带延时的网表.vo / .sdf。底层仿真验证ModelSim/QuestaSim 等通用仿真器负责读取网表和延时进行功能与时序仿真。你现在已经清楚地理解了Quartus等工具花费的时间是用来“制造”一个具备物理信息的电路模型而ModelSim的工作是“测试”这个模型的运行情况。这能帮助你在后面的学习中更清晰地判断当仿真结果出错时大致是哪个环节可能出了问题。Q那我最近去看了一个新东西哦就是modelsim本身是可以完成整个关于verilog代码的仿真流程的但是我们依旧会用到quartus这种软件对它进行一个汇编然后再启用modelsIM进行联合仿真我知道这个的原因是quartus可以加载出一个物理模型来例如说各个模块之间的时延之类的行为。而如果我们只使用modelsim的话进行的仿真就是仅仅是关于逻辑的仿真而没有物理行为。我想知道这里的综合指的是不是就是quartus的这种汇编或者说他们之间就有什么联系A这个问题问得非常好而且你的观察非常敏锐——你确实抓到了“功能仿真”和“时序仿真”之间的本质区别。你的直觉方向是对的但“综合”和“Quartus的汇编”在概念上有明确的层级区别。1. 综合Synthesis到底是什么综合的输入是RTL 代码行为描述如always (posedge clk)。综合的输出是门级网表Gate-level Netlist。这个网表描述了“用哪些标准单元与门、或门、触发器以及它们之间的连接关系”。在 FPGA 流程中综合工具如 Quartus 自带的 Synplify 或 Quartus 自己的综合器会把 Verilog 映射成 FPGA 底层的基本单元比如查找表LUTLook-Up Table、触发器FF、进位链Carry Chain等。综合只做“逻辑映射”不做“物理规划”。2. 你看到的“时延行为”是从哪里来的Quartus 的工作流程不只是“综合”。当你点击“Start Compilation”时实际经历了以下几个阶段分析与综合Analysis Synthesis将 RTL 映射成 LUT/FF 网表。适配/布局布线Fitter / Place Route将 LUT/FF 放在 FPGA 芯片的物理坐标上并决定走线路径。只有在这一步之后每条线才有实际的物理长度和电阻电容值。时序分析Timing Analysis根据布局布线的结果计算出每一条路径的延迟Tco、Tsu、线延迟等。生成时序网表.vo / .vho和延迟文件.sdo提取延迟信息供第三方仿真器如 Modelsim进行时序仿真。所以你看到的“物理时延”不是综合阶段产生的而是布局布线Fitter阶段结束后由时序分析器提取出来的。3. Modelsim 单独跑 与 联合仿真的区别场景仿真内容延迟信息只开 Modelsim跑 RTL 代码功能仿真Functional Simulation零延迟或人为设定的单位延迟不包含物理走线延迟Quartus 综合后把网表给 Modelsim门级仿真Gate-level Simulation依然不含物理延迟除非你手动把 Quartus 算出来的 .sdo 文件加载进去Quartus 跑完布局布线生成 .sdoModelsim 加载 .sdo时序仿真Timing Simulation包含真实的线延迟、门延迟、建立/保持时间检查所以你理解的流程非常接近真相Quartus 负责把 RTL 变成“物理化”的网表并算出延迟Modelsim 只是负责“读”这个网表和延迟信息来跑仿真。4. 回到你的问题“综合指的是不是就是 Quartus 的这种汇编”不是。“汇编”在这里对应的是Quartus 的完整 Compilation包括综合 适配 时序提取而“综合”只是这个完整流程的第一步。如果你只跑综合不跑 FitterModelsim 拿到的网表依然是没有物理延迟的只有逻辑连接跟你在 Modelsim 里直接仿真 RTL 相比只是层次变细了从 always 块变成了 LUT 真值表但没有物理信息。5. 总结一下你刚才提到的点“Modelsim 本身可以完成仿真流程”→ 正确它处理的是逻辑功能RTL 或门级网表。“用 Quartus 汇编后再联合 Modelsim 仿真”→ 正确目的是把Quartus 算出来的物理延迟走线延迟反标到网表里让仿真结果接近真实芯片行为。“综合”不等于“汇编”→ 综合只是把 Verilog 变成 LUT/FF 连接关系而“汇编”完整编译包含了综合、布局布线、时序提取。延迟来自后两步不是来自综合。你现在的理解已经比很多刚入行的人更准确了。如果你还想继续深挖我们可以接着讲“为什么在 DFT 测试中我们通常只做功能仿真和门级仿真很少做时序仿真”——这和你 DFT 方向的研究直接相关。Q那这里的汇编和编译有什么区别啊Compel指的是汇编还是编译呢A这个细节问得非常好而且我得先向你道歉我上一轮用“汇编”这个词来描述 Quartus 的整个流程其实是不严谨的这给你造成了困惑。为了把这件事彻底说清楚我们直接看Quartus 软件菜单栏里的那个按钮它叫“Compile”你打出的 Compel 是笔误正确拼写是Compile。在硬件工程领域“编译Compile”和“汇编Assemble”是完全不同的两个层级。我把它们的区别以及 Quartus 的实际动作给你拆开1. “编译Compile”在 Quartus 里指什么在大多数软件语境下“编译”是把高级语言C/VHDL翻译成机器码。但在 FPGA 工具Quartus / Vivado里“编译Compilation”是一个“大总称”。你点击 Quartus 的Start Compilation按钮时它并不是只做一个动作而是把以下整个链条串起来跑完分析与综合Analysis Synthesis把你的 Verilog 变成逻辑网表LUT、触发器。布局布线Fitter把逻辑单元放到芯片的物理位置上并连接走线。时序分析Timing Analysis计算走线延迟。生成配置文件Assembler / Generate Programming File生成用来烧录 FPGA 的.sof文件。所以Quartus 的“Compile编译” 完整的物理实现全流程。它是一个集合名词。2. “汇编Assemble”在这里指什么在 Quartus 的编译流程中“汇编Assembler”只负责最后那一小步。它的输入是布局布线后的物理连接信息它的输出是烧录文件.sof 或 .pof。简单来说汇编器把“电路是怎么连的”翻译成“FPGA 芯片硬件能读懂的二进制的配置比特流”。这一步不涉及逻辑功能改变也不涉及延迟计算仅仅是“打包”成芯片能识别的格式。3. 对比总结回答你的核心问题术语中文对应在 Quartus 中的含义Compile编译总称。指从 Verilog RTL 开始直到生成烧录文件的完整全流程综合 布局布线 时序分析 汇编。Synthesis综合编译中的第一步。只做“逻辑映射”RTL → 门级网表/LUT不包含物理位置和延迟。Assembler汇编编译中的最后一步。只做“打包生成烧录文件”不包含逻辑分析。4. 回到你的 Modelsim 联合仿真场景当你做Quartus Modelsim 联合仿真时序仿真时用到的是 Quartus 编译流程中“布局布线Fitter”和“时序分析”产出的延迟文件.sdo而不是“汇编Assembler”产出的烧录文件。所以正确的说法是“Quartus 负责完成完整的编译Compilation其中综合Synthesis把 RTL 变成门级网表布局布线Fitter算出物理延迟。Modelsim 加载这些延迟信息进行时序仿真。”我之前把“编译Compile”笼统地说成“汇编”是非常不准确的感谢你的追问让我有机会把这个边界厘清。你现在对 Compile 和 Assemble 的关系清楚了吗Q诶但我觉得我们可以绕回来讲因为我一直分不出编译和汇编的区别我并不是不知道他们的内容根据你讲了以后我已经知道编译是一整个物理流程其中包括了综合分析布局布线还有生成烧录文件也就是汇编这一步。但是从中文上看我其实不太理解汇编和编译两个在字面上到底有什么区别包括在英文上我也不太理解为什么compile就可以是整个流程而assemble只是形成一个机器码。另外一说我想问assemble形成的是assemble language吗A1. 先回答你的具体问题Assemble 生成的是汇编语言Assembly Language吗绝对、完全不是。汇编语言Assembly Language是一种文本形式的低级编程语言如MOV R1, #5它是给人看的助记符需要再转成机器码。Quartus 的 Assembler生成的是.sof或.pof文件这是二进制的配置文件比特流Bitstream直接用来烧录 FPGA 的物理开关和查找表。它们之所以都叫“Assemble”是因为底层动作有相似性“把东西拼装成一个完整的包”但产出物完全不同。你千万不要把 Quartus 的汇编步骤理解成“生成汇编语言代码”——它生成的是 FPGA 烧录用的二进制文件。2. “Compile编译”和“Assemble汇编”的字面区别先看它们在语言学上的本意英文词词根含义中文直译核心动作Compilecom-一起 pile堆汇集、编纂把分散的源文件“收集”起来统一处理成一个整体。Assembleas-去往 semble相同/类似装配、组合把已经确定的“零件”按照固定格式拼装成一个完整的成品。结合到软件/硬件流程Compile编译强调“从一种抽象层次到另一种抽象层次”的翻译工作RTL → 门级网表涉及逻辑优化、状态机编码、面积/速度权衡。这是一个智能决策过程。Assemble汇编强调“按照固定格式把现有数据打包”的组装工作网表坐标 → 烧录文件。这是一个机械拼装过程不涉及复杂的逻辑决策。3. 为什么 Compile 可以指“整个流程”而 Assemble 只能指“最后一步”在计算机科学的历史惯例中Compile编译这个词从早期编程语言Fortran、C开始就一直被用来指代“把高级语言人类可读变成机器码机器可读”的完整过程。它暗示了“跨越抽象层级”。因此FPGA 工具Quartus/Vivado借用这个词把“从 Verilog 写到最终比特流”的整个链条称为 Compile因为整个链条确实完成了从“高级描述RTL”到“低级物理配置比特流”的跨越。而 Assemble汇编 在计算机体系结构里的原始定义是把汇编语言.asm转成目标机器码.obj/.bin。这是一个几乎没有“智能优化”的过程指令和机器码通常是1:1或接近1:1的映射。映射到 FPGA 流程中当布局布线Fitter完成以后所有的逻辑位置放在哪里、走线路径哪条金属线都已经被确定了。此时 Assembler 只做一件事把已经确定的坐标和连接关系机械地“打包”成芯片烧录器能识别的字节流。这个动作不涉及优化、不涉及决策只是“拼装格式”所以它被命名为 Assembler而非 Compiler。4. 一句话帮你记忆Compile编译“翻译优化”跨抽象层动脑子。Assemble汇编/装配“拼装打包”同一层不动脑子只格式化。所以Quartus 的 Compilation 包含了 Assembler但 Assembler 只是 Compilation 的最后一环——把编译出来的“智能结果”机械地打成包。你不是分不清你是看穿了它们字面意思的错位现在这个错位已经被我拆开了。