news 2026/4/15 12:47:42

一位全加器结构化建模在Verilog中的应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一位全加器结构化建模在Verilog中的应用

从门级搭建开始:一位全加器的结构化Verilog实现

在数字系统设计的世界里,我们常常追求“高大上”的架构——多核处理器、高速缓存一致性协议、深度流水线……但所有这些复杂系统的根基,其实都始于一个极其简单却至关重要的模块:一位全加器(Full Adder, FA)

别看它只处理三个输入、产生两个输出,这个小小的组合逻辑电路却是构建整个算术运算体系的起点。无论是CPU中的ALU,还是FPGA上的矩阵乘法加速器,背后都有无数个全加器在默默工作。

而真正让这种基础模块变得强大的,并不是它的功能本身,而是我们如何用结构化的方式去建模和复用它。今天,我们就从零开始,手把手用Verilog完成一位全加器的门级结构化建模,看看这块“数字积木”是如何被精心打造出来的。


全加器的本质:不只是加法那么简单

先来问一个问题:为什么我们需要“全”加器?半加器不行吗?

当然可以——如果你只关心最低位的加法。但一旦涉及多位运算,就必须考虑来自低位的进位。全加器之所以“全”,就在于它能同时处理两个操作数A、B和一个进位输入Cin,从而支持级联扩展。

它的输入是三个1比特信号:
-A:第一个操作数
-B:第二个操作数
-Cin:来自低位的进位

输出也是两个:
-Sum:当前位的结果
-Cout:向高位传递的新进位

来看一张真值表,直观理解其行为:

ABCinSumCout
00000
01010
10010
11001
00110
01101
10101
11111

通过观察你会发现:

  • Sum = A ⊕ B ⊕ Cin
    这正是异或运算的典型特征:奇数个1时结果为1。

  • Cout = (A ∧ B) ∨ (Cin ∧ (A ⊕ B))
    意思是:只要A和B都为1(直接产生进位),或者其中一个与Cin共同作用导致溢出(即部分和加上进位再次进位),就应产生新的Cout。

这两个公式不仅是数学表达,更是硬件连接的蓝图。


结构化建模:把公式变成真实的电路

现在我们要做的,就是将上面的布尔表达式转化为实际的门级网络。这正是结构化建模(Structural Modeling)的核心思想:不依赖高级抽象描述,而是明确指定每一个逻辑门及其连接方式。

这种方式的优势在于:
- 清晰反映物理实现结构
- 易于进行时序分析与功耗估算
- 更贴近综合后的网表形式
- 特别适合教学演示和底层IP开发

下面我们一步步拆解这个逻辑网络。

第一步:计算A和B的部分和

wire sum_ab; xor (sum_ab, A, B);

这里我们用一个异或门得到A+B的中间结果。注意使用了wire类型作为中间信号,这是组合逻辑中标准的做法。

第二步:生成最终的Sum

xor (Sum, sum_ab, Cin);

将前面的部分和再与Cin异或一次,就得到了本位的最终和值。这就是三输入异或的实际电路实现方式。

第三步:生成两个进位源

进位由两部分构成:

  1. A和B同时为1时产生的进位:
    verilog wire carry_ab; and (carry_ab, A, B);

  2. 当前部分和(A^B)与Cin同时为1时产生的进位:
    verilog wire carry_sum_cin; and (carry_sum_cin, sum_ab, Cin);

第四步:合并进位输出

最后,只要任意一个进位路径激活,就应该产生Cout:

or (Cout, carry_ab, carry_sum_cin);

至此,整个逻辑链路完整闭合。


完整代码实现

下面是完整的Verilog模块定义:

// 文件名:full_adder_structural.v // 功能:一位全加器的结构化(门级)建模 module full_adder ( input A, input B, input Cin, output Sum, output Cout ); wire sum_ab; wire carry_ab; wire carry_sum_cin; // 第一级异或:A XOR B xor (sum_ab, A, B); // 第二级异或:(A XOR B) XOR Cin → Sum xor (Sum, sum_ab, Cin); // A AND B → 直接进位 and (carry_ab, A, B); // (A XOR B) AND Cin → 间接进位 and (carry_sum_cin, sum_ab, Cin); // 或门合并两个进位源 or (Cout, carry_ab, carry_sum_cin); endmodule

✅ 提示:这段代码完全可综合,可以在Xilinx Vivado、Intel Quartus或Synopsys DC等工具中顺利映射到实际门电路。


为什么选择结构化建模?对比其他风格

在Verilog中有三种常见的建模方式:

建模风格示例特点
结构化实例化门级原语明确电路结构,适合底层设计
数据流assign Sum = A ^ B ^ Cin;简洁高效,侧重信号流动
行为级always @(*) Sum = A + B + Cin;高度抽象,利于快速原型

虽然行为级写起来最省事,比如:

assign {Cout, Sum} = A + B + Cin;

一行搞定。但它隐藏了太多细节——综合工具可能会优化成不同的结构,甚至跳过门级实现直接使用LUT或DSP单元。这对于学习硬件本质来说是一种“黑箱”。

而结构化建模强迫你思考:“我是怎么搭出这个功能的?” 它让你看到每一条路径、每一个延迟来源,对理解后续的时序分析、关键路径、功耗分布至关重要。


不止是一个加法器:它是更大系统的基石

单个全加器的价值有限,但当我们把它当作“积木块”来复用时,奇迹就开始发生了。

构建4位纹波进位加法器(RCA)

设想我们要做一个4位加法器。最简单的办法就是把四个全加器串起来:

module ripple_carry_adder_4bit ( input [3:0] A, input [3:0] B, input Cin, output [3:0] Sum, output Cout ); wire c1, c2, c3; full_adder fa0 (.A(A[0]), .B(B[0]), .Cin(Cin), .Sum(Sum[0]), .Cout(c1)); full_adder fa1 (.A(A[1]), .B(B[1]), .Cin(c1), .Sum(Sum[1]), .Cout(c2)); full_adder fa2 (.A(A[2]), .B(B[2]), .Cin(c2), .Sum(Sum[2]), .Cout(c3)); full_adder fa3 (.A(A[3]), .B(B[3]), .Cin(c3), .Sum(Sum[3]), .Cout(Cout)); endmodule

你看,没有任何重复逻辑,只需要例化四次相同的模块。这就是模块化设计的力量

不过也要注意它的缺点:进位要一级一级传递,导致延迟随位宽线性增长。例如第4位的Cout必须等到前三位全部计算完毕才能得出。这种“纹波效应”限制了最高频率。

解决方案?当然是更高级的超前进位加法器(CLA),它通过提前预测进位来打破延迟瓶颈。但我们今天的主角仍是那个最原始、最扎实的一位全加器——没有它,CLA也无从谈起。


工程实践中的几个关键考量

当你真的把这个模块放进项目中时,以下几个问题值得深思:

1. 可测试性设计(DFT)

结构化模型天然适合插入扫描链。你可以轻松地在每个wire上添加观测点,便于后期芯片测试中捕获内部状态。

2. 综合工具会不会“破坏”你的设计意图?

现代综合工具非常聪明,可能会把你写的门级结构优化成查找表或其他等效结构。如果你希望保留特定拓扑(比如为了匹配版图规划),可以用(* keep *)syn_keep属性锁定信号:

wire sum_ab /* synthesis keep */ ;

3. 参数化扩展建议

虽然目前是一位加法器,但可以通过参数化支持任意宽度:

module nbit_adder #( parameter WIDTH = 4 )( input [WIDTH-1:0] A, B, input Cin, output [WIDTH-1:0] Sum, output Cout ); genvar i; wire [WIDTH:0] carries; assign carries[0] = Cin; generate for (i = 0; i < WIDTH; i = i + 1) begin : fa_stage full_adder fa_inst ( .A(A[i]), .B(B[i]), .Cin(carries[i]), .Sum(Sum[i]), .Cout(carries[i+1]) ); end endgenerate assign Cout = carries[WIDTH]; endmodule

这样只需修改参数就能适配不同场景,极大提升复用效率。


写在最后:掌握“第一块积木”,才能搭建高楼大厦

也许你会觉得:“一个加法器而已,有什么好讲的?”

但请记住:所有复杂的数字系统,都是由最简单的单元层层堆叠而成的。就像建筑师不会忽视每一块砖的质量,优秀的数字设计师也绝不会轻视任何一个基础模块的实现方式。

通过本次对一位全加器的结构化建模,我们不仅掌握了门级电路的构建方法,更重要的是体会到了:
- 模块化设计带来的可维护性和可扩展性
- 从数学公式到物理电路的转化过程
- 如何写出既符合逻辑又利于综合的Verilog代码

下一步,你可以尝试:
- 为该模块编写Testbench并做功能验证
- 对比结构化、数据流、行为级三种风格的综合面积与延迟
- 将其集成进一个简易ALU中,支持加减法切换
- 探索如何将其改造成低功耗版本(如采用传输门逻辑)

当你能够熟练驾驭这些“小东西”时,那些曾经遥不可及的高性能计算架构,也就不再那么神秘了。

如果你在实现过程中遇到了其他挑战,欢迎在评论区分享讨论。我们一起把数字世界的地基打得更牢。

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

媒体真实性挑战:新闻机构如何标注VibeVoice制作内容

媒体真实性挑战&#xff1a;新闻机构如何标注VibeVoice制作内容 在一场模拟的新闻发布会上&#xff0c;主持人与嘉宾就人工智能伦理展开激烈对谈。语调起伏自然&#xff0c;停顿恰到好处&#xff0c;甚至能听到轻微的呼吸声和翻阅笔记的窸窣——但这段音频从未真实发生。它由AI…

作者头像 李华
网站建设 2026/4/12 0:31:02

AdGuard Home高效配置指南:打造无广告纯净网络环境

AdGuard Home高效配置指南&#xff1a;打造无广告纯净网络环境 【免费下载链接】AdGuardHomeRules 高达百万级规则&#xff01;由我原创&整理的 AdGuardHomeRules ADH广告拦截过滤规则&#xff01;打造全网最强最全规则集 项目地址: https://gitcode.com/gh_mirrors/ad/A…

作者头像 李华
网站建设 2026/4/10 21:14:25

QQ音乐解密终极指南:qmcdump免费音频转换工具完整教程

QQ音乐解密终极指南&#xff1a;qmcdump免费音频转换工具完整教程 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 还在为…

作者头像 李华
网站建设 2026/4/15 7:16:35

QQ音乐加密格式破解实战:用qmcdump重获音频自由

QQ音乐加密格式破解实战&#xff1a;用qmcdump重获音频自由 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 当音乐被锁住…

作者头像 李华
网站建设 2026/4/8 20:14:13

宗教讲道传播:牧师用VibeVoice生成多语言布道内容

宗教讲道传播&#xff1a;牧师用VibeVoice生成多语言布道内容 在一场清晨的线上礼拜中&#xff0c;一位美国牧师的声音缓缓响起&#xff0c;讲述《马太福音》的深意。几秒钟后&#xff0c;同一个声音切换为流利的中文&#xff0c;逐句翻译刚刚的内容——不是通过剪辑拼接&#…

作者头像 李华
网站建设 2026/4/12 19:53:26

高速PCB设计中线宽与载流能力匹配:Altium工具应用指南

高速PCB设计中的线宽与载流能力匹配&#xff1a;从理论到Altium实战你有没有遇到过这样的情况&#xff1f;板子打样回来&#xff0c;通电没多久&#xff0c;某根电源走线就开始冒烟——不是芯片坏了&#xff0c;而是那条看似无害的细铜线扛不住电流&#xff0c;热到发红、氧化、…

作者头像 李华