news 2026/3/19 10:02:22

基于Verilog的半加器设计:新手入门必看

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Verilog的半加器设计:新手入门必看

从零开始:用Verilog实现半加器,迈入数字设计的第一步

你有没有想过,计算机是怎么做加法的?
别急着回答“当然是CPU算的”——那我再问一句:CPU里的加法器又是怎么工作的?

答案可能比你想象的更简单。一切,都始于一个只有两个逻辑门的小电路——半加器(Half Adder)

这玩意儿看起来不起眼,但它却是构建整个数字世界算术能力的起点。今天我们就来手把手写一段 Verilog 代码,从真值表到仿真,完整实现一个半加器,并告诉你为什么每一个 FPGA 学习者都应该从它开始。


为什么是半加器?因为它够“小”,也够“深”

在所有组合逻辑电路中,半加器可能是最常被忽略、却又最重要的一环。

它只干一件事:把两个 1 比特的二进制数 A 和 B 相加,输出它们的“和”(Sum)与“进位”(Carry)。听起来很简单对吧?但正是这个简单的功能,构成了全加器、多位加法器、ALU,乃至现代处理器中复杂运算单元的基础。

更重要的是,对于初学者来说,半加器是一个完美的入门项目

  • 它没有时钟,不需要状态机;
  • 它逻辑清晰,可以直接从真值表推导出表达式;
  • 它代码短小,几分钟就能写完;
  • 它可测试性强,仿真结果一目了然;
  • 它还能作为模块被复用,体现“积木式设计”的精髓。

换句话说,你想学的 FPGA 开发流程——编码 → 综合 → 仿真 → 下载验证——都可以通过它走通一遍。


半加器是怎么工作的?

我们先来看一张最核心的表格:真值表

ABSumCarry
0000
0110
1010
1101

看到没?当 A 和 B 都为 1 时,二进制加法产生进位,Sum 变成 0,Carry 输出 1。这就是1 + 1 = 10的本质。

再观察一下规律:

  • Sum = A ⊕ B—— 异或运算,表示“不同则为1”
  • Carry = A · B—— 与运算,表示“全1才进位”

所以硬件上只需要两个门:一个异或门 + 一个与门。

📌 小贴士:之所以叫“半”加器,是因为它不处理来自低位的进位输入。真正的加法需要考虑三个输入(A、B、Cin),那种电路叫做“全加器”。而一个全加器,通常可以用两个半加器拼出来。


用 Verilog 写一个半加器

接下来就是动手环节了。下面这段代码,就是我们今天的主角:

// 1-bit Half Adder - Behavioral Model module half_adder ( input wire A, input wire B, output wire Sum, output wire Carry ); assign Sum = A ^ B; assign Carry = A & B; endmodule

就这么两行?没错!

关键点解析:

  • 所有端口都是wire类型,因为这是纯组合逻辑;
  • 使用assign实现连续赋值,对应实际电路中的连线和门级结构;
  • A ^ B自动综合成异或门,A & B综合成与门;
  • 接口命名清晰,方便后续例化。

这种写法属于数据流建模(Dataflow Modeling),是 Verilog 中最直观、也最常用的风格之一。比起画原理图,这种方式更接近“编程思维”,适合快速原型开发。


怎么验证它真的能工作?写个 Testbench!

写了模块还不算完,我们必须证明它是对的。这就需要一个测试平台(testbench)。

module tb_half_adder; reg A, B; wire Sum, Carry; // 实例化被测模块 half_adder uut ( .A(A), .B(B), .Sum(Sum), .Carry(Carry) ); initial begin $display("时间\tA\tB\tSum\tCarry"); $monitor("%0t\t%b\t%b\t%b\t%b", $time, A, B, Sum, Carry); #10 A = 0; B = 0; #10 A = 0; B = 1; #10 A = 1; B = 0; #10 A = 1; B = 1; #10 $finish; end endmodule

