06 FPGA组合逻辑—加法器(半加和全加)

1. 理论

        数字电路中加法器是经常用到的一种基本器件,主要用于两个数或者多个数的加和,加法器又分为半加器(half adder)和全加器(full adder)。

       半加器是指对两个输入数据位相加,输出一个求和结果位和进位,没有进位输入的加法器电路。实现两个一位二进制数的加法运算电路,是加法器的基本单元。

       全加器是在半加器的基础上的升级版,输入除了加数和被加数外还要加上上一级传进来的进位信号

2. 半加器

实验目标:实现一个半加器,按键 KEY1、 KEY2 作为输入,LED 灯D6 表示相加和的输出, LED 灯 D7 表示进位输出。

2.1 系统框图

2.2 真值表与波形图

2.3 硬件资源说明 

     KEY1、KEY2分别对应in1、in2,LED 灯D6、LED 灯 D7分别作为输出和与进位。

2.4 RTL代码:

`timescale  1ns/1ns

module  half_adder01
(
    input   wire    in1 ,   //加数1
    input   wire    in2 ,   //加数2
    
    output  reg    sum ,   //加和
    output  reg    cout    //进位
);
//第一种:拼接符                 
//assign  {cout, sum} = in1 + in2;
//第二种
/*always@(*)	
    case ({in1,in2})
	    2'b00:    {cout, sum} =  2'b00;
	    2'b11:    {cout, sum} =  2'b10;
	    2'b01:    {cout, sum} =  2'b01;
		2'b10:    {cout, sum} =  2'b01;
		default:  {cout, sum} =  2'b00;
    endcase*/
//第三种:逻辑运算
//异或运算
always@(*)
    if(in1 == in2)
        sum = 0;
	else
	    sum = 1;
//与运算
always@(*)
    if((in1 == 1) && (sum == 0))
	    cout = 1;
    else 
	    cout = 0;
endmodule   

2.5 仿真验证

仿真代码:

`timescale  1ns/1ns

module  tb_half_adder();

//wire  define
wire            sum;
wire            cout;

reg             in1;
reg             in2;
          //初始化输入信号
initial
    begin
        in1 <=  1'b0;
        in2 <=  1'b0;
    end

always #10 in1 <= {$random} % 2;    
always #10 in2 <= {$random} % 2;

initial
 begin
    $timeformat(-9, 0, "ns", 6);
    $monitor("@time %t: in1=%b in2=%b sum=%b cout=%b", $time, in1, in2, sum, cout);
end


half_adder  half_adder_inst
(
    .in1    (in1  ),  
    .in2    (in2  ),  
    .sum    (sum  ),  
    .cout   (cout )   
);
endmodule

 仿真结果:

上板验证

     两按键均未按下, in1 和 in2 输出均为高电平,得到和 sum 为 0,进位 count 为 1, D6 被点亮。
 

3. 全加器实验

实验目标:实现全加器,按键 KEY1、 KEY2 作为输入,LED 灯D6 表示相加和的输出, LED 灯 D7 表示进位输出。

硬件资源说明同半加器。

3.1 系统框图 

      全加器的单位是半加器故采用层次化设计,直接例化半加器的模块。

3.2 真值表与波形图

3.5 程序设计

RTL代码:

      这里展示的是顶层代码,工程中直接调用半加器模块即可。

`timescale  1ns/1ns

module  full_adder           //输入信号的声明
(
    input   wire    in1 ,   //加数1
    input   wire    in2 ,   //加数2
    input   wire    cin ,  

    output  wire    sum ,   //两个数的加和
    output  wire    cout    //加和后的进位
);                      
wire    h0_sum;             //中间连线
wire    h0_cout;            //中间连线
wire    h1_cout;            //中间连线

half_adder  half_adder_inst0
(                                          //前面是实例化(调用)的模块的名字相当于是告诉顶层我要使用来自half_adder这个模块的功能
    .in1    (in1    ),                     //input     in1       前面in1是相当于half_adder模块中的信号,(in1)顶层中的信号,然后最前面加上“.”,可以形象的理解为把这两个信号线连接到一起(rtl中的实例化过程和Testbench中的实例化过程是一样的,可以对比理解学习)
    .in2    (in2    ),                     //input     in2
                                          
    .sum    (h0_sum ),                     //ouptut    sum
    .cout   (h0_cout)                      //output    cout
);

half_adder  half_adder_inst1
(                                           //同一个模块可以被实例化多次(所以相同功能只设计一个通用模块即可),但是在顶层的名字一定要区别开,这样子才能表达出是实例化的两个相同功能的模块
    .in1    (h0_sum ),                      //input     in1
    .in2    (cin    ),                      //input     in2
                                           
    .sum    (sum    ),                      //ouptut    sum
    .cout   (h1_cout)                       //output    cout
);

                                            //cout:总的进位信号
assign  cout = h0_cout | h1_cout;      

endmodule

仿真代码:

`timescale  1ns/1ns

module  tb_full_adder();

wire            sum;
wire            cout;
                              
reg             in1;
reg             in2;
reg             cin;

                                
initial 
     begin
    in1 <= 1'b0;
    in2 <= 1'b0;
    cin <= 1'b0;
      end

//in1:产生输入随机数,模拟加数1的输入情况
always #10 in1 <= {$random} % 2;    //取模求余数,产生随机数1'b0、1'b1,每隔10ns产生一次随机数

always #10 in2 <= {$random} % 2;

always #10 cin <= {$random} % 2;


full_adder  full_adder_inst
(
    .in1    (in1    ),  //input         in1
    .in2    (in2    ),  //input         in2
    .cin    (cin    ),  //input         cin

    .sum    (sum    ),  //output        sum
    .cout   (cout   )   //output        cout
);
endmodule

 总结:

   重点是了解层次化设计,越复杂的工程使用经常使用这个方法,需好好掌握。

说明:

       本人使用的是野火家Xilinx Spartan6系列开发板及配套教程主要用于自我学习,以上内容如有疑惑或错误欢迎评论区指出,或者移步B站观看野火家视频教程。

开发软件:ise14.7     仿真:modelsim 10.5 

如需上述资料私信或留下邮箱。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,可以用于实现各种不同的逻辑电路。有符号加法器是其中一种用于实现加法运算的电路。 在计算机中,有符号加法器被用来对带符号数进行加法操作。有符号数在二进制表示中的最高位被用作符号位,0表示正数,1表示负数。有符号加法器可以实现对带符号数进行相加,并考虑了进位和溢出的情况。 FPGA中的有符号加法器可以通过组合逻辑电路的方式来实现。首先,需要将输入的带符号数进行位扩展,即将符号位复制到更高位,以便在加法运算中保持符号一致。接下来,使用全加器或组合电路来实现位级的加法运算。最后,检查最高位的进位和溢出情况,通过输出信号来表示运算结果。 有符号加法器的实现需要考虑到多个方面,如进位的传递、符号位的处理和溢出的检测等。因此,设计一个有效和高性能的有符号加法器是一项具有挑战性的任务。FPGA作为可编程器件,可以根据需求灵活地配置有符号加法器的结构和功能,以满足不同应用的要求。 有符号加法器在很多领域中都有广泛的应用,如数字信号处理、图像处理、通信系统等。通过在FPGA中实现有符号加法器,可以提供高度定制化的加法运算能力,满足不同应用对于处理速度、精度和功耗等方面的要求。同时,FPGA的可编程性还使得有符号加法器的功能可以根据需求进行灵活调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖啡0糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值