巴音郭楞蒙古自治州网站建设_网站建设公司_响应式网站_seo优化
2025/12/24 2:36:45 网站建设 项目流程

从零开始玩转Vivado:一个四输入多数表决器的完整实现

你是不是也曾在看到别人用FPGA做出炫酷项目时心生向往,却不知道该从哪里下手?
是不是打开Vivado后一脸懵:工程怎么建?代码写在哪?仿真怎么做?下载到板子上为啥不亮?

别急。今天我们就手把手带你走完一次完整的FPGA开发流程——从无到有,在Xilinx Vivado中设计一个“四输入多数表决器”,完成仿真、综合、引脚约束、生成比特流,最后烧录到开发板上点亮LED。

整个过程不跳步、不省略,适合第一次接触Vivado的新手。你会发现:原来FPGA开发,并没有想象中那么难。


先搞清楚我们要做什么

我们做的不是一个花哨的项目,而是一个典型的组合逻辑电路四输入多数表决器

它的规则很简单:

当四个输入信号 A、B、C、D 中,至少有三个为高电平(1)时,输出 Y 就为 1;否则为 0。

这就像开会投票:4个人举手,超过半数(≥3人)同意,决议通过。

这种电路的特点是:
-没有记忆功能,输出只取决于当前输入;
-不需要时钟,纯靠门电路实现;
-响应极快,延迟在纳秒级;
-非常适合入门练习,逻辑清晰、验证方便。

我们将使用Verilog编写逻辑,用Vivado 自带仿真器 XSIM验证功能,再通过XDC 文件绑定引脚,最终生成.bit文件下载到 FPGA 开发板上进行实物验证。

目标开发平台是常见的Artix-7 系列 FPGA 板卡(如 Basys 3、Nexys A7 等),但本教程通用性强,稍作修改即可适配其他 Xilinx 7系列板子。


第一步:创建工程,选对芯片

打开 Vivado(建议使用 2020.1 或更新版本),点击Create Project

接下来是一连串向导操作,我们一步步来:

  1. Project Name:比如叫majority_voter
  2. Project Location:选择你喜欢的路径
  3. Project Type:选 “RTL Project”,不勾选“Do not specify sources at this time”
  4. 添加源文件时,选择Add Sources → Create or add design sources
    - 点击“Create File”,类型选 Verilog,名字填majority_voter,添加进去

然后进入器件选择界面 (Default Part)

如果你用的是Basys 3开发板,就选:

Family: Artix-7 Device: xc7a35tcpg236-1

如果不确定,查一下你的开发板手册,找到对应的 FPGA 型号填写即可。

点 Finish 完成工程创建。


第二步:写核心逻辑 —— Majority Voter 模块

现在你已经有了一个空的 Verilog 文件。把下面这段代码复制进去:

// majority_voter.v module majority_voter ( input A, input B, input C, input D, output Y ); // 只要任意三个输入为1,输出就为1 assign Y = (A & B & C) | (A & B & D) | (A & C & D) | (B & C & D); endmodule

就这么几行,就是我们的全部逻辑。

为什么这么写?

这个表达式是从真值表推导出来的:只有当 ABCD 中有 ≥3 个 1 时,Y 才为 1。

所有满足条件的情况列举出来:
- A=B=C=1 →A&B&C
- A=B=D=1 →A&B&D
- A=C=D=1 →A&C&D
- B=C=D=1 →B&C&D

然后把这些项“或”起来,就得到了最终结果。

虽然可以用更高级的方法化简(比如卡诺图),但对于小规模逻辑来说,这样写最直观、最容易理解,而且综合效果很好。


第三步:仿真验证 —— 别急着上板,先看波形对不对

很多新手一上来就想下载到板子上看现象,结果灯不亮就开始怀疑人生。其实问题可能早在设计阶段就存在了。

正确的做法是:先仿真,确认逻辑正确后再综合和下载

写一个 Testbench 测试平台

右键点击工程 → Add Sources → Add or create simulation sources
新建一个 Verilog 文件,命名为tb_majority_voter

填入以下代码:

`timescale 1ns / 1ps module tb_majority_voter; reg A, B, C, D; wire Y; // 实例化被测模块 majority_voter uut ( .A(A), .B(B), .C(C), .D(D), .Y(Y) ); initial begin $monitor("Time=%0t | A=%b B=%b C=%b D=%b | Y=%b", $time, A, B, C, D, Y); // 枚举所有16种输入组合 A=0; B=0; C=0; D=0; #10; A=0; B=0; C=0; D=1; #10; A=0; B=0; C=1; D=0; #10; A=0; B=0; C=1; D=1; #10; A=0; B=1; C=0; D=0; #10; A=0; B=1; C=0; D=1; #10; A=0; B=1; C=1; D=0; #10; A=0; B=1; C=1; D=1; #10; // 应输出1 A=1; B=0; C=0; D=0; #10; A=1; B=0; C=0; D=1; #10; A=1; B=0; C=1; D=0; #10; A=1; B=0; C=1; D=1; #10; // 应输出1 A=1; B=1; C=0; D=0; #10; A=1; B=1; C=0; D=1; #10; // 应输出1 A=1; B=1; C=1; D=0; #10; // 应输出1 A=1; B=1; C=1; D=1; #10; // 应输出1 #10 $finish; end endmodule

关键点说明:
-$monitor会自动打印每一时刻的输入输出状态,便于日志检查;
- 每组输入保持 10ns,足够观察变化;
- 最终$finish结束仿真。

运行行为仿真

回到 Vivado 主界面,确保你在Simulation标签下。

右键点击tb_majority_voter.vSet as Top

然后点击左侧Flow Navigator中的Run Simulation → Run Behavioral Simulation

Vivado 会自动启动 XSIM 仿真器,弹出波形窗口。

你会看到类似这样的画面:
- 四个输入信号 A~D 依次变化;
- 输出 Y 在第7、11、13、14、15、16个状态变为高电平 —— 正是我们期望的结果!

还可以在 TCL 控制台看到$monitor输出的日志信息,逐行核对也很方便。

仿真通过!说明我们的逻辑没问题,可以继续下一步了。


第四步:告诉 Vivado 这些信号接哪个引脚

FPGA 芯片有很多 IO 引脚,但我们必须明确告诉工具:A 接哪个物理管脚?Y 接哪个 LED?

这就需要XDC 约束文件

创建 XDC 文件

右键工程 → Add Sources → Add or create constraints
新建一个约束文件,命名为project.xdc

填入如下内容(以 Basys 3 板为例):

## 输入按键分配(假设使用开关模拟) set_property PACKAGE_PIN J15 [get_ports A] # Switch 0 set_property IOSTANDARD LVCMOS33 [get_ports A] set_property PACKAGE_PIN L16 [get_ports B] # Switch 1 set_property IOSTANDARD LVCMOS33 [get_ports B] set_property PACKAGE_PIN M13 [get_ports C] # Switch 2 set_property IOSTANDARD LVCMOS33 [get_ports C] set_property PACKAGE_PIN R15 [get_ports D] # Switch 3 set_property IOSTANDARD LVCMOS33 [get_ports D] ## 输出连接LED set_property PACKAGE_PIN H17 [get_ports Y] # LED 0 set_property IOSTANDARD LVCMOS33 [get_ports Y]

📌 注意事项:
- 引脚编号一定要根据你的开发板原理图来定;
-IOSTANDARD设置为 LVCMOS33 表示 3.3V CMOS 电平标准;
- 不同板子引脚不同,请务必查阅官方文档替换对应 PIN 名称。

保存后,这个文件会被自动加入工程。


第五步:综合 + 实现 —— 把代码变成硬件连接

现在我们有了逻辑描述,也有引脚约束,接下来让 Vivado 把这一切“翻译”成真正的硬件配置。

点击左侧Run Synthesis

等待几分钟(视电脑性能而定),综合完成后弹出对话框,点Run Implementation

Implementation 包括布局布线(Place & Route),它会决定这些逻辑单元放在芯片的哪个位置,怎么连线。

完成后点击Generate Bitstream,生成最终的.bit文件。

如果中间出现报错,常见原因包括:
- 引脚已被占用(比如某个 PIN 已用于时钟或其他功能)
- 拼写错误(端口名与约束不一致)

只要前面步骤都正确,这里通常不会有问题。

✅ 成功生成 bit 文件,意味着我们可以下载了!


第六步:下载到开发板,看真实世界反馈

把开发板通过 USB 线接到电脑,确保供电正常。

点击菜单中的Open Hardware Manager

点击Open Target → Auto Connect,然后选择你的设备(通常是xc7a35t

双击设备名称,进入编程界面。

找到刚刚生成的.bit文件(一般在./majority_voter.runs/impl_1/目录下),选中并点击Program Device

几秒钟后,提示“Programming Succeeded”。

🎉 恭喜!你的设计已经运行在 FPGA 上了!


第七步:动手测试 —— 拨动开关,看灯亮不亮

现在你可以操作开发板上的拨码开关(或按键)来控制 A~D 输入。

按照我们的逻辑:
- 当任意三个开关拨到高电平(ON),对应的 LED 应该亮起;
- 少于三个时,LED 熄灭。

试试看吧!比如拨动 SW0~SW2(A/B/C)为 ON,SW3(D)为 OFF —— 灯应该亮!

💡 如果灯不亮,别慌,按下面顺序排查:
1. 检查电源是否正常;
2. 查看 XDC 文件中的引脚是否与实际板子一致;
3. 重新运行仿真,确认逻辑没错;
4. 检查下载器驱动是否安装(推荐使用 Digilent Adept 或最新版驱动);
5. 更换 USB 线或接口试试。


关于资源占用的小知识

这样一个简单的组合逻辑,到底占了多少 FPGA 资源?

在综合报告里可以看到:

资源类型使用数量
LUTs1
FFs0
IOs5

因为这是纯组合逻辑,不需要寄存器(FF),所以只用了1 个 LUT6(查找表)来实现整个函数。

也就是说,哪怕是最小的 Artix-7 芯片,也能放下成百上千个这样的模块。

这也体现了 FPGA 的优势:高度并行、资源丰富、灵活复用


这个案例能教会你什么?

别小看这个“简单”的项目,它实际上覆盖了FPGA 开发全流程的关键环节

阶段学到了什么
工程创建如何新建项目、添加源文件、选定目标器件
Verilog 编码组合逻辑的建模方式、assign 使用场景
Testbench 仿真功能验证的重要性、$monitor 和 initial 块的使用
XDC 约束引脚映射方法、IO 标准设置
综合与实现理解 RTL 到网表再到物理布局的过程
下载调试硬件连接、程序烧录、故障排查思路

更重要的是,你完成了从理论到实践的闭环验证
写了代码 → 看了波形 → 改了参数 → 烧上了板 → 看到了结果。

这才是真正意义上的“学会”。


后续可以怎么玩?

当你掌握了这套基本流程,就可以开始尝试更有意思的事情了:

✅ 加个时钟,升级成时序逻辑

比如做一个带计数功能的表决系统:每秒采样一次输入,统计过去10秒内有多少次表决通过。

这就需要用到always @(posedge clk)和寄存器了。

✅ 调用 IP 核

在 Vivado 的 IP Catalog 里搜索 “Clocking Wizard”,生成一个 50MHz 分频到 1Hz 的时钟,用来驱动 LED 闪烁节奏。

✅ 扩展成 8 输入表决器

试着写出八选五的逻辑表达式,看看综合后用了多少 LUT?

✅ 接入 AXI 总线(Zynq 用户)

如果你用的是 Zynq-7000 系列(如 Zybo Z7),可以把这个模块封装成 AXI Slave,让 ARM 处理器读取表决结果。


写在最后

很多人觉得 FPGA 很难入门,其实是被复杂的术语和庞大的工具链吓住了。

但只要你愿意动手,从一个最简单的组合逻辑做起,一步一步走过仿真、约束、综合、下载全过程,你会发现:

原来,掌控硬件的感觉,就这么开始了。

掌握 Vivado 不是为了记住菜单在哪,而是建立起一种工程化的思维方式:
设计 → 验证 → 实现 → 测试 → 迭代优化

而这,正是数字系统工程师的核心能力。

所以,别等了。关掉这篇文章,打开 Vivado,新建一个工程,敲下第一行module吧。

你的第一个 FPGA 项目,就从此刻开始。

如果你在实现过程中遇到了问题,欢迎留言交流,我们一起解决。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询