news 2026/3/12 20:23:57

FPGA项目实战:构建4位全加器并将和值数码管显示

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FPGA项目实战:构建4位全加器并将和值数码管显示

从加法器到数码管:在FPGA上实现一个“看得见”的4位计算器

你有没有过这样的经历?写了一堆Verilog代码,烧进FPGA板子后,逻辑看似正确,但就是不知道内部数据到底对不对。没有输出,就像黑盒运行——这正是初学者常遇到的困境。

今天,我们来做点“看得见”的事情:用FPGA搭建一个4位全加器,把两个二进制数相加的结果,实时显示在一个七段数码管上。整个过程不依赖电脑串口、也不靠逻辑分析仪,只靠一排拨码开关输入,一眼就能看到计算结果。

这个项目虽小,却完整走通了信号输入 → 算术运算 → 数据译码 → 物理输出的全流程。它是数字系统设计的“Hello World”,也是理解硬件行为本质的最佳入口。


为什么是4位全加器?

别看它简单,全加器可是现代处理器算术单元(ALU)的起点。哪怕是最强大的CPU,其加法功能也始于这样一个个小小的“1位全加器”模块。

我们要做的4位全加器,能完成如下任务:

  • 输入:两个4位二进制数 A[3:0] 和 B[3:0]
  • 外加一个进位输入 Cin
  • 输出:4位和值 Sum[3:0] + 最终进位 Cout

数学上就是:

Sum = A + B + Cin (模16)

结构上,它由四个1位全加器级联而成,采用串行进位(Ripple Carry)方式连接。虽然速度不如超前进位加法器,但胜在结构清晰、易于理解和实现,非常适合教学与入门实践。


搭建你的第一个组合逻辑模块:1位全加器

先来拆解最基本的单元——1位全加器。

它有三个输入:A、B、Cin
两个输出:S(和)、Cout(进位)

布尔表达式非常经典:

  • S = A ⊕ B ⊕ Cin
  • Cout = (A & B) | (Cin & (A ^ B))

这两个公式背后其实有直观含义:

  • 和S是“奇数个1就输出1”,相当于三输入异或;
  • 进位Cout发生于两种情况:AB同时为1(产生进位),或者其中一个是1且Cin也是1(传递进位)。

用Verilog写出来简洁明了:

// 1位全加器模块 module full_adder_1bit ( input A, input B, input Cin, output S, output Cout ); assign S = A ^ B ^ Cin; assign Cout = (A & B) | (Cin & (A ^ B)); endmodule

这段代码使用assign语句描述纯组合逻辑,没有任何时钟参与。也就是说,只要输入变了,输出立刻响应——这就是组合电路的本质:无记忆,只看当前


把四个小砖块砌成墙:构建4位加法器

现在我们把四个1位全加器连起来,形成4位串行进位加法器。

关键在于“进位链”的连接:低位的Cout接高位的Cin。这里我们用wire声明中间进位信号C[3:0],分别作为各级之间的桥梁。

// 4位全加器顶层模块 module adder_4bit ( input [3:0] A, input [3:0] B, input Cin, output [3:0] Sum, output Cout ); wire [3:0] C; // 内部进位线 full_adder_1bit fa0 (.A(A[0]), .B(B[0]), .Cin(Cin), .S(Sum[0]), .Cout(C[0])); full_adder_1bit fa1 (.A(A[1]), .B(B[1]), .Cin(C[0]), .S(Sum[1]), .Cout(C[1])); full_adder_1bit fa2 (.A(A[2]), .B(B[2]), .Cin(C[1]), .S(Sum[2]), .Cout(C[2])); full_adder_1bit fa3 (.A(A[3]), .B(B[3]), .Cin(C[2]), .S(Sum[3]), .Cout(Cout)); endmodule

这种结构化实例化的方式,让设计层次分明。每个模块各司其职,后期若要替换成超前进位结构,只需替换顶层连接方式即可,底层原语保持不变。

⚠️ 注意:由于是组合逻辑,必须确保输入稳定后再读取输出,否则可能采样到毛刺或中间态。


如何让人“读懂”FPGA里的数据?七段数码管登场

FPGA内部的数据是冰冷的0和1。要想让人眼能识别,就得翻译成视觉符号。这时候,七段数码管就成了最直接的选择。

常见的共阳极数码管长这样:

a --- f | | b | g | --- e | | c | d | ---

每一段对应一个LED。对于共阳极类型,所有阳极接VCC,阴极由FPGA控制。因此:

  • FPGA输出低电平(0)→ 段点亮
  • FPGA输出高电平(1)→ 段熄灭

