
简介这份PPT课件围绕系统仿真展开面向电子设计与EDA学习者尤其是正在接触VHDL与FPGA/CPLD开发流程的初学者和授课教师帮助其在硬件制造前借助计算机模型验证电路逻辑、理解仿真在电子设计中的定位。压缩包内仅含1个PPT文件体积约654KB以章节化幻灯片形式组织内容便于课堂讲解或自学时按页梳理知识脉络。课件从仿真概念切入串联VHDL源程序仿真流程、设计库管理并给出AND门、三态缓冲器等实体与架构示例还专门讲解仿真激励信号的两种产生方式包括用VHDL编写波形信号发生器及顶层测试平台的组织方法。已有169人学习适合作为系统仿真入门的框架性资料配合示例代码理解行为描述与波形分析的基本思路。1. 系统仿真到底在“仿”什么从一次不用通电的电路实验说起你有没有见过这样的场景工程师在电脑上点几下屏幕上就跳出一堆波形图红的绿的线条上下翻飞旁边的人盯着看了一会儿说“这里时序不对得改”。奇怪的是桌上明明没有一块真实的电路板也没有接电源他们凭什么判断设计有问题这就是系统仿真要干的事。通俗地说系统仿真Simulation就是用计算机把整个硬件系统的行为“演”一遍让你在不接触真实硬件的前提下提前看到设计跑起来是什么样子。它像什么呢像拍电影前的预演——演员不用真上高空、真炸大楼先在绿幕前把走位和节奏对一遍哪里别扭当场就能改。电路设计也一样芯片流片一次成本高得吓人谁也不想等到实物做出来才发现逻辑写错了。所以系统仿真值得搞懂的地方在于它是电子设计里的一道“后悔药”。你写的设计描述不管是图形画出来的还是用硬件描述语言写出来的都能先扔进仿真器里跑看输出数据和波形对不对再决定要不要往下走。这份课件围绕的就是这套流程——仿真是什么、VHDL 源程序怎么仿真、激励信号怎么产生、测试基准怎么搭。2. 为什么不能直接上硬件仿真在 FPGA/CPLD 设计流程里的位置2.1 一条设计流程里仿真站在哪几个关口要理解仿真为什么存在得先看它在整条设计流程里被安排在哪。课件里给出的 FPGA/CPLD 设计流程大致是这样一条链设计准备与系统划分 → 原理图或 HDL 文本编辑 → 行为仿真 → 逻辑综合 → 结构综合适配 → 时序仿真 → 编程下载 → 落到具体器件和电路系统。注意这里仿真出现了两次而且位置很讲究。第一次叫行为仿真排在综合之前此时设计还停留在“描述意图”的阶段仿真器只关心你写的逻辑对不对不关心最终会映射到哪颗器件的哪个逻辑单元。第二次叫时序仿真排在适配之后这时候设计已经被翻译成具体器件的资源连接连布线延迟都算进去了仿真结果更接近真实芯片跑起来的样子。打个比方行为仿真像写剧本时的通读看故事逻辑通不通时序仿真像带妆彩排连灯光、道具、换景时间都算上看会不会因为某个演员换衣服太慢而穿帮。两者缺一不可前者帮你抓逻辑错误后者帮你抓延迟引发的时序问题。2.2 省下的不只是钱还有排查问题的顺序有人会问既然最后都要做实物为什么不直接烧进芯片测原因很现实实物调试是“黑匣子”式的。芯片焊在板子上你只能看到引脚上的信号内部某个中间节点到底翻没翻、翻早了多少纳秒探针都未必够得着。而仿真里所有内部信号都是敞开的想看哪个看哪个想在第几纳秒停就在第几纳秒停。更关键的是排查顺序。逻辑错误如果在综合之后才发现你可能已经花时间调了半天的引脚约束如果等到板子回来才发现那返工周期就是按周算的。仿真把问题拦在最便宜的阶段——改一行描述、重跑一次几分钟的事。课件里反复强调“间接的检测方法”这个“间接”不是退而求其次而是刻意把验证前移。提示仿真通过不代表实物一定通过它验证的是你描述的逻辑和时序模型器件本身的模拟特性、电源完整性这些仿真器管不了。2.3 VHDL 源程序仿真的完整链路课件里给了一张 VHDL 仿真流程图拆开看是这么几步VHDL 文本或图形输入 → 翻译成文本 → VHDL 编译 → 进入设计库 → VHDL 仿真 → 输出仿真结果数据和波形中间还有设计库管理在旁支撑。这条链路里“设计库”是个容易被忽略的角色。你写的每个实体ENTITY和结构体ARCHITECTURE编译后都进库仿真时仿真器从库里取。库管理得好多个模块互相引用才不会乱库乱了最常见的翻车就是“明明改了代码仿真结果还是旧的”——其实是编译产物没更新进库。举个最小例子感受一下链路终点。课件例 12-1 是一个与门LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY and1 IS PORT(aaa, bbb : IN STD_LOGIC; ccc : OUT STD_LOGIC); END and1; ARCHITECTURE one OF and1 IS BEGIN ccc aaa AND bbb; -- 输出等于两输入的逻辑与 END;这段描述编译进库后仿真器需要你给 aaa、bbb 喂激励它才能算出 ccc 的波形。实体部分定义“有几个脚、什么方向”结构体部分定义“脚之间什么关系”仿真就是沿着这个关系把输入的变化传导到输出。参数上STD_LOGIC 是标准逻辑类型取值包括 0、1、高阻 Z 等这也是后面三态缓冲器例子能表达“断开”状态的基础。3. 仿真里的几个关键角色激励、测试基准与三态行为3.1 激励信号仿真没有输入就等于空转仿真器本身不会凭空产生输入。你给它一个与门它不知道 aaa 该是 0 还是 1所以必须有人“施加激励”。课件给了两条路一条是用仿真器自带的波形设置命令直接强制信号值另一条是用 VHDL 写一个波形信号发生器。先看命令方式典型写法是forceforce a 0 # 把信号 a 当前值强制为 0 force b 0 0, 1 10 # b 在时刻 0 为 0时刻 10 变为 1 force clk 0 0, 1 15 -repeat 20 # clk 周期 20前 15 为 0后 5 为 1 run 500 # 推进仿真 500 个时间单位参数含义很直白信号名、值、时间点-repeat表示周期重复。这种方式上手快适合临时试探缺点是激励写死在命令里换一个设计就得重敲一遍不好复用。于是有了第二种方式用 VHDL 写信号发生器。课件例 12-4 的 SIGGEN 就是这么个东西ENTITY SIGGEN IS PORT ( sig1 : OUT INTEGER RANGE 0 TO 15; sig2 : OUT INTEGER RANGE 0 TO 15 ); END; ARCHITECTURE Sim OF SIGGEN IS BEGIN sig1 10, 5 AFTER 200 ns, 8 AFTER 400 ns; -- 三个时间点的取值序列 sig2 3, 4 AFTER 100 ns, 6 AFTER 300 ns; END;这里用信号赋值语句的时间表达式把“什么时候变成什么值”直接写进描述里。好处是激励成了可编译、可保存、可版本管理的代码换个设计改几个数字就行。注意AFTER后面跟的是相对当前时刻的延迟多个取值按顺序排开仿真器会自动在对应时刻驱动信号。3.2 测试基准给被测设计配一个“陪练”激励有了还得有个地方把激励和被测设计接起来这就是测试基准Test Bench。课件给的定义很干脆用来测试一个 VHDL 实体的程序。做法是在测试基准里把被测实体当成元件例化进来给它的输入接上激励然后编译运行这个测试基准观察被测实体的输出。测试基准有个鲜明特点一般不需要定义输入输出端口。因为它自己就是顶层没有“外面”给它信号所有激励都在内部产生结果也通过内部信号观察。课件例 12-5 的 BENCH 就是典型结构ENTITY BENCH IS END ENTITY BENCH; -- 空实体没有端口 ARCHITECTURE one OF BENCH IS COMPONENT ADDER4 -- 声明被测元件 PORT ( a, b : integer range 0 to 15; c : OUT INTEGER RANGE 0 TO 15 ); END COMPONENT; COMPONENT SIGGEN -- 声明激励发生器 PORT ( sig1 : OUT INTEGER RANGE 0 TO 15; sig2 : OUT INTEGER RANGE 0 TO 15 ); END COMPONENT; SIGNAL a, b, c : INTEGER RANGE 0 TO 15; -- 内部连线 BEGIN U1 : ADDER4 PORT MAP (a, b, c); -- 被测设计 U2 : SIGGEN PORT MAP (sig1 a, sig2 b); -- 激励接到被测输入 END;这段代码的骨架值得记住空实体 元件声明 内部信号 端口映射。PORT MAP就是把激励发生器的输出口和被测试设计的输入口用内部信号连起来相当于在仿真世界里拉了两根线。被测的 ADDER4 做的是c a b激励给 a、b 排好取值序列仿真波形上就能看到 c 跟着变。3.3 三态缓冲器仿真能表达“断开”这件事课件例 12-2 的 TRIBUF_and1 比与门复杂它带一个输出使能 oe输出可能是 0、1也可能是高阻 Z。高阻在仿真里的意义是“这根线现在不驱动”多个器件挂同一根总线时靠它避免打架。ARCHITECTURE behavior OF TRIBUF_and1 IS BEGIN PROCESS (in1, oe) BEGIN IF oeEVENT THEN -- 使能信号发生变化 IF oe 0 THEN y TRANSPORT Z AFTER ttxz; -- 关闭输出进入高阻 ELSIF oe 1 THEN y TRANSPORT in1 AFTER ttzx; -- 打开输出跟随输入 END IF; ELSIF oe 1 THEN y TRANSPORT in1 AFTER ttri; -- 使能保持有效时输入变化 ELSIF oe 0 THEN y TRANSPORT Z AFTER ttxz; END IF; END PROCESS; END behavior;这里几个 GENERIC 参数 ttri、ttxz、ttzx 是延迟时间分别对应“输入到输出”“使能到高阻”“使能到导通”的传输延迟。TRANSPORT关键字表示按指定延迟传输不做惯性延迟过滤。这段描述的价值在于仿真不仅能算逻辑值还能把“什么时候变成高阻、延迟多少”这种时序行为表达出来这正是纯逻辑真值表做不到的。4. 常见误区与易混概念别把仿真和这四件事搅在一起4.1 误区一仿真通过就等于设计没问题易混点把仿真当成验收标准。为什么混仿真确实能跑出漂亮波形容易给人“已经验证过了”的错觉。怎么区分仿真验证的是模型模型和实物之间有差距。行为仿真不包含布线延迟时序仿真虽然包含延迟但器件模型、温度、电压这些因素仍然简化处理。仿真通过只说明“在你给的激励和模型下没暴露问题”激励覆盖不到的场景它照样测不出来。4.2 误区二行为仿真和时序仿真是一回事易混点都叫仿真波形看起来也差不多。为什么混名字里都带“仿真”流程图上又都出现。怎么区分看位置和输入。行为仿真在综合之前输入是行为级描述关心逻辑功能时序仿真在适配之后输入是映射到具体器件资源并带延迟信息的网表关心功能和延迟一起作用下的结果。前者快、抽象后者慢、贴近实物。课件流程图把两者分列在综合前后就是在提醒这个顺序。4.3 误区三测试基准就是被测设计的一部分易混点测试基准里也写实体、也写结构体看起来像另一个模块。为什么混语法形式一样都是 VHDL 代码。怎么区分看端口和用途。被测设计有明确的输入输出端口是要被综合成硬件的测试基准通常没有端口只负责产生激励和观察结果它不参与综合、不会变成电路。把测试基准当成设计的一部分去综合是初学者常踩的坑。4.4 误区四激励只能用命令强制写代码是多此一举易混点force命令几秒钟就能让波形动起来何必写 SIGGEN。为什么混临时调试时命令确实快。怎么区分看复用和可追溯。命令式激励留在会话里关掉就没了换人接手看不懂VHDL 激励是代码能存进设计库、能改参数、能随设计一起版本管理。课件把两种方法并列给出不是让你二选一而是让你知道什么场景用哪种——试探用命令正式验证用代码。4.5 误区五高阻 Z 就是 0 或者没信号易混点波形上 Z 看起来平平的容易被当成低电平。为什么混不驱动和驱动为 0 在电压上可能接近。怎么区分Z 表示高阻是“这个输出端现在不参与驱动”逻辑上区别于 0 和 1。三态缓冲器例子里 oe 为 0 时输出 Z就是为了让同一根线可以被别的器件接管。仿真里把 Z 当 0 处理总线冲突类问题就永远测不出来。5. 什么时候该用仿真、什么时候别指望它一个计数器测试的边界判断5.1 一个具体例子8 位计数器的测试基准课件例 12-6 和 12-7 给了一个完整对照被测设计是一个 8 位计数器 counter8带时钟 CLK、复位 RESET、计数使能 CE、加载 LOAD、方向 DIR、数据输入 DIN 和计数输出 COUNT。测试基准 testbench 把它例化进来产生时钟和各类控制信号还把结果写进文本文件。-- 测试基准中的关键部分 File RESULTS: TEXT open WRITE_MODE is results.txt; -- 结果落盘 UUT: COUNTER8 port map (CLK CLK, RESET RESET, CE CE, LOAD LOAD, DIR DIR, DIN DIN, COUNT COUNT); -- 被测设计接入这个例子的看点在于“观察方式”。除了看波形它用过程 WRITE_RESULTS 把每个时刻的输入和 COUNT 写进文本时间、CLK、RESET、CE、LOAD、DIR、DIN、COUNT 一列列排好。波形适合人眼看趋势文本适合比对和留档两种观察手段互补。5.2 该用与不该用的分界线场景适合仿真不适合只靠仿真逻辑功能验证是行为仿真快速暴露逻辑错误—时序余量评估是时序仿真看延迟影响极端工艺角、温度漂移仍需实物验证总线竞争、三态冲突是Z 状态可观察—模拟特性、电源完整性—仿真模型通常不覆盖上板后的偶发故障—需要在线调试手段配合判断标准可以收成一句话凡是“描述里写清楚了的逻辑和时序关系”仿真都能帮你查凡是“描述之外、由物理世界决定的东西”仿真只能给参考。计数器这种纯数字逻辑仿真几乎能覆盖绝大部分功能问题但如果你要验证的是板级信号完整性仿真器就不是主角了。5.3 我自己的习惯早些年我做一个小项目图省事只用force命令临时敲了几组激励波形看着全对就直接往下走了。后来换人接手想复现当时那组激励命令早没了只能凭记忆重敲结果漏了一个使能组合问题在实物上才暴露。从那以后我每次做仿真哪怕只是验证一个与门都强制走一遍“写测试基准、激励进代码、结果落文件”的流程命令只用来临时探路。这套习惯不花多少时间但省下的返工次数血泪经验告诉我值。希望这份课件里的流程和例子能帮你在下次面对一个没见过的设计时知道先让它在计算机里跑一遍再决定要不要动手做实物。本文还有配套的精品资源点击获取