加法器简介及Verilog实现

[TOC]

写在前面的话

加法器是数字系统最基础的计算单元,用来产生两个数的和,加法器是以二进制作运算。负数可用二的补数来表示,减法器也是加法器,乘法器可以由加法器和移位器实现。加法器和乘法器由于会频繁使用,因此加法器的速度也影响着整个系统的计算速度。对加法器的设计也一直在更新迭代,反观数字IC初学者,往往只是了解个全加器和半加器,而对一些经典的加法器类型和实现方式却很少了解。

经典加法器

8bit并行加法器

并行加法器就是利用多个全加器实现两个操作数各位同时相加。并行加法器中全加器的个数与操作数的位数相同,常用的并行加法器有行波进位加法器、超前进位加法器、进位选择加法器等。容易实现、运算速度快,但是耗用资源多,当位宽较宽时,耗用的资源会非常大。

Verilog代码:

// Verdion: v1.0
// Description: 8位并行加法器
// -----------------------------------------------------------------------------
module parallel_adder (
	input [7:0]			din_a 	,    	// data in a
	input [7:0]			din_b 	, 		// data in b
	input 				cin 	,		// carry in
	output wire [7:0]	sum 	, 		// summation of a ,b
	output wire  		cout 			// carry out 
);


assign {cout,sum}	=	din_a + din_b +	cin ;

endmodule 

Quartus RTL图
用到了两个加法器。


Quartus Post mapping图


Vivado synthesis图


这里可以看出,相同的设计,在不同综合工具中综合出的电路结构是不同的,感兴趣的同学可以学习综合相关的知识点。后续也会把DC综合的教程笔记分享出来,这个可以在笔面前再了解,大部分同学都很难接触到流片相关的软件,在学校稍微熟悉就好。

8bit超前进位加法器

超前进位加法器是由全加器发展而来,目的是提高运算速度。当加法器级数提高时,高位的进位信号需要从低级逐级传递,为了缩短这个时间,我们可以从低级的输入信号确定一个组合逻辑电路,唯一确定一个高位的进位信号,从而提高运行速度。超前进位加法器也称为快速进位加法器,目的就是缩短进位信号生成的时间。

Verilog代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT904  1320343336@qq.com
// File   : Carry_Look_ahead_adder.v
// Create : 2022-11-19 16:15:31
// Revise : 2022-11-19 16:15:31
// Editor : 0078
// Verdion: v1.0
// Description: 8bit 超前进位加法器
// -----------------------------------------------------------------------------
module Carry_Look_ahead_adder (
	input [7:0] 		din_a 	,    	// data in a
	input [7:0] 		din_b 	, 		// data in b
	input 				cin 	, 	 	// carry in 
	output  wire 		cout 	, 		// carry out 
	output 	wire [7:0]	sum 			// summation of a ,b
);

wire [7:0]	G  	;
wire [7:0]	P 	;
wire [7:0] 	C 	;


assign G[0] 	= din_a[0] & din_b[0]	;		//bit 0
assign P[0]		= din_a[0] | din_b[0]	;
assign C[0]		= cin 					;
assign sum[0]	= G[0] ^ P[0] ^ C[0]	;


assign G[1] 	= din_a[1] & din_b[1]	;		//bit 1
assign P[1]		= din_a[1] | din_b[1]	;
assign C[1]		= G[0] | (P[0] & cin) 	;
assign sum[1]	= G[1] ^ P[1] ^ C[1]	;


assign G[2] 	= din_a[2] & din_b[2]	;		//bit 2
assign P[2]		= din_a[2] | din_b[2]	;
assign C[2]		= G[1] | (P[1] & C[1]) 	;
assign sum[2]	= G[2] ^ P[2] ^ C[2]	;


assign G[3] 	= din_a[3] & din_b[3]	;		//bit 3
assign P[3]		= din_a[3] | din_b[3]	;
assign C[3]		= G[2] | (P[2] & C[2]) 	;
assign sum[3]	= G[3] ^ P[3] ^ C[3]	;

assign G[4] 	= din_a[4] & din_b[4]	;		//bit 4
assign P[4]		= din_a[4] | din_b[4]	;
assign C[4]		= G[3] | (P[3] & C[3]) 	;
assign sum[4]	= G[4] ^ P[4] ^ C[4]	;


assign G[5] 	= din_a[5] & din_b[5]	;		//bit 5
assign P[5]		= din_a[5] | din_b[5]	;
assign C[5]		= G[4] | (P[4] & C[4]) 	;
assign sum[5]	= G[5] ^ P[5] ^ C[5]	;


assign G[6] 	= din_a[6] & din_b[6]	;		//bit 6
assign P[6]		= din_a[6] | din_b[6]	;
assign C[6]		= G[5] | (P[5] & C[5]) 	;
assign sum[6]	= G[6] ^ P[6] ^ C[6]	;

assign G[7] 	= din_a[7] & din_b[7]	;		//bit 7
assign P[7]		= din_a[7] | din_b[7]	;
assign C[7]		= G[6] | (P[6] & C[6]) 	;
assign sum[7]	= G[7] ^ P[7] ^ C[7]	;

assign cout = G[7] | (P[7] & C[7])		;
endmodule 

Quartus RTL图
用到了两个加法器。


Quartus Post mapping图
使用的资源明显要高于普通的并行加法器。


8bit流水线加法器

流水线设计可以有效提高工作频率,核心就是面积换速度。


