在上篇文章,介绍了串行进位加法器: 数字电子技术基础(七):加法器
这种加法器在运算过程中,所花费的时间比较长。假设4位串行进位加法器,一共需要4个1位全加器。

如上图,s1的进位输入是s0的进位输出,相当于是等到第一个加法器运算完成,第二个加法器才开始工作,等到第二个加法器运算完成,第三个加法器才开始运算,一直等到第四个加法器运算完成。
假设每个加法器运算需要的时间为a,则s0的输出需要a;s1的输出需要2a;s2的输出需要3a;s3的输出需要4a;co的输出需要4a。
当等待4a的时间后,4位串行进位加法器才能输出正确的数据。
当位数更多的时候,需要花费的时间会更多,于是超前进位加法器出现了。
一、原理
上图为一位全加器的真值表。
我们假设这是n位加法器中的第 i 位相加。从表中我们可以得到 (CO)i 的逻辑表达式:
其中,我们令进位函数Gi = AiBi, 令进位传送函数 Pi = Ai + Bi;
其中 (CI)i 为第i-1位的加法进位输出 (CI)i = (CO)i-1
我们通过看这个可以展开出以下公式
再从真值表推导出第i位 Si 的逻辑表达式
二、Verilog实现及仿真
1、1位超前进位加法器
/****** 一位超前进位加法器 ********/
module pre_1_adder(
input ain,
input bin,
input cin,
output SO,
output Gi,
output Pi
);
assign Gi = ain & bin;
assign Pi = ain | bin;
assign SO = ain ^ bin ^ cin;
endmodule
2、4位超前加法器
4位超前加法器可以用4个1位超前加法器并联而成
/******* 四位超前加法器 *******/
module pre_4_adder(
input [3:0] ain,
input [3:0] bin,
input cin,
output [3:0] SO,
output Pm,
output Gm,
output CO
);
wire [4:1] CI;
wire [3:0] Pi;
wire [3:0] Gi;
pre_1_adder u0(
.ain (ain[0]),
.bin (bin[0]),
.cin (cin),
.SO (SO[0]),
.Gi (Gi[0]),
.Pi (Pi[0])
);
pre_1_adder u1(
.ain (ain[1]),
.bin (bin[1]),
.cin (CI[1]),
.SO (SO[1]),
.Gi (Gi[1]),
.Pi (Pi[1])
);
pre_1_adder u2(
.ain (ain[2]),
.bin (bin[2]),
.cin (CI[2]),
.SO (SO[2]),
.Gi (Gi[2]),
.Pi (Pi[2])
);
pre_1_adder u3(
.ain (ain[3]),
.bin (bin[3]),
.cin (CI[3]),
.SO (SO[3]),
.Gi (Gi[3]),
.Pi (Pi[3])
);
CLA_4 uut
(
.P (Pi),
.G (Gi),
.cin (cin),
.Ci (CI),
.Gm (Gm),
.Pm (Pm)
);
assign CO = CI[4];
endmodule
其中的CLA_4为4位超前进位部件CLA 专门用来计算进位的
/************ 4位超前进位部件CLA 专门用来计算进位的**********/
module CLA_4(
input [3:0] P,
input [3:0] G,
input cin,
output [4:1] Ci,
output Gm,
output Pm
);
assign Ci[1]=G[0]|P[0]&cin;
assign Ci[2]=G[1]|P[1]&G[0]|P[1]&P[0]&cin;
assign Ci[3]=G[2]|P[2]&G[1]|P[2]&P[1]&G[0]|P[2]&P[1]&P[0]&cin;
assign Ci[4]=G[3]|P[3]&G[2]|P[3]&P[2]&G[1]|P[3]&P[2]&P[1]&G[0]|P[3]&P[2]&P[1]&P[0]&cin;
assign Gm=G[3]|P[3]&G[2]|P[3]&P[2]&G[1]|P[3]&P[2]&P[1]&G[0]; // 可以从ci4,也就是最终进位输出CO得到,从ci4可以看出,
// 整个进位输出由两个部分构成,G和P的函数,以及有cin的函数
// 我们之前令与cin无关的项为Gi,与cin有关的为Pi。可以得到
// 可以得到每四位的进位函数和进位传送函数
assign Pm=P[3]&P[2]&P[1]&P[0];
endmodule
从代码中可以看到,我们输出了Pm和Gm,这两个是什么意思呢?
我们再看看一位超前进位输出的Pi和Gi
其中,我们令进位函数Gi = AiBi, 令进位传送函数 Pi = Ai + Bi;
这是一位超前进位加法的两个函数,那么我们写出四位的最终进位函数可以从ci4,也就是最终进位输出CO得到,从ci4可以看出,整个进位输出由两个部分构成,G和P的函数,以及有cin的函数,我们之前令与cin无关的项为Gi,与cin有关的为Pi。可以得到每四位的进位函数和进位传送函数
标号1就是Gm,标号2就是Pm
Gm=G[3]|P[3]&G[2]|P[3]&P[2]&G[1]|P[3]&P[2]&P[1]&G[0];
Pm=P[3]&P[2]&P[1]&P[0];
RTL视图
可以从图中看出,从输入到输出,4位超前加法器大概会延迟6个门电路的时间
3、16位超前进位加法器
16位超前进位加法器可以由四个4位超前进位加法器加上一个4位超前进位部件CLA构成
/******* 16位超前加法器 *******/
module pre_16_adder(
input [15:0] ain,
input [15:0] bin,
input cin,
output [15:0] SO,
output Gm,
output Pm,
output CO
);
wire [3:0] Gi;
wire [3:0] Pi;
wire [4:1] CI;
pre_4_adder U0
(
.ain (ain[3:0]),
.bin (bin[3:0]),
.cin (cin),
.SO (SO[3:0]),
.Gm (Gi[0]),
.Pm (Pi[0])
);
pre_4_adder U1
(
.ain (ain[7:4]),
.bin (bin[7:4]),
.cin (CI[1]),
.SO (SO[7:4]),
.Gm (Gi[1]),
.Pm (Pi[1])
);
pre_4_adder U2
(
.ain (ain[11:8]),
.bin (bin[11:8]),
.cin (CI[2]),
.SO (SO[11:8]),
.Gm (Gi[2]),
.Pm (Pi[2])
);
pre_4_adder U3
(
.ain (ain[15:12]),
.bin (bin[15:12]),
.cin (CI[3]),
.SO (SO[15:12]),
.Gm (Gi[3]),
.Pm (Pi[3])
);
CLA_4 CLA_4
(
.P (Pi),
.G (Gi),
.cin (cin),
.Ci (CI),
.Gm (Gm),
.Pm (Pm)
);
assign CO=CI[4];
endmodule
仿真文件
`timescale 1ns/1ps
`define clk_period 20
module pre_16_adder_tb();
reg [15:0] ain;
reg [15:0] bin;
reg cin;
wire [15:0] SO;
wire Gi;
wire Pi;
wire CO;
initial begin
ain = 16'b0001_1111_1010_0101;
bin = 16'b1010_1010_1110_0110;
cin = 0;
#50 $stop;
end
pre_16_adder pre_16_adder(
.ain (ain),
.bin (bin),
.cin (cin),
.Gm (Gi),
.Pm (Pi),
.SO (SO),
.CO (CO)
);
endmodule
RTL视图
可以从图中看出,从输入到输出,16位超前加法器大概会延迟11个门电路的时间
参考:
https://blog.csdn.net/JohnHe1994/article/details/79709711
https://blog.csdn.net/qq_26707507/article/details/106146619