前言
2023.4.25
一、半加器
两个数直接相加,无进位,真值表如下
module add_half(
input A ,
input B ,
output wire S ,
output wire C
);
assign S = A ^ B;
assign C = A & B;
endmodule
二、全加器
两个数和进位一起相加,根据真值表画出卡诺图,对表达式进行化简
S = A ^ B ^ Cin;
CO = A & B | A & Cin | B & Cin;
{CO, S} = A + B + Cin; //也可以直接写成这种形式
用两个半加器来组成一个全加器
module add_full(
input A ,
input B ,
input Ci ,
output wire S ,
output wire Co
);
wire c_1;
wire c_2;
wire sum_1;
add_half add_half_1(
.A (A),
.B (B),
.S (sum_1),
.C (c_1)
);
add_half add_half_2(
.A (sum_1),
.B (Ci),
.S (S),
.C (c_2)
);
assign Co = c_1 | c_2;
endmodule
三、串行/行波进位加法器(Ripple-Carry Adder/RCA)
原理:N bit的加法器由N个1 bit的全加器组成
。从低位开始,逐位相加, 每一bit需要等待前面计算出来得到进位,才能进行下一bit的计算
优点:电路结构比较简单
缺点:速度比较慢,组合逻辑延时较长
内部的门延迟如下图所示:
module add_4(
input [3:0] A ,
input [3:0] B ,
input Ci ,
output wire [3:0] S ,
output wire Co
);
wire [3:0] C;
genvar i; //用generate来例化多个模块
generate
for(i=0;i<4;i=i+1)begin:adder
add_full add(
.A(A[i]),
.B(B[i]),
.Ci(i==0?Ci:C[i-1]),
.S(S[i]),
.Co(C[i])
);
end
endgenerate
assign Co = C[3];
endmodule
四、超前进位加法器(Lookahead Carry Adder/LCA)
原理:逻辑电路事先得出每一位全加器的进位输入信号(并行计算各个加法器的进位),而无需再从最低位开始向高位逐位传递进位信号,一种用面积换性能的方法。
优点:缩短路径的延时
缺点:电路比较复杂,面积大
只需要三级门电路就可以计算出进位CO
而整个电路的计算结果需要四级延时
module lca_4(
input [3:0] A_in ,
input [3:0] B_in ,
input C_1 ,
output wire CO ,
output wire [3:0] S
);
wire [3:0] P,G,C;
genvar i;
generate for(i=0;i<4;i=i+1)
begin:adder //这个地方的名称不可少
assign P[i] = A_in[i] ^ B_in[i];
assign G[i] = A_in[i] & B_in[i];
assign C[i] = (i==0)?(G[i] | P[i] & C_1) : (G[i] | P[i] & C[i-1]);
assign S[i] = (i==0)?(P[i] ^ C_1) : (P[i] ^ C[i-1]);
end
endgenerate
assign CO = C[3];
endmodule
五、进位保存加法器(Carry Save Adder/CSA)
原理:把对应bit的数相加,分别得到进位和和的结果,再把进位和和进行相加。
优点:把三个数相加变成了两个数相加,门延迟最小
文章来源:https://www.toymoban.com/news/detail-429657.html
文章来源地址https://www.toymoban.com/news/detail-429657.html
到了这里,关于verilog手撕代码2——各种加法器介绍——真值表、表达式、电路图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!