HDLBits 系列(11)All about Adder

举报
李锐博恩 发表于 2021/07/15 01:47:22 2021/07/15
【摘要】 目录 半加器 全加器 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...

目录

半加器

全加器

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
  
 

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


多位加法器

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

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

例化四个半加器?每个半加器得到一个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
  
 

 

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
  
 

最后想说的一些话

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

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

由于人数较多,所以加我的时候务必备注:CSDN+地区或学校+职位(意向职位)+昵称。

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

 

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/103219777

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。