半加器和全加器 verilog FPGA 基础练习1

半加器和全加器 verilog FPGA 基础练习1

发现问题,用技术解决问题。兴趣是自己的源动力 !

前言

对于半加器和全加器的练习,根本目的在于理解自底向上(Bottom-Up)的设计方法和自顶向下(Top- Down)的设计方法,既学会堆积木。


一、半加器理论

半加器电路是指对两个输入数据位相加,输出一个结果位和进位,没有进位输入的加法器电路。既,1‘b1 + 1’b1,结果位1’b0,进位为1‘b1。

1.1 Verilog实现

代码如下:

module half_adder(
input  in_1  , // 输入信号
input  in_2  , // 输入信号
output sum   , // 两个加数的求和结果(1bit位宽相加的数据,结果只有0或者1)
output count   // 两个加数求和后的进位信号
);
// 这里需要注意的是单bit相加,相加后结果的位宽是等号右边决定的;
// 1'b1 + 1'b1 的结果为2,即2'b10,如果等号左边为 1bit,即 assign sum = in_1 + in_2,那么会对高位截位。
// 即:相加后的数值位宽和等式右边无关 
assign {count,sum} = in_1 + in_2; 

endmodule

1.2 仿真tb

`timescale 1ns/1ns
module tb_top();

// 模块的接口参数定义
reg  in_1  ;
reg  in_2  ;
wire sum   ;
wire count ;

initial 
	begin
		in_1 <= 1'b0;
		in_2 <= 1'b0;	
	end

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


half_adder u0_half_adder(
	.in_1  (in_1 ),
	.in_2  (in_2 ),
	.sum   (sum  ),
	.count (count)
);

endmodule

1.3 仿真结果

在这里插入图片描述

二、全加器理论

而全加器是在半加器的基础上的升级版,除了加数和被加数加和外还要加上上一级传进来的进位信号。既,除了单bit数相加,还需要考虑进位信号(低位的进位),可以结合下面代码来理解。

2.1 Verilog实现

代码如下:

module full_adder(
input  in_1  , // 输入信号
input  in_2  , // 输入信号
input  cin   , // 进位信号

output sum   , // 两个加数的求和结果(1bit位宽相加的数据,结果只有0或者1)
output count   // 两个加数求和后的进位信号

);

wire  sum_0    ;
wire  count_0  ;
wire  count_1  ;

// 第一个半加器:两个1bit数相加
half_adder u0_half_adder(
	.in_1  (in_1 ),
	.in_2  (in_2 ),
	.sum   (sum_0  ),
	.count (count_0)
);

// 第二个半加器:和低位的进位相加
half_adder u1_half_adder(
	.in_1  (sum_0 ),
	.in_2  (cin),
	.sum   (sum  ),
	.count (count_1)
);
// 理解1:单bit数,如果count_0 = 1,那么 sum_0为0,此时如果cin为0或1,都不影响进位;
// 理解2:如果 count_0 = 0;那么sum_0为0或者1,此时,如果cin为0或1,则count_1有两种情况,分别为0或者1
// 结合上面两个理解,那么使用或判断,即可判断进位的情况。(最好通过真值表来理解)
assign count = count_0 | count_1; 

endmodule

2.2 仿真tb

这里tb使用3位全加器来实现3bit位宽的数据相加,方便理解半加器和全加器的区别和理解。

`timescale 1ns/1ns
module tb_top();

// 模块的接口参数定义
reg [2:0] in_1;
reg [2:0] in_2;

wire [2:0] sum      ;
wire 	   u0_count ;
wire 	   u1_count ;
wire       u2_count ;

initial 
	begin
		in_1 <= 3'b000;
		in_2 <= 3'b000;	
		#200;
		in_1 <= 3'b101;
		in_2 <= 3'b001;	
	end

// 此处举例3bits数的相加:3'bxxx = 3'b101 + 3'b001,通过全加器来进行计算xxx的值是什么?

//u0_full_adder 全加器:表示3'b101 + 3'b001第0位加数结果和进位,既 1’b1 + 1'b1
full_adder u0_full_adder(
	.in_1  (in_1[0] ),     // 1’b1 
	.in_2  (in_2[0] ),     // 1’b1 
	.cin   (1'b0    ),     // 最低位没有进位
	.sum   (sum[0]  ),  // 3'bxxx 0位的结果
	.count (u0_count)      // 3'bxxx 第0位的进位
);
//u1_full_adder 全加器:表示3'b101 + 3'b001第1位加数结果和进位,既 1’b0 + 1'b0
full_adder u1_full_adder(
	.in_1  (in_1[1]      ), // 1’b0 
	.in_2  (in_2[1]      ), // 1’b0 
	.cin   (u0_count     ), // 来自u0_full_adder的进位 u0_count
	.sum   (sum[1]       ), // 3'bxxx 1位的结果
	.count (u1_count     )  // 3'bxxx 第1位的进位
);
//u2_full_adder 全加器:表示3'b101 + 3'b001第2位加数结果和进位,既 1’b1 + 1'b0
full_adder u2_full_adder(
	.in_1  (in_1[2] ),      // 1’b1 
	.in_2  (in_2[2] ),      // 1’b0 
	.cin   (u1_count  ),    // 来自 u1_full_adder 的进位 u1_count
	.sum   (sum[2]  ),   // 3'bxxx 2位的结果
	.count (u2_count)       // 3'bxxx 第2位的进位
);

// 最后3‘bxxx的值为3’b110

endmodule

半加器和全加器的区别不是很大,输出都是一个sum和一个进位,主要区别在于全加器要考虑低位的进位,相当于要加两次(一次考虑自身位的相加,二是考虑要和低位的进位相加)

2.3 仿真结果

在这里插入图片描述

三、升华

自底向上(Bottom-Up)的设计方法和自顶向下(Top- Down)的设计方法。可以直观的去理解为搭积木原则,既,每一个module都是一个积木块,积木块的特性就是特定功能(一个积木只做一件事),可复用,最后用多个积木组建为一个城堡!
在这里插入图片描述

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值