加法器
(1)半加器
不考虑有来自低位的进位将两个1位二进制数相加,称为半加。实现半加运算的电路称为半加器。
-
真值表
-
逻辑表达式
{ S = A ⊕ B C O = A B \left\{ \begin{matrix} S\text{=}A\oplus B \\ CO\text{=}AB \\ \end{matrix} \right. {S=A⊕BCO=AB
- verilog代码
module h_adder(
input A,
input B,
output S,
output CO
);
assign S = A^B;
assign CO = A&B;
endmodule
(2)全加器
再将两个多位二进制数相加时,除了最低位外,每一位都应该考虑来自低位的进位,即将两个对应位的加数和来自低位的进位3个数相加。这种运算称为全加,所用的电路称为全加器。
-
真值表
-
逻辑表达式
{ S = A ⊕ B ⊕ C I C O = A B + ( A ⊕ B ) C I \left\{ \begin{matrix} S=A\oplus B\oplus CI \\ CO\text{=}AB\text{+}\left( A\oplus B \right)CI \\ \end{matrix} \right. {S=A⊕B⊕CICO=AB+(A⊕B)CI
- verilog代码
module f_adder(
input A,
input B,
input CI,
output S,
output CO
);
assign S = A^B^CI;
assign CO = (A&B) | ((A^B)&CI);
endmodule
(3)行波进位加法器
N bit加法器可以根据1bit全加器组合而成。每个全加器的输出进位CO作为下一个全加器的输入进位CI,这种加法器称为行波进位加法器(Ripple-carry adder,简称RCA),如一个4 bit加法器的结构如下图所示,其中A,B为4 bit的加数,S为A+B的和,CO为该加法器的输出:
由上图可以看出得到进位CO的结果依赖于C3,C2,C1,C0,对于16-bit,32-bit,64-bit,128-bit等加法器,进位链将显得更加长。所以,行波进位加法器设计简单,只需要级联全加器即可,但它的缺点在于超长的进位链,限制了加法器的性能。
- verilog代码
module # (WIDTH=4) rca(
input [WIDTH-1:0] A,
input [WIDTH-1:0] B,
input CI,
output [WIDTH-1:0] S,
output CO
);
wire [WIDTH:0] C;
assign C[0] = CI;
assign CO = C[WIDTH];
genvar i;
generate
for(i = 0; i<WIDTH ;i=i+1)begin:adder
f_adder u_f_adder(.A(A[i]),
.B(B[i]),
.CI(C[i]),
.S(S[i]),
.CO(C[i+1]));
end
endgenerate
endmodule
(4)超前进位加法器
为了克服行波进位加法器的缺点(运算速度慢,延迟时间长),对多bit全加器的公式可以反复使用代入定理来简化运算结果。
{ S i = A i ⊕ B i ⊕ C i C i + 1 = A i B i + ( A i ⊕ B i ) C i \left\{ \begin{matrix} {{S}_{i}}={{A}_{i}}\oplus {{B}_{i}}\oplus {{C}_{i}} \\ {{C}_{i+1}}\text{=}{{A}_{i}}{{B}_{i}}\text{+}\left( {{A}_{i}}\oplus {{B}_{i}} \right){{C}_{i}} \\ \end{matrix} \right. {Si=Ai⊕Bi⊕CiCi+1=AiBi+(Ai⊕Bi)Ci
- 令
{ P i = ( A i ⊕ B i ) G i = A i B i \left\{ \begin{matrix} {{P}_{i}}=\left( {{A}_{i}}\oplus {{B}_{i}} \right) \\ {{G}_{i}}={{A}_{i}}{{B}_{i}} \\ \end{matrix} \right. {Pi=(Ai⊕Bi)Gi=AiBi
⇒ { S i = P i ⊕ C i C i + 1 = G i + P i C i ; { C 0 = C I C O = C N \Rightarrow \left\{ \begin{matrix} {{S}_{i}}={{P}_{i}}\oplus {{C}_{i}} \\ {{C}_{i+1}}={{G}_{i}}+{{P}_{i}}{{C}_{i}} \\ \end{matrix};\left\{ \begin{matrix} {{C}_{0}}=CI \\ CO={{C}_{N}} \\ \end{matrix} \right. \right. ⇒{Si=Pi⊕CiCi+1=Gi+PiCi;{C0=CICO=CN
- 以4 bit为例,
C
i
+
1
C_{i+1}
Ci+1可以根据
G
i
G_i
Gi、
P
i
P_i
Pi以及
C
i
C_i
Ci得出,而
G
i
G_i
Gi和
P
i
P_i
Pi又可以通过
A
i
A_i
Ai和
B
i
B_i
Bi计算得出:
{ C 0 = C I ; C 1 = G 0 + P 0 C 0 ; C 2 = G 1 + P 1 C 1 = G 1 + P 1 ( G 0 + P 0 C 0 ) ; C 3 = G 2 + P 2 C 2 = G 2 + P 2 ( G 1 + P 1 ( G 0 + P 0 C 0 ) ) ; C 4 = G 3 + P 3 C 3 = G 3 + P 3 ( G 2 + P 2 ( G 1 + P 1 ( G 0 + P 0 C 0 ) ) ) ; \left\{ \begin{array}{l} {C_0} = CI;\\ {C_1} = {G_0} + {P_0}{C_0};\\ {C_2} = {G_1} + {P_1}{C_1} = {G_1} + {P_1}({G_0} + {P_0}{C_0});\\ {C_3} = {G_2} + {P_2}{C_2} = {G_2} + {P_2}({G_1} + {P_1}({G_0} + {P_0}{C_0}));\\ {C_4} = {G_3} + {P_3}{C_3} = {G_3} + {P_3}({G_2} + {P_2}({G_1} + {P_1}({G_0} + {P_0}{C_0}))); \end{array} \right. ⎩ ⎨ ⎧C0=CI;C1=G0+P0C0;C2=G1+P1C1=G1+P1(G0+P0C0);C3=G2+P2C2=G2+P2(G1+P1(G0+P0C0));C4=G3+P3C3=G3+P3(G2+P2(G1+P1(G0+P0C0)));
- verilog代码
module lca (
input [3:0] A,
input [3:0] B,
input CI,
output [3:0] S,
ouput CO
);
wire [3:0] P;
wire [3:0] G;
genvar i;
generate
for(i=0; i<4; i=i+1)begin:pg_gen
pg_gen u_pg_gen(.A(A[i]),
.B(i]),
.P(P[i]),
.G(G[i])
);
end
endgenerate
wire[4:0] C;
wire[4:0] F;
carry_gen u_carry_gen(.CI(CI),
.P(P),
.G(G),
.S(F),
.C(C)
);
assign CO = C[4];
endmodule
module pg_gen(
input A,
input B,
output P,
output G
);
assign P = A^B;
assign G = A&B;
endmodule
module carry_gen(
input CI,
input [3:0] P,
input [3:0] G,
output [3:0] S,
output [4:0] C
);
assign C[0] = CI;
genvar i;
gennerate
for(i=0; i<4; i=i+1)begin:sum
assign C[i+1] = G[i] | (P[i] & C[i]);
assign S[i] = P[i]^C[i];
end
endgenerate
endmodule