HDLBits 练习题:实现32位加法器
原题
You are given a module add16
that performs a 16-bit addition. Instantiate two of them to create a 32-bit adder. One add16 module computes the lower 16 bits of the addition result, while the second add16 module computes the upper 16 bits of the result, after receiving the carry-out from the first adder. Your 32-bit adder does not need to handle carry-in (assume 0) or carry-out (ignored), but the internal modules need to in order to function correctly. (In other words, the add16
module performs 16-bit a + b + cin, while your module performs 32-bit a + b).
Connect the modules together as shown in the diagram below. The provided module add16
has the following declaration:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
问题描述
在本练习中,你需要创建一个32位加法器,该加法器由两个16位加法器(add16
模块)组成。每个add16
模块负责计算16位加法的结果。具体要求如下:
- 一个
add16
模块计算加法结果的低16位。 - 另一个
add16
模块计算加法结果的高16位,该模块需接收第一个加法器的进位输出。 - 32位加法器不需要处理进位输入(假设为0)或进位输出(忽略)。
提供的add16
模块接口如下:
module add16 (
input [15:0] a,
input [15:0] b,
input cin,
output [15:0] sum,
output cout
);
实现步骤
- 输入定义:
- 定义两个32位的输入
a
和b
。
- 定义两个32位的输入
- 将32位输入分割:
- 取低16位:
a[15:0]
和b[15:0]
- 取高16位:
a[31:16]
和b[31:16]
- 取低16位:
- 实例化第一个add16:
- 计算低16位加法,输入
cin
为0,输出为sum_low
和cout_low
。
- 计算低16位加法,输入
- 实例化第二个add16:
- 计算高16位加法,输入为
a[31:16]
和b[31:16]
,以及第一个加法器的进位输出cout_low
。
- 计算高16位加法,输入为
- 输出定义:
- 定义一个32位的输出
sum
,将低16位和高16位的计算结果组合在一起。
- 定义一个32位的输出
示例代码
以下是32位加法器的示例代码:
module add32 (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum_low;
wire cout_low;
wire [15:0] sum_high;
// 计算低16位
add16 add_low (
.a(a[15:0]),
.b(b[15:0]),
.cin(1'b0),
.sum(sum_low),
.cout(cout_low)
);
// 计算高16位
add16 add_high (
.a(a[31:16]),
.b(b[31:16]),
.cin(cout_low),
.sum(sum_high),
.cout() // 忽略高16位的进位输出
);
// 合并结果
assign sum = {sum_high, sum_low};
endmodule
解释
-
add32
模块通过实例化两个add16
模块实现32位加法。 -
第一个
add16
负责计算低16位的和,第二个add16
计算高16位的和并考虑来自低16位的进位。 -
最终结果通过将高16位和低16位连接在一起形成32位的加法结果。
那么,
add16
模块的内部是怎么样的呢?add16
模块作为基础的 16 位加法器,负责将两个 16 位的输入进行加法运算,并处理可能出现的进位。其设计逻辑简单而高效,是构建更复杂加法器的基础,所以接下来我们看add16
模块的具体实现。
add16
模块的实现
add16
模块是一个 16 位加法器,接受两个 16 位输入和一个进位输入,并输出 16 位的和和一个进位输出。
add16
模块的 Verilog 代码
module add16 (
input [15:0] a,
input [15:0] b,
input cin,
output [15:0] sum,
output cout
);
wire [16:0] temp; // 使用一个 17 位的临时变量来存储结果,以处理进位
assign temp = a + b + cin; // 计算总和
assign sum = temp[15:0]; // 取低 16 位作为和
assign cout = temp[16]; // 取第 17 位作为进位输出
endmodule
代码说明
- 输入和输出:
add16
模块接受两个 16 位输入a
和b
,以及一个进位输入cin
,并输出 16 位和sum
和进位输出cout
。 - 临时变量:使用一个 17 位的变量
temp
来存储计算结果,以便处理进位。 - 加法操作:通过
assign temp = a + b + cin;
进行加法计算,然后分别提取和和进位。