verilog学习:加法器

前言

之前的文章《verilog学习:使用VCS仿真验证一个全加器》,示范了下全加器,这篇文章就展开说一下加法器。

加法器(Adder)

  • 加法器分为1位数加法器和多位数加法器,1位数加法器又可以分为半加器和全加器。
    在这里插入图片描述
  • 半加:两个1位二进制数相加,不考虑来自低位的进位(2个二进制数相加);
  • 全加:两个1位二进制数与来自低位的进位三者相加(3个二进制数相加);
    在这里插入图片描述
  • 半加器+半加法和全加法是算术运算电路中的基本单元,它们是完成1位二进制相加的一种组合逻辑电路。

1.半加器(Half Adder)

不考虑低位的进位信号,将两个一位二进制数相加,只求本位和

  • 二进制加法隐含条件:变量只取0和1;逢二进位;
    在这里插入图片描述
  • 真值表如下:
被加数A加数B和数S进位CO
0000
0110
1010
1101

由表中可以看见,这种加法没有考虑低位来的进位,所以称为半加。

  • 跟据真值表,写出方程;根据表达式画出逻辑图:
    在这里插入图片描述
    在这里插入图片描述

1.1 半加器verilog设计代码

  • 第一种写法:
module half_adder(
      input a,             //第一个加数a
      input b,             //第二个加数b
      output sum,          //和
      output cout          //位
);     
		
    assign sum=a ^ b;     //sum=a⊕b
    assign cout=a & b;	  //cout=ab

endmodule
  • 第二种写法:
module half_adder(cout,sum,a,b);    
	output   cout;               
	output   sum;               
	input    a,b;               
	wire     cout,sum  ;          
	
	//assign   {cout,sum}=a+b;   
	assign cout = a & b;
	assign sum = a ^ b;    
	
endmodule   
  • 这两种写法综合出来的电路图是一样的,如下:
    在这里插入图片描述
  • 第三种写法:
module half_adder(cout,sum,a,b);    
	output   cout;               
	output   sum;               
	input    a,b;               
	wire     cout,sum  ;          
	
	assign   {cout,sum}=a+b;   
	//assign cout = a & b;
	//assign sum = a ^ b;    
	
endmodule   
  • 第三种写法综合出来的电路图如下:
    在这里插入图片描述

1.2 测试文件testbench

`timescale 1ns/10ps            
//`include "adder.v"         
module adder_testbench;        
	reg    a,b;                   
	wire   sum,cout;           
	integer i,j;   
	                 
	adder  adder_te(
	.sum  ( sum ),
	.cout  ( cout),
	.a     ( a  ),
	.b     ( b  )
	);   
	
	initial begin
	a=0;b=0;
	for(i=1;i<16;i=i+1)
	#20   a=i;
	end
	
	initial begin
	for(j=1;j<16;j=j+1)
	#10   b=j;
	end
	
	initial begin
	$monitor($time,,,"%d + %d ={%b,%d}",a,b,cout,sum);
	#160  $finish;
	end
	
endmodule
  • 三种方式产生的波形文件都一样(注意,这里是1bit数相加,高位会溢出的)!
    在这里插入图片描述

2.全加器(Full Adder)

  • 半加法器中,不考虑输入进位,在全加法器设计中将第i-1位的输出进位当
    作第i位的输入。
  • 在将两个多位二进制数相加时,除了最低位以外,每一位都应该考虑来自低位的进位,即将两个对应位的加数和来自低位的进位3个数相加。这种运算称为全加,所用的电路称为全加器。
  • 两个1位二进制数相加,考虑低位进位

一位全加器的真值表如下图,其中Ai为被加数,Bi为加数,相邻低位来的进位数为Ci-1,输出本位和为Si。向相邻高位进位数为Ci

进位输入Ci-1被加数Ai加数Bi本位和Si进位输出Ci
00000
00110
01010
01101
10010
10101
11001
11111

在这里插入图片描述
一位全加器的逻辑表达式如下:

Si=Ai⊕Bi⊕Ci-1
在这里插入图片描述
电路图如下:
在这里插入图片描述

2.1 全加器verilog设计代码

  • 第一种写法:
module full_add (a,b,cin,sum,cout);  
	input a,b,cin;       
	output sum,cout;               
	reg sum,cout;             
	
	always @(a or b or cin)begin
		sum = a ^ b ^ cin;
		cout = a & b |(cin&(a^b));
	end
	