Verilog代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2022 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT90S  1320343336@qq.com
// File   : Pipeline_adder.v
// Create : 2022-11-21 15:40:45
// Revise : 2022-11-21 15:40:45
// Editor : 0078
// Verdion: v1.0
// Description: 8bit 流水线加法器
// -----------------------------------------------------------------------------
module Pipeline_adder (
	input [7:0]			din_a		,   // data in a
	input [7:0]			din_b		, 	// data in b
	input 				cin 		,	// Carry in
	input 				clk 		,	// Clock
	output 	reg [7:0]	sum 		,	// Sum
	output	reg 		cout 			// Carry out	
);

	reg 	[7:0]	a_t ;
	reg 	[7:0]	b_t ;

//carry in & out
	reg 	ci_t 	;
	reg 	p1co 	;
	reg 	p2co 	;
	reg 	p3co 	;

	reg [5:0]	p1a ;
	reg [5:0]	p1b ;
	reg [1:0] 	p1s ;

	reg [3:0]	p2a ;
	reg [3:0] 	p2b ;
	reg [3:0]	p2s ;

	reg [1:0] 	p3a ;
	reg [1:0]	p3b ;
	reg [5:0]	p3s ;


always@(posedge clk) begin
		a_t 	<=   din_a 	;
		b_t 	<= 	 din_b 	;
		ci_t 	<=	 cin 	;
end


always@(posedge  clk )	begin
	{p1co,p1s}  <= a_t[1:0]	+ b_t[1:0] + ci_t	;
	p1a 		<= a_t[7:2]	;
	p1b 		<= b_t[7:2]	;
end


always@(posedge  clk )	begin
	{p2co,p2s}  <= p1a[1:0]	+ p1b[1:0] + p1co + p1s	;
	p2a 		<= p1a[5:2]	;
	p2b 		<= p1b[5:2]	;
end

always@(posedge  clk )	begin
	{p3co,p3s}  <= p2a[1:0]	+ p2b[1:0] + p2co + p2s	;
	p3a 		<= p1a[3:2]	;
	p3b 		<= p1b[3:2]	;
end

always@(posedge  clk )	begin
	{cout,sum}		<=	p3a[1:0] + p3b[1:0]	+ p3co + p3s ;
end

endmodule 

Quartus RTL图
用到了四个2bit加法器以及中间数据缓存。


Quartus Post mapping图
这个资源的使用就更多,更大的面积换取更高的运行速度。


8bit级联加法器

级联加法器的结构简单,但N位级联加法器的延时是一位全加器的N倍,延时主要是由于进位信号级联造成的,避免在高性能要求的设计中采用该结构。
Verilog代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT90S  1320343336@qq.com
// File   : Cascade_adder.v
// Create : 2023-03-20 10:51:14
// Revise : 2023-03-20 10:51:14
// Editor : 0078
// Verdion: v1.0
// Description: 8bit 级联加法器
// -----------------------------------------------------------------------------
module Cascade_adder(

	input  	[7:0] 		a 		, 	 	//data in a
	input 	[7:0]		b 		, 		//data in b
	input 				cin 	,		//carry in
	output wire  		cout 	,		//carry out
	output wire [7:0]	sum 			//sum
	);

//signal 
wire cin1 	;
wire cin2 	;
wire cin3 	;
wire cin4 	;
wire cin5 	;
wire cin6 	;
wire cin7 	;

// inst cascade desc

full_add1 f0(
	.a 		(a[0]	),
	.b 	 	(b[0]	),
	.cin  	(cin 	),
	.cout 	(cin1 	),
	.sum 	(sum[0] )
	);

full_add1 f1(
	.a 		(a[1]	),
	.b 	 	(b[1]	),
	.cin  	(cin1 	),
	.cout 	(cin2 	),
	.sum 	(sum[1] )
	);

full_add1 f2(
	.a 		(a[2]	),
	.b 	 	(b[2]	),
	.cin  	(cin2 	),
	.cout 	(cin3 	),
	.sum 	(sum[2] )
	);

full_add1 f3(
	.a 		(a[3]	),
	.b 	 	(b[3]	),
	.cin  	(cin3 	),
	.cout 	(cin4 	),
	.sum 	(sum[3] )
	);


full_add1 f4(
	.a 		(a[4]	),
	.b 	 	(b[4]	),
	.cin  	(cin4 	),
	.cout 	(cin5 	),
	.sum 	(sum[4] )
	);

full_add1 f5(
	.a 		(a[5]	),
	.b 	 	(b[5]	),
	.cin  	(cin5 	),
	.cout 	(cin6 	),
	.sum 	(sum[5] )
	);

full_add1 f6(
	.a 		(a[6]	),
	.b 	 	(b[6]	),
	.cin  	(cin6 	),
	.cout 	(cin7 	),
	.sum 	(sum[6] )
	);

full_add1 f7(
	.a 		(a[7]	),
	.b 	 	(b[7]	),
	.cin  	(cin7 	),
	.cout 	(cout 	),
	.sum 	(sum[7] )
	);

endmodule 

其中,8bit级联加法器需要使用8个单bit的全加器。其描述如下:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : HFUT90S  1320343336@qq.com
// File   : fuu_add1.v
// Create : 2023-03-20 11:06:52
// Revise : 2023-03-20 11:06:52
// Editor : 0078
// Verdion: v1.0
// Description: 1bit full adder
// -----------------------------------------------------------------------------
module full_add1 (
	input  		a 	,    	// data in a
	input  		b 	, 		// data in b
	input 		cin ,  		// carry in 
	output 		sum ,		// sum
	output 		cout 		// carry out
);

//signal 
wire 	s1 	;
wire 	m1 	;
wire 	m2 	;
wire 	m3 	;

and (m1,a,b 	),
	(m2,b,cin   ),
	(m3,a,cin 	);

xor (s1,a,b 	),
	(sum,s1,cin );

or (cout,m1,m2,m3);

endmodule 

Quartus RTL图
用到了8个加法器。


单bit全加器。


Quartus Post mapping图


总结