这段 testbench 做了什么?

  • 声明reg类型信号作为输入激励(只能在过程块中赋值);
  • 实例化我们的half_adder模块,使用命名端口连接,避免接错;
  • $display打印表头,$monitor自动监听信号变化并输出;
  • #10表示延迟 10 个时间单位,模拟输入切换;
  • 覆盖全部四种输入组合,确保功能完整。

运行后你会在控制台看到类似这样的输出:

时间 A B Sum Carry 0 x x x x 10 0 0 0 0 20 0 1 1 0 30 1 0 1 0 40 1 1 0 1

或者用 ModelSim 看波形图,会更直观地看到每个信号的变化趋势。

✅ 提示:#10在 testbench 中是可以综合的吗?不可以!但在仿真环境中完全合法,仅用于生成激励。


放进 FPGA 会发生什么?

如果你把这段代码放进 Vivado 或 Quartus,会经历这样一个流程:

  1. 语法检查→ 编译器确认你的 Verilog 没有拼写错误;
  2. 综合(Synthesis)→ 工具识别出你需要一个 XOR 门和一个 AND 门;
  3. 映射到 LUT→ 在 FPGA 上,这两个门会被打包进查找表(LUT)中;
  4. 布局布线→ 工具决定这些逻辑资源放在芯片哪个物理位置;
  5. 生成比特流→ 最终烧录到 FPGA 上运行。

虽然半加器太简单,几乎不会占用任何资源(可能只用了一个 CLB 的一部分),但它已经完整走完了工业级 FPGA 设计的所有关键步骤。

而且你会发现:你写的每一行代码,都在硬件中有对应的实体存在。这不是软件模拟,而是真正的“硬件即代码”。


它到底有什么用?不只是教学玩具

很多人觉得:“半加器这么简单,现实中谁还单独用它?”
其实不然。它的价值不在独立使用,而在构建更大系统的能力

典型应用场景包括:

🔹 构建全加器

一个全加器可以这样搭建:
- 第一级半加器计算 A+B 得到 S1 和 C1;
- 第二级半加器将 S1 与 Cin 相加得到最终 Sum;
- 两个 Carry 输出通过或门合并得到最终 Carry_out。

┌────────┐ A ──┤ │ │ HA1 ├── S1 ───────┐ B ──┤ │ │ ┌────────┐ └────────┘ ├───┤ │ │ │ HA2 ├── Sum ┌──────────────────────┘ │ │ Cin ───────────────────────────┤ │ └────────┘ ↑ Carry_in 输入 Final Carry = C1 OR C2
🔹 多位加法器的最低位

在一个 4 位加法器中,第 0 位是没有进位输入的,因此可以直接用半加器代替全加器,节省一个门电路。

🔹 ALU 中的基本加法路径

即使是高级处理器中的算术逻辑单元(ALU),其加法功能也是由一个个这样的基础单元堆叠而来。

🔹 教学与实训的核心案例

全国高校 EDA/FPGA 课程几乎都以半加器作为第一个实验项目。原因很简单:它能让学生第一次真正理解“代码变硬件”的全过程。


初学者常踩的坑 & 我的经验建议

别以为这么简单的电路就不会出错。我在带学生做实验时,见过太多“翻车现场”:

❌ 常见错误 1:用了非阻塞赋值<=

always @(*) begin Sum <= A ^ B; // 错!组合逻辑应该用阻塞 = Carry <= A & B; end

→ 虽然仿真可能没问题,但容易引起综合工具误解,导致意外锁存器或时序问题。

✅ 正确做法:组合逻辑优先使用assign,或者用always @(*)配合阻塞赋值=

❌ 常见错误 2:漏掉敏感列表或写错条件

always @(A) begin // 错!只监听 A,B 改变时不触发 Sum = A ^ B; end

✅ 应该写成always @(*)或显式列出所有输入:@(A or B)

✅ 最佳实践建议:

  1. 命名要有意义:比如ha_inst_lsb表示“最低位半加器实例”;
  2. 注释要到位:哪怕只有两行代码,也要说明每条语句的作用;
  3. 保持接口一致性:输入用input wire,输出用output wire,避免混用 reg/wire;
  4. testbench 要覆盖边界情况:虽然这里只有四种输入,但养成习惯很重要;
  5. 学会看综合报告:看看工具是否真的把你想要的门电路给综合出来了。

