FPGA入门实战:用DE10-Lite开发板复刻经典七人表决器电路
第一次接触FPGA开发时,很多人会被Verilog语法、开发工具链和硬件约束搞得晕头转向。其实最好的学习方式就是找一个具体项目动手实践。今天我们就以Intel DE10-Lite开发板为硬件平台,用最直观的方式实现一个七人表决器电路。这个经典案例不仅能帮你理解数字逻辑设计的基本思想,还能掌握Quartus Prime开发全流程。
选择DE10-Lite开发板主要考虑三点:一是价格亲民(约100美元),二是自带丰富外设(10个滑动开关和8个LED),三是完全支持免费的Quartus Prime Lite版。我们将用板载的SW0-SW6开关模拟七人投票,用LEDR0显示表决结果。当4个以上开关拨到"ON"位置时LED点亮,表示议案通过。
1. 开发环境准备
在开始编码前,需要准备好软硬件环境。硬件方面除了DE10-Lite开发板,还需要一条USB-Blaster下载线(通常随板附赠)。软件方面需要:
- Quartus Prime Lite Edition:Intel官方提供的免费版本,支持DE10-Lite所有功能
- USB-Blaster驱动:用于连接开发板与电脑
- ModelSim-Intel FPGA Starter Edition:进行功能仿真的轻量级工具
安装时特别注意:
- Quartus安装包约15GB,建议预留足够磁盘空间
- 勾选"Devices"时确保包含Cyclone V系列(DE10-Lite搭载的是5CSXFC6D6F31C6芯片)
- 安装完成后在设备管理器检查USB-Blaster驱动是否正常
提示:首次连接开发板时,需将电源开关拨到"USB"位置,通过USB供电。JTAG模式选择开关应拨到"RUN"。
2. 创建Quartus工程
启动Quartus Prime后,按照以下步骤创建新项目:
- File → New Project Wizard
- 设置工程路径和名称(如
voter7_de10lite) - 选择设备型号:
Cyclone V → 5CSXFC6D6F31C6 - 跳过EDA工具设置(暂时不需要第三方工具)
- 完成向导
接下来需要添加Verilog设计文件:
// File: voter7.v module voter7 ( input [6:0] sw, // 对应7个开关输入 output led // 表决结果输出 ); assign led = (sw[0]+sw[1]+sw[2]+sw[3]+sw[4]+sw[5]+sw[6]) >= 4; endmodule这段代码的精妙之处在于:
- 使用加法器自动统计"同意"票数
- 比较器直接输出表决结果
- 完全用数据流建模方式描述,无需复杂的状态机
3. 引脚分配与硬件连接
DE10-Lite开发板的物理资源与我们的设计需要完美匹配:
| FPGA引脚 | 开发板标记 | 功能说明 |
|---|---|---|
| PIN_C10 | SW0 | 投票人1输入 |
| PIN_C11 | SW1 | 投票人2输入 |
| PIN_D12 | SW2 | 投票人3输入 |
| PIN_C12 | SW3 | 投票人4输入 |
| PIN_A12 | SW4 | 投票人5输入 |
| PIN_B12 | SW5 | 投票人6输入 |
| PIN_A13 | SW6 | 投票人7输入 |
| PIN_A8 | LEDR0 | 表决结果输出 |
在Quartus中进行引脚分配有两种方式:
- GUI方式:通过Assignment Editor可视化配置
- TCL脚本方式:创建
.qsf文件直接写入约束
推荐使用TCL脚本方式,便于版本管理:
# File: voter7.qsf set_location_assignment PIN_C10 -to sw[0] set_location_assignment PIN_C11 -to sw[1] set_location_assignment PIN_D12 -to sw[2] set_location_assignment PIN_C12 -to sw[3] set_location_assignment PIN_A12 -to sw[4] set_location_assignment PIN_B12 -to sw[5] set_location_assignment PIN_A13 -to sw[6] set_location_assignment PIN_A8 -to led4. 功能仿真与调试
在下载到开发板前,建议先进行功能仿真验证逻辑正确性。ModelSim的基本使用流程:
- 在Quartus中设置仿真工具:
Assignments → Settings → EDA Tool Settings → Simulation - 创建测试激励文件:
// File: tb_voter7.v `timescale 1ns/1ns module tb_voter7; reg [6:0] sw; wire led; voter7 uut (sw, led); initial begin // 测试用例1:4人同意 sw = 7'b1111000; #10; // 测试用例2:3人同意 sw = 7'b1110000; #10; // 随机测试 sw = $random; #10; $stop; end endmodule- 运行仿真后,在波形窗口可以观察到:
- 当sw中有4个以上高电平时,led输出高
- 否则led保持低电平
常见调试技巧:
- 使用
$display在仿真时打印中间变量值 - 对复杂设计可添加SignalTap逻辑分析仪
- 遇到时序问题时,检查时钟约束是否合理
5. 下载与硬件验证
完成编译(Ctrl+L)后,生成.sof配置文件,通过USB-Blaster下载到开发板:
- 连接开发板并打开电源
- 在Quartus中打开Programmer(
Tools → Programmer) - 添加生成的
.sof文件 - 确保编程硬件显示为"USB-Blaster"
- 点击"Start"开始下载
实际操作演示:
- 将SW0-SW6中的任意4个或更多开关拨到ON位置(向上)
- 观察LEDR0会自动点亮
- 少于4个开关ON时LEDR0熄灭
如果遇到LED不亮的情况,按以下步骤排查:
- 检查开发板供电是否正常(PWR灯亮)
- 确认JTAG模式开关在"RUN"位置
- 重新插拔USB线尝试再次下载
- 用万用表测量LED对应引脚电压
6. 进阶优化方向
完成基础功能后,可以考虑以下扩展:
性能优化
// 使用并行前缀加法器优化关键路径 wire [2:0] sum1 = sw[0]+sw[1]+sw[2]; wire [2:0] sum2 = sw[3]+sw[4]+sw[5]+sw[6]; assign led = (sum1 + sum2) >= 4;功能扩展
- 添加表决结果锁存功能(按下按键时保存当前状态)
- 增加声音提示(通过板载蜂鸣器)
- 显示具体同意人数(用7段数码管)
时序约束示例
# 创建时钟约束(假设使用50MHz板载时钟) create_clock -name clk -period 20 [get_ports clk] # 设置输入延迟 set_input_delay -clock clk 2 [get_ports sw[*]] # 设置输出延迟 set_output_delay -clock clk 1 [get_ports led]实际项目中,我发现在Cyclone V器件上这个设计最高可以运行在约150MHz时钟频率。对于表决器这类组合逻辑电路,关键路径通常出现在加法器链路上。通过流水线化设计可以进一步提升性能,但会引入一个时钟周期的延迟。