比如要显示数字“5”,需要点亮 a、c、d、f、g,其余关闭。对应的控制字就是7'b0010010(顺序为 {a,b,c,d,e,f,g})。

于是问题来了:如何将Sum[3:0]自动转换成这7位控制信号?

答案是:BCD译码器


写一个“翻译官”:BCD转七段译码器

我们需要一个模块,能把4位二进制输入(当作BCD码处理)映射成对应的段选信号。

考虑到4位最大是15,而数码管通常只能准确显示0~9,所以我们做个小约定:

  • 若结果 ≤ 9,正常显示;
  • 若 ≥ 10,则统一显示“E”表示溢出或越界。

下面是核心代码:

// BCD到七段数码管译码器(共阳极) module seg7_decoder ( input [3:0] bcd, output reg [6:0] seg // {a,b,c,d,e,f,g} ); always @(*) begin case(bcd) 4'd0: seg = 7'b1000000; // 显示 0 4'd1: seg = 7'b1111001; // 显示 1 4'd2: seg = 7'b0100100; // 显示 2 4'd3: seg = 7'b0110000; // 显示 3 4'd4: seg = 7'b0011001; // 显示 4 4'd5: seg = 7'b0010010; // 显示 5 4'd6: seg = 7'b0000010; // 显示 6 4'd7: seg = 7'b1111000; // 显示 7 4'd8: seg = 7'b0000000; // 显示 8 4'd9: seg = 7'b0010000; // 显示 9 default: seg = 7'b1000111; // 显示 E(用于10~15) endcase end endmodule

这里用了经典的always @(*)组合逻辑块,配合case语句实现真值表查找。注意default分支的重要性——它保证了非法输入也能安全响应,避免综合工具生成锁存器。

✅ 小贴士:如果你的开发板是共阴极数码管,只需要把每一位取反即可。


整体系统整合:把所有模块串起来

现在我们有了三大部件:

  1. 输入源(拨码开关)
  2. 核心运算(adder_4bit)
  3. 输出显示(seg7_decoder + 数码管)

接下来,在顶层模块中将它们统一例化:

module top_module ( input [3:0] sw_a, // 拨码开关输入A input [3:0] sw_b, // 拨码开关输入B input cin_sw, // 进位输入开关 output [6:0] seg_out // 驱动数码管的7段信号 ); wire [3:0] sum; // 实例化4位加法器 adder_4bit u_adder ( .A(sw_a), .B(sw_b), .Cin(cin_sw), .Sum(sum), .Cout() ); // 实例化译码器 seg7_decoder u_decoder ( .bcd(sum), .seg(seg_out) ); endmodule

这个顶层就像“总指挥”,把各个功能模块粘合在一起。所有接口一一对应,干净利落。


硬件配置与调试要点

光有代码还不够,还得让FPGA知道哪个信号连哪根物理引脚。你需要在XDC约束文件中添加类似内容(以Xilinx Artix-7为例):

set_property PACKAGE_PIN J15 [get_ports {sw_a[0]}] # 对应开关0 set_property PACKAGE_PIN L16 [get_ports {sw_a[1]}] # ... 其他输入依次分配 set_property PACKAGE_PIN H15 [get_ports {seg_out[0]}] # 段a set_property PACKAGE_PIN K16 [get_ports {seg_out[1]}] # 段b # ... 直至段g

同时务必注意以下几点:

🔌 引脚分配准确性

必须查阅开发板原理图,确认拨码开关和数码管的实际连接引脚,否则会出现“按键无效”或“乱码”。

💡 加上限流电阻

每个数码管段建议串联220Ω ~ 1kΩ的限流电阻,防止电流过大损坏FPGA I/O或LED本身。很多开发板已内置,但仍需确认。

🧪 仿真验证不可少

在下载前,强烈建议编写Testbench进行功能仿真。例如测试组合(A=5, B=3, Cin=0)是否输出8(7+8)是否触发“E”提示。

// testbench 片段示例 initial begin A = 4'd5; B = 4'd3; Cin = 1'b0; #10; if (Sum === 4'd8) $display("Pass: 5+3=8"); end

常见坑点与解决秘籍

❌ 问题1:数码管显示乱码或全暗

  • 排查方向:检查是否搞错了共阳/共阴类型;
  • 对策:尝试将译码输出全部取反再观察。

❌ 问题2:按下某个键,数值跳变不止

  • 原因:机械开关存在抖动;
  • 对策:加入去抖模块(可用计数器延时消抖),或改用按键+同步寄存器采样。

❌ 问题3:明明输入是6+3=9,却显示“E”

  • 真相:可能是引脚接错导致某一位始终为高;
  • 技巧:先单独测试译码器,输入固定值看能否正常显示0~9。

❌ 问题4:仿真通过,板级失败

  • 重点怀疑对象:XDC引脚约束错误、电源异常、下载模式设置不当;
  • 建议:逐级隔离测试,先验证输入,再验证中间信号,最后看输出。

可以怎么继续玩?扩展思路推荐

别以为这只是个“玩具项目”。它的骨架足够灵活,可以轻松升级为更实用的功能模块:

✅ 双数码管显示(0~15)

把Sum[3:0]拆分为十位和个位,用动态扫描方式驱动两位数码管,真正显示十六进制结果。

✅ 添加减法功能

引入一个op_sel信号,当为1时执行减法(通过补码实现),变成简易ALU。

✅ 自动累加器

加入时钟和寄存器,实现每隔1秒自动+1,做成计数器或定时提醒装置。

✅ 结果存储与回显

加一个简单的RAM模块,记录最近几次运算结果,支持翻页查看。

✅ 接入真实传感器

后续可结合ADC模块读取温度、电压等模拟量,再用数码管显示数字化结果。


写在最后:最小单元中的工程哲学

这个项目从头到尾没用一行高级语言,也没有操作系统介入。但它完整展现了嵌入式系统的灵魂:

输入感知 → 数据处理 → 物理反馈

我们从最基础的门电路出发,一步步构建出具有实际交互能力的数字系统。每一个assign语句都在定义硬件行为,每一根连线都承载着信号流动的真实路径。

更重要的是,当你拨动开关、看到数码管亮起那一刻,你会真切感受到:硬件不是抽象的概念,而是可以触摸的逻辑世界

也许有一天你会设计CPU、做图像处理、跑AI推理。但请记得,一切伟大的工程,往往都始于这样一个小小的加法器。

正如那句话所说:从最小单元出发,构建无限可能

如果你正在学习FPGA,不妨今晚就动手试试。点亮第一个“看得见”的结果,也许就是你成为硬件工程师的真正起点。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/13 16:23:39

notepad-- macOS编辑器深度体验:从日常使用到专业开发的完整指南

notepad-- macOS编辑器深度体验:从日常使用到专业开发的完整指南 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器,目标是做中国人自己的编辑器,来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad--…

作者头像 李华
网站建设 2026/3/13 8:43:47

Windhawk深度体验:打造专属Windows系统的5个关键步骤

Windhawk深度体验:打造专属Windows系统的5个关键步骤 【免费下载链接】windhawk The customization marketplace for Windows programs: https://windhawk.net/ 项目地址: https://gitcode.com/gh_mirrors/wi/windhawk 厌倦了千篇一律的Windows界面&#xff…

作者头像 李华
网站建设 2026/3/10 15:57:53

如何快速汉化赛马娘DMM版:完整中文补丁安装指南

如何快速汉化赛马娘DMM版:完整中文补丁安装指南 【免费下载链接】umamusume-localify Localify "ウマ娘: Pretty Derby" DMM client 项目地址: https://gitcode.com/gh_mirrors/um/umamusume-localify 想要彻底告别赛马娘DMM客户端的语言障碍&…

作者头像 李华
网站建设 2026/3/13 2:18:39

Windhawk:Windows系统终极自定义解决方案完整指南

Windhawk:Windows系统终极自定义解决方案完整指南 【免费下载链接】windhawk The customization marketplace for Windows programs: https://windhawk.net/ 项目地址: https://gitcode.com/gh_mirrors/wi/windhawk 想要彻底改造你的Windows系统界面和功能&a…

作者头像 李华
网站建设 2026/3/13 9:29:34

开源看板工具Planka私有化部署:从团队协作痛点出发的完整解决方案

开源看板工具Planka私有化部署:从团队协作痛点出发的完整解决方案 【免费下载链接】planka planka - 一个优雅的开源项目管理工具,提供创建项目、看板、列表、卡片、标签和任务等功能,适用于需要进行项目管理和团队协作的程序员。 项目地址…

作者头像 李华
网站建设 2026/3/4 1:51:17

CCPD车牌识别实战三部曲:从零基础到精准识别的完整指南

CCPD车牌识别实战三部曲:从零基础到精准识别的完整指南 【免费下载链接】CCPD [ECCV 2018] CCPD: a diverse and well-annotated dataset for license plate detection and recognition 项目地址: https://gitcode.com/gh_mirrors/cc/CCPD 在车牌识别技术快速…

作者头像 李华