本节摘要:完整走一遍 VHDL 工程的最小闭环——设计文件加测试台,编译、仿真、导出波形、打开看信号。本节的产物是一个可以反复套用的工程模板,后面每一章的练习都在它上面生长。
这一节的动手目标非常具体:写一个带使能的门控 LED 控制器,给它配一个测试台,跑出波形,并在波形窗口里验证行为。整个闭环涉及两个源文件、五条命令、一次波形检查。先给出设计文件,端口有一个时钟、一个使能、一个输出:
library ieee; use ieee.std_logic_1164.all; entity led_gate is port ( clk : in std_logic; -- 板载时钟,上板后来自晶振 en : in std_logic; -- 使能:高电平允许输出翻转 led : out std_logic -- 接到板上的 LED ); end entity led_gate; architecture rtl of led_gate is signal reg : std_logic := '0'; -- 内部状态位,初值为低电平 begin process (clk) begin if rising_edge(clk) then -- 每个时钟上升沿检查一次 if en = '1' then reg <= not reg; -- 使能有效就翻转 end if; end if; end process; led <= reg; -- 状态位接到输出端口 end architecture rtl;
这个十几行的设计藏着后面几章的全部主角:进程、敏感表、时钟沿检测、if 嵌套、内部信号、端口赋值。现在不必逐个吃透,重点是把工程跑起来;每个概念都会在后续章节展开。你只需要确认一件事:这个电路在每个时钟上升沿,如果使能为高,就把输出翻转一次——行为上它是个可控的闪烁源。
测试台是没有端口的顶层实体,职责是给设计施加激励并观察响应。新建第二个源文件:
library ieee; use ieee.std_logic_1164.all; entity led_gate_tb is end entity led_gate_tb; -- 测试台不需要端口 architecture sim of led_gate_tb is signal clk : std_logic := '0'; -- 激励信号都在这里声明 signal en : std_logic := '1'; signal led : std_logic; begin -- 被测设计的实例:把测试台信号接到它的端口上 dut : entity work.led_gate port map (clk => clk, en => en, led => led); -- 时钟进程:每 10 ns 翻转一次,周期 20 ns clk_gen : process begin wait for 10 ns; clk <= not clk; end process; -- 激励进程:按时间表驱动 en,最后停机 stim : process begin en <= '1'; wait for 95 ns; en <= '0'; -- 中途关掉使能,看 led 是否停翻 wait for 40 ns; std.env.stop; -- VHDL-2008 的仿真结束方式 end process; end architecture sim;
三段结构值得记住:实例化(port map 把测试台信号与设计端口对应起来)、时钟进程(用 wait for 造出周期信号)、激励进程(按时间表改输入并最终停机)。dut 是被测设计的习惯名,全称 device under test。
在 GHDL 环境下,把两个源文件放同一目录,依次执行:
ghdl -a led_gate.vhd led_gate_tb.vhd ghdl -e led_gate_tb ghdl -r led_gate_tb --wave=wave.ghw gtkwave wave.ghw
第一条分析两个文件;第二条把测试台精化为可运行对象(注意精化的是测试台而不是设计本身,测试台才是顶层);第三条运行仿真并把波形写进文件;第四条打开波形窗口。厂商 IDE 里对应"运行行为仿真"一个按钮。波形窗口里把 clk、en、led 三个信号加进视图,应该看到:led 在每个时钟上升沿翻转,en 变低后 led 冻结不动。
⚠️ 常见坑:仿真一直跑不停机,是新手最常撞上的事——激励进程里忘了写停止语句,仿真器会永远循环时钟。老版本 VHDL 用
assert false report "done" severity failure;结束仿真,VHDL-2008 起推荐std.env.stop,GHDL 两种都认。
看到波形不算完成,完成的标准是在波形上做出判断:找到 en 拉低的那个时钟沿,确认 led 在它之后不再变化;再数一数 en 有效期间 led 翻转的次数,与你手推的期望一致。验证的思维要从"看起来动了"升级为"行为与预期逐点对上"。
两个扩展练习留给动手环节。练习一:把使能极性反过来——en 为低电平才翻转,改设计文件(提示:条件取反),重跑仿真确认。练习二:把时钟周期从 20 ns 改成 8 ns,观察仿真停机前翻转次数变多,体会"仿真时间"与"墙上时间"的区别:仿真里的纳秒是逻辑时间,跑多快取决于电脑。
💡 关键直觉:测试台与设计的关系是"考试卷与学生"。考卷出得全,学生的水平才能暴露得全。本节的测试台只考了使能开与关两件事,第 6 章会专门教你把考卷出得更刁钻。