endmodule

综合出来的电路:
在这里插入图片描述

  • 第二种写法:
module full_add (a,b,cin,sum,cout);  
	input a,b,cin;       
	output sum,cout;               
	reg sum,cout;                
	
	always @(a or b or cin)begin
		sum = a ^ b ^ cin;
		//cout = a & b |(cin&(a^b));
		cout = (a & b)|(b & cin)|(a & cin);
	end	
	
endmodule

综合出来的电路:
在这里插入图片描述

  • 第三种写法:
module full_add (a,b,cin,sum,cout);  
	input a,b,cin;       
	output sum,cout;               
	reg sum,cout;
	reg m1,m2,m3;                 
	
	always @(a or b or cin)begin
		{cout,sum} = a + b + cin;
	end
	
endmodule

综合出来的电路:
在这里插入图片描述

2.2 测试文件testbench

`timescale 1ns/10ps            
//`include "full_add.v"         
module full_add_testbench;        
	reg    a,b,cin;                   
	wire   sum,cout;           
	integer i,j,k;  

	full_add  full_adder_te(
	.sum  ( sum ),
	.cout  ( cout),
	.a     ( a  ),
	.b     ( b  ),
	.cin   ( cin)
	); 
    
	initial begin
		a=0;
		for(i=1;i<16;i=i+1)
		#20   a=~a;
	end
	
	initial begin
		b=0;
		for(j=1;j<16;j=j+1)
		#10   b=~b;
	end
	
	initial begin
		cin=0;
		for(k=1;k<16;k=k+1)
		#5   cin=~cin;
	end
		
	initial begin
	  $monitor($time,,,"%d + %d + %d ={%b,%d}",a,b,cin,cout,sum);
	  #80  $finish;
	end
	
endmodule
  • 这三种方法的仿真波形都一样,可对比:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.其实还有很多种加法器,可深入了解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后记

  • 28
    点赞
  • 177
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
以下是三种常见的Verilog进位加法器的选择方法: 1.前进进位加法器(Carry Lookahead Adder,CLA):前进进位加法器是一种高速的加法器,它通过预先计算进位来减少了进位延迟。在Verilog中,可以使用generate语句来实现前进进位加法器。例如,下面是一个4位CLA的Verilog代码: ```verilog module cla_adder( input [3:0] a, input [3:0] b, output [3:0] sum, output carry ); genvar i; generate for (i = 0; i < 4; i = i + 1) begin : cla assign sum[i] = a[i] ^ b[i] ^ carry; assign carry = (a[i] & b[i]) | (a[i] & carry) | (b[i] & carry); end endgenerate endmodule ``` 2.超前进位加法器(Carry Select Adder,CSA):超前进位加法器是一种折衷方案,它通过将加法器分成多个块来平衡速度和规模。在Verilog中,可以使用generate语句来实现超前进位加法器。例如,下面是一个4位CSA的Verilog代码: ```verilog module csa_adder( input [3:0] a, input [3:0] b, output [3:0] sum, output carry ); wire [1:0] c; wire [1:0] p; wire [1:0] g; assign p[0] = a[0] ^ b[0]; assign g[0] = a[0] & b[0]; assign p[1] = a[1] ^ b[1] ^ g[0]; assign g[1] = (a[1] & b[1]) | (g[0] & (a[1] ^ b[1])); assign c[0] = g[0] | (p[0] & c[0]); assign c[1] = g[1] | (p[1] & c[0]); assign carry = c[1]; assign sum[0] = a[0] ^ b[0] ^ c[0]; assign sum[1] = a[1] ^ b[1] ^ c[0]; assign sum[2] = a[2] ^ b[2] ^ c[1]; assign sum[3] = a[3] ^ b[3] ^ c[1]; endmodule ``` 3.等波纹进位加法器(Ripple Carry Adder,RCA):等波纹进位加法器是一种简单的加法器,它的进位延迟随着加法器位数的增加而增加。在Verilog中,可以使用简单的assign语句来实现等波纹进位加法器。例如,下面是一个4位RCA的Verilog代码: ```verilog module rca_adder( input [3:0] a, input [3:0] b, output [3:0] sum, output carry ); wire [3:0] c; assign sum = a + b; assign c = {1'b0, sum[3:1]}; assign carry = c[3]; endmodule ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杰之行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值