一、1位二进制半加器
没有进位carry-in,只有两个加数相加得到和sum和进位cout。
代码
module top_module(
input a, b,
output cout, sum );
assign cout = a&b; //cout为a和b的与
assign sum = a^b; //sum为a和b的亦或
endmodule
二、1位二进制全加器
含有进位carry-in,还有两个数相加,结果为和sum和进位输出carry-out。
真值表
A和B相加,Ci-1表示前一个加法器的进位值,Si是运算结果sum,Ci是进位值。
表达式
根据真值表,可以写出相对应的表达式:
Si=Ai⊕Bi⊕Ci-1
Ci= Ai*Bi+Ci-1(A1⊕Bi)
框图
代码
根据逻辑表达式写1位二进制全加器:
module top_module(
input a,b,cin,
output sum,cout
);
assign sum = a^b^cin;
assign cout = a&b|cin&(a^b);
endmodule
或者也可以根据框图来写:
module add1(
input a,b,cin,
output cout,sum
);
wire S1,T1,T2,T3;
xor x1(S1,a,b);
xor x2(sum,S1,cin);
and a1(T3,a,b);
and a2(T2,b,cin);
and a3(T1,a,cin);
or o1(cout,T1,T2,T3);
endmodule
三、 3位二进制加法器
可以实例化三个1位二进制加法器,然后将上一位加法器的carry-out连到当前的carry-in,将当前的carry-out连接到下一位加法器的carry-in。这里,我用for循环构造了三个1位二进制加法器,最后组成了3位二进制加法器。
module top_module(
input [2:0]a,b,
input cin,
output [2:0]cout,
output [2:0]sum
);
reg [2:0] temp_cout;
integer i;
always @(*) begin
for(i = 0;i<3;i++)begin
if(i == 0)begin
sum[0] = a[0]^b[0]^cin;
temp_cout[0] = a[0]&b[0] | cin&(a[0]^b[0]);
end
else begin
sum[i] = a[i]^b[i]^temp_cout[i-1];
temp_cout[i] = a[i]&b[i] | temp_cout[i-1]&(a[i]^b[i]);
end
end
end
assign cout = temp_cout;
endmodule
四、用行为级描述
如下图,直接用x+y。其中结果sum要比加数多一位,sum的最高位表示进位carry-out。
代码示例1
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
assign sum = x+y;
endmodule
代码示例2
//100位的二进制加法
module top_module(
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
assign {cout,sum} = a+b+cin;//结果的最高位是进位cout,低位是结果sum
endmodule
五、关于溢出
两个补码相加,就会出现溢出的情况。当两个正数相加产生负结果,或两个负数相加产生正结果时,就会发生溢出。可以根据两个加数和结果sum的最高位符号位来判断是否溢出。补码的最高位是符号位,0为正数、1为负数。如果两个加数都为负数(最高位为1),和为正数(最高位是0)的话,则溢出;如果两个数都为正数(最高位为0),和为负数(最高位为1)的话,则溢出。
代码
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);
assign s = a + b;
//判断溢出:两个正数相加出现了负数或者两个负数相加出现正数。
//如果两个加数都为负数(最高位为1),和为正数(最高位是0)的话,则溢出;如果两个数都为正数(最高位为0),和为负数(最高位为1)的话,则溢出。
assign overflow = a[7]&b[7]&~s[7] | ~a[7]&~b[7]&s[7];
endmodule
六、十进制数的加法
10进制数的加法是以10为基数的。这里,我们通过实例化四个4位十进制加法器(bcd_fadd)来构造一个16位的十进制加法器。
代码
module top_module(
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );
reg [3:0]temp_cout;
generate
genvar i;
for(i = 0;i<4;i++)begin:BCD_Adder
if(i==0)begin
bcd_fadd bcd_fadd_u(
.a(a[i+3:0]),
.b(b[i+3:0]),
.cin(cin),
.cout(temp_cout[0]),
.sum(sum[i+3:0])
);
end
else begin
bcd_fadd bcd_fadd_u(
.a(a[i*4+3:i*4]),
.b(b[i*4+3:i*4]),
.cin(temp_cout[i-1]),
.cout(temp_cout[i]),
.sum(sum[i*4+3:i*4])
);
end
end
assign cout = temp_cout[3];
endgenerate
endmodule