简介这份资源是面向高校软件工程、电子信息等专业学生的FPGA数字系统设计实验报告对应西电软工院选课程第1次实验适合正在学习FPGA开发、VHDL硬件描述语言与Xilinx ISE集成环境的初学者参考。报告围绕层次化工程创建展开涵盖简单逻辑门的RTL描述、结构化电路描述、VHDL层次结构设计以及ISE中HDL编辑器的使用并完整记录了实验原理、实现步骤、测试结果与实验总结还附有AND_OR顶层模块原理图与底层电路说明。资源包共1个docx文档约267KB内容紧凑、结构清晰可直接对照完成实验报告撰写与代码调试。目前已有344人学习下载适合需要快速上手FPGA基础实验、理解RTL描述与层次化设计思路的同学借鉴。1. 从一份实验报告说起FPGA层次化工程到底练什么很多人第一次拿到 FPGA 实验报告看到“层次化工程创建”几个字第一反应是“不就是画个与门或门吗”。但真正动手把两个独立实体 MY_AND2、MY_OR2 用结构化描述拼成一个顶层 AND_OR再跑通语法检查、生成原理图你会发现卡住新手的从来不是逻辑本身而是工程结构、端口映射和元件例化这三件事。这份实验报告围绕 ISE 集成环境用 VHDL 完成简单逻辑门的 RTL 描述再通过层次化方式把底层模块串起来本质上是一次完整的“自底向上”设计流程演练。它适合刚接触 FPGA 开发、需要把课堂理论落到 ISE 操作上的学生也适合想回头补一补 VHDL 结构化描述基本功的工程师。下面我按实际复现顺序把这份报告里的技术点拆开讲透。2. 层次化工程创建从新建工程到两个底层实体2.1 为什么先建工程再写代码ISE 的工程文件管理方式和现在很多 FPGA 工具不同它把源码、约束、综合结果、仿真文件全部挂在同一个工程目录下。如果先写代码再补工程很容易出现源文件路径对不上、综合时找不到顶层模块的情况。常见做法是打开 ISE 后先通过 File → New Project 建立工程器件系列和型号按实验平台实际选仿真器可以选 ISim 也可以先跳过。工程建好后再通过 Project → New Source 分别添加两个 VHDL Module命名必须和实体名一致也就是 MY_AND2 和 MY_OR2。这里有个细节ISE 新建 VHDL Module 时会弹出一个端口定义向导很多人图快直接点下一步跳过结果实体里没有端口声明后面例化时顶层找不到信号可连。我一般会在这个向导里把输入输出端口先定义好或者干脆跳过向导手动在代码里补全。两种方式都行但端口名和方向必须和后续顶层例化严格对应。2.2 MY_AND2 与 MY_OR2 的 RTL 描述RTL 描述的核心是用 HDL 表达寄存器传输级行为对于纯组合逻辑门来说就是用一个并发赋值语句把输入和输出的逻辑关系写清楚。下面是我在复现这份报告时用的两个底层实体代码端口名和报告里的描述保持一致。-- MY_AND2.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MY_AND2 is Port ( A : in STD_LOGIC; B : in STD_LOGIC; Y : out STD_LOGIC); end MY_AND2; architecture Behavioral of MY_AND2 is begin Y A and B; -- 并发赋值综合后映射为与门 end Behavioral;-- MY_OR2.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity MY_OR2 is Port ( A : in STD_LOGIC; B : in STD_LOGIC; Y : out STD_LOGIC); end MY_OR2; architecture Behavioral of MY_OR2 is begin Y A or B; -- 并发赋值综合后映射为或门 end Behavioral;这两段代码的逻辑说明很直接Y A and B和Y A or B都是并发信号赋值综合工具会把它们分别映射成二输入与门和二输入或门。参数上唯一需要注意的是端口类型统一用STD_LOGIC不要混用BIT或STD_ULOGIC否则顶层例化时类型不匹配会报错。另外实体名和文件名必须一致ISE 对这一点比较敏感文件名写成my_and2.vhd而实体名是MY_AND2综合时可能提示找不到实体。2.3 语法检查与原理图生成两个底层文件写完后不要急着写顶层。先在 ISE 里对每个文件单独做一次 Check Syntax快捷键是右键文件 → Check Syntax。这一步能抓出大部分拼写错误、缺少库声明、端口方向写反的问题。语法通过后可以右键综合后的模块选择 View RTL Schematic看工具把and和or综合成了什么。常见情况是看到两个独立的门级符号输入输出端口和代码一致说明底层实体没问题。这里有个容易翻车的地方如果 Check Syntax 报错说STD_LOGIC未定义多半是忘了写use IEEE.STD_LOGIC_1164.ALL;。如果报错说实体名不匹配检查文件名和实体名是否完全一致包括大小写。ISE 在 Windows 下对大小写不敏感但综合器内部有时会区分统一用大写最省事。3. 顶层 AND_OR 的结构化描述元件例化与端口映射3.1 结构化描述和 RTL 描述的区别RTL 描述关注的是“这个模块做什么”比如Y A and B描述的是与逻辑行为。结构化描述关注的是“这个模块由哪些子模块组成、怎么连”它不直接写逻辑表达式而是通过元件例化和端口映射把底层模块拼起来。对于顶层 AND_OR 来说它内部实例化一个 MY_AND2 和一个 MY_OR2然后把外部输入信号分别接到两个子模块的输入端再把两个子模块的输出接到顶层输出端口。这种描述方式的价值在于层次清晰。底层模块可以单独仿真、单独综合顶层只负责连线。项目大了以后每个子模块可以由不同人维护顶层结构不变替换底层实现时不影响整体框架。这也是 FPGA 开发里常说的“自底向上”设计流程。3.2 顶层实体的端口定义顶层 AND_OR 的端口需要根据实际连接关系来定。假设我们要实现的功能是两个输入 A、B 分别同时送入与门和或门输出分别是与结果和或结果。那么顶层需要四个端口两个输入 A、B两个输出 Y_AND、Y_OR。实体声明如下。-- AND_OR.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity AND_OR is Port ( A : in STD_LOGIC; B : in STD_LOGIC; Y_AND : out STD_LOGIC; Y_OR : out STD_LOGIC); end AND_OR;端口方向说明A、B 是输入Y_AND、Y_OR 是输出。类型全部用STD_LOGIC和底层模块保持一致。这里不要图省事把两个输出合并成一个总线除非实验要求明确说要用向量否则分开写更直观也方便后面单独看波形。3.3 元件例化与端口映射的两种写法结构化描述的核心是component声明和port map例化。VHDL 里端口映射有两种写法位置映射和命名映射。位置映射要求端口顺序严格对应一旦底层端口顺序调整顶层就得跟着改维护性差。命名映射用端口名 信号名的形式顺序无关可读性好我一般优先用命名映射。-- AND_OR.vhd 架构部分 architecture Structural of AND_OR is -- 声明底层元件 MY_AND2 component MY_AND2 Port ( A : in STD_LOGIC; B : in STD_LOGIC; Y : out STD_LOGIC); end component; -- 声明底层元件 MY_OR2 component MY_OR2 Port ( A : in STD_LOGIC; B : in STD_LOGIC; Y : out STD_LOGIC); end component; begin -- 例化与门命名映射 U1: MY_AND2 port map ( A A, B B, Y Y_AND ); -- 例化或门命名映射 U2: MY_OR2 port map ( A A, B B, Y Y_OR ); end Structural;逻辑说明component声明告诉综合器“我要用一个叫 MY_AND2 的元件它的端口是这样”port map则把顶层信号和元件端口一一对应起来。U1、U2是例化标签同一个元件多次例化时标签必须不同。参数上需要注意的是port map左边的端口名必须和 component 声明里的端口名完全一致右边的信号名必须是顶层实体或架构里已经存在的信号。如果右边写了一个未声明的信号名综合会报“signal not declared”。3.4 综合后看原理图验证层次结构顶层写完后把 AND_OR 设为顶层模块右键综合然后 View RTL Schematic。正常情况下你会看到两个层次顶层是 AND_OR里面包含两个子模块 MY_AND2 和 MY_OR2子模块内部再展开成门级符号。如果原理图里只看到一个扁平的门电路没有层次说明综合器把层次展开了可以在综合选项里把“Keep Hierarchy”设为 Yes 或 Soft再看一次。这一步的验证价值在于它能直观告诉你端口映射有没有连错。比如你把与门的输出连到了 Y_OR原理图上会显示 Y_OR 接在与门输出端一眼就能看出来。比跑仿真看波形更快。4. 仿真测试与常见翻车点排查4.1 写一个最小 Testbench 验证逻辑原理图看的是结构逻辑对不对还得靠仿真。ISE 里可以新建一个 VHDL Test Bench 文件也可以手写一个简单的测试平台。下面是我常用的最小 Testbench给 A、B 各扫一遍四种组合观察 Y_AND 和 Y_OR 的输出。-- AND_OR_tb.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity AND_OR_tb is end AND_OR_tb; architecture Behavioral of AND_OR_tb is signal A : STD_LOGIC : 0; signal B : STD_LOGIC : 0; signal Y_AND : STD_LOGIC; signal Y_OR : STD_LOGIC; begin -- 例化被测顶层 UUT: entity work.AND_OR port map ( A A, B B, Y_AND Y_AND, Y_OR Y_OR ); -- 激励过程 process begin A 0; B 0; wait for 10 ns; A 0; B 1; wait for 10 ns; A 1; B 0; wait for 10 ns; A 1; B 1; wait for 10 ns; wait; end process; end Behavioral;逻辑说明Testbench 里用signal声明内部信号通过port map把被测模块的端口和这些信号连起来。process里按时间顺序给 A、B 赋值wait for 10 ns让每个组合保持 10 纳秒方便波形观察。参数上唯一要注意的是wait语句不能写在 process 外面否则仿真器会报错。仿真跑完后在 ISim 里看波形预期结果是Y_AND 只在 A1、B1 时为 1Y_OR 在 A0、B0 时为 0其余为 1。4.2 常见问题排查现象一综合报错“Entity MY_AND2 is not found”。原因通常是底层文件没有添加到工程里或者文件名和实体名不一致。解决方法是检查工程目录下是否有 MY_AND2.vhd以及文件里的实体名是否严格写成 MY_AND2。现象二顶层例化时报“Port Y of MY_AND2 is not connected”。原因是port map里漏写了某个端口的映射。命名映射虽然顺序无关但每个端口都必须出现。解决方法是对照 component 声明逐个检查确保 A、B、Y 都有对应。现象三仿真波形里 Y_AND 和 Y_OR 一直是红色或未知态。原因是 Testbench 里没有给输入信号赋初值或者被测模块的端口没有正确连接。解决方法是给 A、B 一个初始值比如signal A : STD_LOGIC : 0;并检查port map里的信号名是否和 Testbench 里声明的一致。现象四原理图里看不到层次结构。原因是综合选项里 Keep Hierarchy 没有打开。解决方法是右键 Synthesize → Process Properties把 Keep Hierarchy 设为 Yes 或 Soft重新综合。现象五Check Syntax 通过但综合报“Multiple drivers”错误。原因是同一个信号在多个地方被赋值。比如在顶层架构里既写了Y_AND A and B;又例化了 MY_AND2 把输出连到 Y_AND。解决方法是结构化描述里只保留例化不要再写并发赋值语句。5. 从这次实验延伸出去层次化设计的几个实用习惯层次化工程创建这个实验看起来简单但它练的是 FPGA 开发里最基础也最容易被忽视的能力把一个大设计拆成可独立验证的小模块再用顶层把它们连起来。我后来做更大的项目时发现几个习惯越早养成越好。第一底层模块的端口命名尽量统一。比如所有模块的输入都叫 A、B输出都叫 Y顶层例化时不容易连错。如果每个模块端口名都不一样顶层port map写起来容易串行。第二每个底层模块单独写一个最小 Testbench。不要等顶层写完再一起仿真底层模块单独验证通过后顶层出问题的概率会小很多。这次实验里 MY_AND2 和 MY_OR2 各跑一遍四种输入组合加起来不到二十行代码但能省掉后面大量排查时间。第三顶层文件里只放例化和连线不放逻辑表达式。结构化描述的意义就在于把行为和结构分开。如果顶层里又写Y_AND A and B;又例化 MY_AND2综合器会报多驱动错误而且层次结构也会乱掉。第四综合后先看 RTL Schematic再看 Technology Schematic。RTL 图看的是代码结构Technology 图看的是映射到具体器件后的资源。这次实验里 RTL 图能看到两个子模块Technology 图里会看到 LUT 和 IO 缓冲对照着看能理解综合器到底做了什么。第五养成看综合日志的习惯。ISE 的综合报告里会列出每个模块的资源占用、端口连接情况、警告信息。很多问题在日志里已经有提示只是被忽略了。比如“Port Y_AND is connected to multiple drivers”这种警告翻到日志末尾就能看到。从那以后我每次新建 FPGA 工程都会先把底层模块和对应 Testbench 建好单独跑通后再写顶层。这个顺序看起来多花了几分钟但后面省下的调试时间远不止这几分钟。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?