更进一步:你能怎么玩?

掌握了半加器之后,下一步你可以尝试:

  • 把两个半加器拼成一个全加器;
  • 用 4 个全加器搭一个 4 位行波进位加法器;
  • 加入寄存器变成同步加法器;
  • 用 Verilog 结构化建模方式重写半加器(用xorand原语);
  • 在 FPGA 开发板上接按键输入、LED 输出,实现真实硬件演示。

甚至有一天,你会意识到:你现在写的这个A ^ B,将来可能会出现在你自己设计的 CPU 核心里。


写在最后:伟大的系统,始于简单的逻辑

有人说,学 FPGA 最难的是入门。
因为你必须同时理解三件事:
- 数字逻辑(硬件行为)
- 编程语法(代码形式)
- 开发流程(工具链)

而半加器,恰好能把这三者完美串联起来。

它不复杂,但足够完整;它很小,但自成一体。当你第一次看到自己写的assign Sum = A ^ B;在 FPGA 上点亮 LED 显示结果时,那种“我真的让硬件动起来了”的感觉,是任何教科书都无法替代的。

每一次A + B的背后,都有一个默默工作的半加器。
每一段 Verilog 代码的背后,也都藏着一位正在成长的硬件工程师。

所以,别小看这短短几行代码。
你迈出的这一小步,也许正是通往数字系统设计大门的第一步。

如果你正在学习 FPGA,不妨现在就打开编辑器,敲下那句:

assign Sum = A ^ B;

然后告诉自己:我,开始懂硬件了。

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

效率对比:传统Flask开发 vs AI辅助开发全流程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个博客平台项目&#xff0c;分别用传统方式和AI辅助方式实现。功能包括&#xff1a;1.用户系统 2.文章发布(支持Markdown) 3.评论功能 4.标签分类 5.全文搜索。记录两种方式…

作者头像 李华
网站建设 2026/3/17 23:19:50

GLM-4.6V-Flash-WEB支持的多模态任务类型汇总介绍

GLM-4.6V-Flash-WEB 支持的多模态任务类型深度解析 在当前AI技术向“看得懂、问得清、答得准”演进的过程中&#xff0c;多模态大模型正从实验室走向真实业务场景。尤其是在内容平台、电商平台、智能客服等需要高频图文交互的系统中&#xff0c;开发者面临一个现实难题&#xf…

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

生态保护项目引入GLM-4.6V-Flash-WEB评估恢复成效

生态保护项目引入GLM-4.6V-Flash-WEB评估恢复成效 在一片刚刚完成退耕还林的山地&#xff0c;护林员举起手机拍下一张航拍图&#xff0c;上传到网页平台&#xff0c;输入问题&#xff1a;“当前植被覆盖情况如何&#xff1f;是否有裸露土壤或破坏痕迹&#xff1f;”不到30秒&am…

作者头像 李华
网站建设 2026/3/16 5:48:48

B站视频转文字实战指南:三步搞定高效内容提取

B站视频转文字实战指南&#xff1a;三步搞定高效内容提取 【免费下载链接】bili2text Bilibili视频转文字&#xff0c;一步到位&#xff0c;输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内容而反复暂停播放吗&#xff1f…

作者头像 李华
网站建设 2026/3/19 4:49:01

用AI打造智能斗鱼养殖监测系统

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个斗鱼智能养殖监测系统&#xff0c;使用传感器监测水温、PH值和溶氧量&#xff0c;通过AI分析数据并自动调节。系统需包含实时数据展示面板、异常报警功能和历史数据记录。…

作者头像 李华
网站建设 2026/3/13 20:56:41

从零搭建企业级云记事本:快马平台实战指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个企业级云记事本系统&#xff0c;功能包括&#xff1a;1. 用户注册/登录(支持OAuth) 2. 富文本编辑器(支持图片上传) 3. 多设备实时同步 4. 团队协作(多人同时编辑) 5. 版本…

作者头像 李华