加法器分为1位数加法器和多位数加法器,1位数加法器又可以分为半加器和全加器。
半加:两个1位二进制数相加,不考虑来自低位的进位(2个二进制数相加);
全加:两个1位二进制数与来自低位的进位三者相加(3个二进制数相加);
(1)半加器
不考虑低位的进位信号,将两个一位二进制数相加,只求本位和
二进制加法隐含条件:变量只取0和1;逢二进位;
真值表
a | b | co | so |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
实现该电路的verilog代码如下:
第一种写法:
module half_add(a,b,so,co);//半加器
input a,b;//定义两个输入
output so,co;//so为和值的输出,co为进位数据的输出
assign so=a^b;//根据真值表可得so为a,b异或逻辑后的结果
assign co=a&b;//根据真值表可得co为a,b与逻辑后的结果
endmodule
综合出来的电路:
第二种写法:
module half_adder(cout,sum,a,b);
output cout;
output sum;
input a,b;
wire cout,sum ;
assign {cout,sum}=a+b;
//assign cout = a & b;
//assign sum = a ^ b;
endmodule
综合出来的电路:
用modelsim进行仿真,testbench文件为:
`timescale 1ns/10ps
//`include "adder.v"
module adder_testbench;
reg a,b;
wire sum,cout;
integer i,j;
adder adder_te(
.sum ( sum ),
.cout ( cout),
.a ( a ),
.b ( b )
);
initial begin
a=0;b=0;
for(i=1;i<16;i=i+1)
#20 a=i;
end
initial begin
for(j=1;j<16;j=j+1)
#10 b=j;
end
initial begin
$monitor($time,,,"%d + %d ={%b,%d}",a,b,cout,sum);
#160 $finish;
end
endmodule
仿真结果为:
(2)全加器
在多位二进制数相加时,对每一位而言,除了考虑相加的两位数(第i位),还要考虑来自低位(i-1位)的进位。实现带低位进位的两个一位数相加的逻辑电路,称为全加器。
真值表
a | b | in | sum | cout |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
实现该电路的verilog代码如下:
第一种写法:
module full_add (a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg sum,cout;
always @(a or b or cin)begin
sum = a ^ b ^ cin;
cout = a & b |(cin&(a^b));
end
endmodule
综合出来的电路:
第二种写法:
module full_add (a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg sum,cout;
always @(a or b or cin)begin
sum = a ^ b ^ cin;
//cout = a & b |(cin&(a^b));
cout = (a & b)|(b & cin)|(a & cin);
end
endmodule
综合出来的电路:
第三种写法:
module full_add (a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg sum,cout;
reg m1,m2,m3;
always @(a or b or cin)begin
{cout,sum} = a + b + cin;
end
endmodule
综合出来的电路:
第四种写法:
module full_add(a,b,in,sum,cout);
input a,b;//两个数据输入
input in;//进位输入
output sum;//和输出
output cout;//进位输出
wire sum_b;
wire in_a;
wire co1,co2;//定义网络线
half_add U1(.a(a),.b(b),.so(sum_b),.co(co2));
half_add U2(.a(in),.b(sum_b),.so(sum),.co(co1));
assign cout = co1|co2;
endmodule
采用上述半加器构成一个全加器表示为:
用modelsim进行仿真,testbench文件为:
`timescale 1ns/10ps
//`include "full_add.v"
module full_add_testbench;
reg a,b,cin;
wire sum,cout;
integer i,j,k;
full_add full_adder_te(
.sum ( sum ),
.cout ( cout),
.a ( a ),
.b ( b ),
.cin ( cin)
);
initial begin
a=0;
for(i=1;i<16;i=i+1)
#20 a=~a;
end
initial begin
b=0;
for(j=1;j<16;j=j+1)
#10 b=~b;
end
initial begin
cin=0;
for(k=1;k<16;k=k+1)
#5 cin=~cin;
end
initial begin
$monitor($time,,,"%d + %d + %d ={%b,%d}",a,b,cin,cout,sum);
#80 $finish;
end
endmodule
仿真结果为: