目录

​半加器​

​全加器​

​Binary Ripple-Carry Adder​

​多位加法器​

​有符号加法溢出​

​Adder100​

​Bcdadd4​

​最后想说的一些话​



半加器

​Create a half adder. A half adder adds two bits (with no carry-in) and produces a sum and carry-out.​

module top_module( 
input a, b,
output cout, sum );
assign sum = a^b;
assign cout = a&b;

endmodule

全加器

​Create a full adder. A full adder adds three bits (including carry-in) and produces a sum and carry-out. ​

module top_module( 
input a, b, cin,
output cout, sum );
assign sum = a^b^cin;
assign cout = a&b + (a&cin)^(b&cin);

endmodule

​全加器​


Binary Ripple-Carry Adder


​既然您已经知道如何构建一个完整的加法器,那么请制作3个实例来创建一个3位二进制纹波进位加法器。 加法器将两个3位数字和一个进位相加,以产生3位总和并执行。 为了鼓励您实际实例化完全加法器,还请在脉动进位加法器中输出每个完全加法器的进位。 cout [2]是最后一个完整加法器的最终进位,并且是通常看到的进位。​

module top_module( 
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
assign cout[0] = a[0]&b[0] + (a[0]&cin)^(b[0]&cin);
assign sum[0] = a[0]^b[0]^cin;

genvar i;
generate
for(i = 1; i <= 2; i = i + 1) begin: adder_
assign cout[i] = a[i]&b[i] + (a[i]&cout[i-1])^(b[i]&cout[i-1]);
assign sum[i] = a[i]^b[i]^cout[i-1];
end
endgenerate


endmodule

由于原题没有给出全加器的模块名,所以我只能这样例化,在知道模块名的情况下,可以直接替换上述写法。


多位加法器

看下面的这个电路图,实现电路图功能:

HDLBits 系列(11)All about Adder_电路图

既然要实现这个功能,那么这个电路图实现的功能是什么呢?

例化四个半加器?每个半加器得到一个sum?

那你真是想错了,这个电路图简直就是扯个淡,如果仅仅是每个半加器得到一个输出sum,那么最后一个sum[4]是什么鬼?

所以,我们只能认为我们需要实现的功能是两个4bit数据相加,如此便简单了:

module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
assign sum = x + y;

endmodule

如果非要问sum[4]是什么?

我们当然可以说是前一位的进位输出,最终我们还可以如下实现上述电路图功能:

module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
wire [3:0] cout;
assign cout[0] = x[0]&y[0];
assign sum[0] = x[0] ^ y[0];

genvar i;
generate
for(i = 1; i <= 3; i = i + 1)begin: adder_4
assign sum[i] = x[i] ^ y[i] ^ cout[i-1];
assign cout[i] = x[i]&y[i] + (x[i] & cout[i-1])^(y[i] & cout[i-1]);
end
endgenerate

assign sum[4] = cout[3];


endmodule

上面的这个第0位的运算,用了一个半加器,1到3位用于3个全加器,最后sum[4]为第3位全加器的进位输出。


有符号加法溢出

​Assume that you have two 8-bit 2's complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.​

Module Declaration

module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);

如何解决这个问题呢?

输入a和b是二进制补码,如果a和b是正数,则最高位,即符号位是正的,如果二者相加为负,则为溢出:

overflow =  a[7] & b[7] & ~s[7];

如果a和b是负数,则最高位为负,如果二者相加为正,则表示溢出。

overflow =  ~a[7] & ~b[7] & s[7];

这样的话,就可以这样做这个题目了:

module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
); //
assign s = a + b;
assign overflow = ( a[7] & b[7] & ~s[7] ) | (~a[7] & ~b[7] & s[7]);

// assign s = ...
// assign overflow = ...

endmodule

Adder100

​Create a 100-bit binary adder. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out.​

module top_module( 
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );

assign {cout, sum} = a + b + cin;

endmodule

这题没什么好说的。


Bcdadd4

​You are provided with a BCD (binary-coded decimal) one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.​

​module bcd_fadd ​

​( ​

​input [3:0] a, ​

​input [3:0] b, ​

​input cin, ​

​output cout, ​

​output [3:0] sum );​

​Instantiate 4 copies of bcd_fadd to create a 4-digit BCD ripple-carry adder. Your adder should add two 4-digit BCD numbers (packed into 16-bit vectors) and a carry-in to produce a 4-digit sum and carry out.​

bcd_fadd已经给了,所以只需要例化四次4次就好了,采用等波纹进位加法器的方式来解决这个问题。

module top_module( 
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );

wire [3:0] cout_mid;
bcd_fadd inst0(
.a(a[3:0]),
.b(b[3:0]),
.cin(cin),
.sum(sum[3:0]),
.cout(cout_mid[0])
);

genvar i;
generate
for(i = 1; i <= 3; i = i + 1) begin : bcd_fadder
bcd_fadd inst(
.a({a[4*i+3], a[4*i+2], a[4*i+1], a[4*i+0]}),
.b({b[4*i+3], b[4*i+2], b[4*i+1], b[4*i+0]}),
.cin(cout_mid[i-1]),
.sum({sum[4*i+3], sum[4*i+2], sum[4*i+1], sum[4*i+0]}),
.cout(cout_mid[i])
);
end
endgenerate

assign cout = cout_mid[3];


endmodule


HDLBits 系列(11)All about Adder_加法器_02

4bit BCD码加法器,也只不过是4bit二进制加法器。

可如下实现:

module bcd_fadder4(
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum

);
assign {cout, sum} = a + b + cin;

endmodule

最后想说的一些话

在今年的秋招一开始,我就建立了一个微信群,在发布了一条博文,召集全国各地的同行朋友们共同加入,共同讨论秋招求职笔试,面试经验,目前已经有300多人加入,各位才华横溢,让我大开眼界。

到今天11月份,从西北地区最早结束到其他各地陆续结束,但是我们曾开玩笑说,本群继续召集下一届同行,作为先行者的我们也会对你们给予应有的帮助,欢迎加入,到你们晒工资的时候,会不会再次把我们倒挂呢?拭目以待。


对于后来很晚的人,也许你看到这个博客我已经工作了,也许我已经变了,不再是一个热心的博主,因此,可能我没有时间做这些事情了,还请见谅。