0+0=0,0+1=1,1+1=0,进位为1。


module half_adder(
input A,
input B,
output F,
output Cout
);
assign F = A ^ B;
assign Cout = A & B;
endmodule

在半加器的基础上,考虑低位运算的进位,因此全加器有三个输入端口。

逻辑表达式 F = A ⊕ B ⊕ C i n F=A\oplus B\oplus Cin F=A⊕B⊕Cin C o u t = A ⋅ B + C i n ( A ⊕ B ) Cout = A\cdot B+Cin(A\oplus B) Cout=A⋅B+Cin(A⊕B)
对应的真值表

Verilog语法
module full_adder(
input A,
input B,
input Cin,
output F,
output Cout
);
assign F = A^B^Cin;
assign Cout = A&B|(Cin&(A^B));
endmodule
RTL视图

另外一种实现全加器,利用两个半加器实现

由于全加器考虑了低位运算的进位,由此我们可以使用级联多个全加器来轻松实现多位数据的加法,如8位数据

采用这种级联方式也叫行波进位加法器,如有进位,就像波纹一样从低位传至高位。这种加法器,由于每一个全加器都需要等待它的前一级全加器的进位输出才能完成计算,因此耗时长、效率低。为了提升加法的时间效率,人们引入了进位选择加法器和超前进位加法器。
HDLBits上面有个有关加法器题目:给出一个16位的加法器add16,设计一个32位加法器。

这个16位加法器,可以通过行波进位的级联方式构成,其内部结构可以先不纠结,就如何构成32位加法器进行理解。
Verilog 实现
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
):
// 定义内部连接线
wire [15:0] a_1, a_2;
wire [15:0] b_1, b_2;
wire [15:0] sum_1, sum_2;
wire cin_1, cin_2, cout_1; // 注意,这里可以看到下面那个进位是没有输出的,所以,可以不定义。
// 将线与端口数据连接起来
assign cin_1 = 0;
assign a_1 = a[15:0];
assign a_2 = a[31:16];
assign b_1 = b[15:0];
assign b_2 = b[31:16];
assign sum = {sum_2,sum_1};
// 调用add16模块
add16 add16_inst_1(.a(a_1),.b(b_1),.cin(cin_1),.cout(cout_1));
add16 add16_inst_2(.a(a_2),.b(b_2),.cin(cin_2));
endmodule
前面谈到了,对于多位总线数据的加法,如果使用行波进位,具有很长的进位链和关键途经,耗时长,效率低。因此去引进基于行波进位衍生的几种加法器。


