Verilog设计实例(5)详解全类别加法器(二)
文章目录
- 写在前面
- 正文
- 超前进位加法器
- 4位超前进位加法器
- 任意位宽的超前进位加法器
- 参考资料
- 交个朋友
写在前面
相关博文
个人博客首页
正文
超前进位加法器
超前加法器由许多级联在一起的全加法器组成。 它仅通过简单的逻辑门就可以将两个二进制数相加。 下图显示了连接在一起以产生4位超前进位加法器的4个全加器。 超前进位加法器类似于纹波提前加法器。 不同之处在于,超前进位加法器能够在完全加法器完成其运算之前计算进位。 这比起波纹加法器具有优势,因为它能够更快地将两个数字加在一起。 缺点是需要更多逻辑。 您会发现在设计FPGA和ASIC时,执行速度和使用的资源之间通常会达到平衡。
所谓超前进位,就是在加法运算得到结果之前,得到进位,如何判断是否进位呢?
以上图为例给出三步判断:
- 如果Ai与Bi都为1,则一定进位,否则不一定进位;由此确定一定进位的情况,可以用与门实现。伪代码表示为:Gi = Ai & Bi;
- 第一步确定了一定进位的情况,这一步确定可能进位的情况,也就是Ai或Bi有一个1,可以使用或门判断,伪代码为:Pi = Ai | Bi;
- 这一步进一步确定第二部不确定的情况,如果低一位(进位用Ci表示,则低为可以表示为C_i-1)确定了进位,并且Pi为1,则一定进位,也即Ci = 1。
最后得到进位公式为:
C_(i+1) = G_i | ( P_i & C_i ) ;
由此得到的伪代码为:
// Create the Generate (G) Terms: Gi=Ai*Biassign w_G[0] = i_add1[0] & i_add2[0];assign w_G[1] = i_add1[1] & i_add2[1];assign w_G[2] = i_add1[2] & i_add2[2];assign w_G[3] = i_add1[3] & i_add2[3];// Create the Propagate Terms: Pi=Ai+Biassign w_P[0] = i_add1[0] | i_add2[0];assign w_P[1] = i_add1[1] | i_add2[1];assign w_P[2] = i_add1[2] | i_add2[2];assign w_P[3] = i_add1[3] | i_add2[3];// Create the Carry Terms:assign w_C[0] = 1'b0; // no carry inputassign w_C[1] = w_G[0] | (w_P[0] & w_C[0]);assign w_C[2] = w_G[1] | (w_P[1] & w_C[1]);assign w_C[3] = w_G[2] | (w_P[2] & w_C[2]);assign w_C[4] = w_G[3] | (w_P[3] & w_C[3]);
4位超前进位加法器
逻辑设计
由上述原理,得到的逻辑设计Verilog代码为:
`timescale 1ns / 1ps
//
// Engineer: Reborn Lee
// Module Name: carry_lookahead_adder_4_bit
// Additional Comments:
// https://blog.csdn.net/Reborn_Lee
//
`include "full_adder.v"module carry_lookahead_adder_4_bit (input [3:0] i_add1,input [3:0] i_add2,output [4:0] o_result);wire [4:0] w_C;wire [3:0] w_G, w_P, w_SUM;full_adder full_adder_bit_0( .i_bit1(i_add1[0]),.i_bit2(i_add2[0]),.i_carry(w_C[0]),.o_sum(w_SUM[0]),.o_carry());full_adder full_adder_bit_1( .i_bit1(i_add1[1]),.i_bit2(i_add2[1]),.i_carry(w_C[1]),.o_sum(w_SUM[1]),.o_carry());full_adder full_adder_bit_2( .i_bit1(i_add1[2]),.i_bit2(i_add2[2]),.i_carry(w_C[2]),.o_sum(w_SUM[2]),.o_carry());full_adder full_adder_bit_3( .i_bit1(i_add1[3]),.i_bit2(i_add2[3]),.i_carry(w_C[3]),.o_sum(w_SUM[3]),.o_carry());// Create the Generate (G) Terms: Gi=Ai*Biassign w_G[0] = i_add1[0] & i_add2[0];assign w_G[1] = i_add1[1] & i_add2[1];assign w_G[2] = i_add1[2] & i_add2[2];assign w_G[3] = i_add1[3] & i_add2[3];// Create the Propagate Terms: Pi=Ai+Biassign w_P[0] = i_add1[0] | i_add2[0];assign w_P[1] = i_add1[1] | i_add2[1];assign w_P[2] = i_add1[2] | i_add2[2];assign w_P[3] = i_add1[3] | i_add2[3];// Create the Carry Terms:assign w_C[0] = 1'b0; // no carry inputassign w_C[1] = w_G[0] | (w_P[0] & w_C[0]);assign w_C[2] = w_G[1] | (w_P[1] & w_C[1]);assign w_C[3] = w_G[2] | (w_P[2] & w_C[2]);assign w_C[4] = w_G[3] | (w_P[3] & w_C[3]);assign o_result = {w_C[4], w_SUM}; // Verilog Concatenationendmodule // carry_lookahead_adder_4_bit
注:头文件中包含的全加器为:
`timescale 1ns / 1ps
//
// Engineer: Reborn Lee
// Module Name: full_adder
// https://blog.csdn.net/Reborn_Lee
//module full_adder(input i_bit1,input i_bit2,input i_carry,output o_sum,output o_carry);assign o_sum = i_bit1 ^ i_bit2 ^ i_carry;assign o_carry = ((i_bit1 ^ i_bit2) & i_carry) | (i_bit1 & i_bit2);// More clear method// wire w_WIRE_1;
// wire w_WIRE_2;
// wire w_WIRE_3;// assign w_WIRE_1 = i_bit1 ^ i_bit2;
// assign w_WIRE_2 = w_WIRE_1 & i_carry;
// assign w_WIRE_3 = i_bit1 & i_bit2;// assign o_sum = w_WIRE_1 ^ i_carry;
// assign o_carry = w_WIRE_2 | w_WIRE_3;// The third method// assign {o_carry, o_sum} = i_bit1 + i_bit2 + i_carry;endmodule
功能仿真
`timescale 1ns/1ps
module carry_lookahead_adder_4_bit_tb;reg [3:0] i_add1;reg [3:0] i_add2;wire [4:0] o_result;initial begini_add1 = 'd5;i_add2 = 'd11;# 10i_add1 = 'd6;i_add2 = 'd15;# 10i_add1 = 'd11;i_add2 = 'd13;# 10i_add1 = 'd15;i_add2 = 'd15;#10 $finish;end// Monitor values of these variables and print them into the log file for debuginitial$monitor ("i_add1 = %b, i_add2 = %b, o_result = %b", i_add1, i_add2, o_result);carry_lookahead_adder_4_bit inst_carry_lookahead_adder_4_bit(.i_add1(i_add1),.i_add2(i_add2),.o_result(o_result));endmodule
仿真波形及数据
i_add1 = 0101, i_add2 = 1011, o_result = 10000
i_add1 = 0110, i_add2 = 1111, o_result = 10101
i_add1 = 1011, i_add2 = 1101, o_result = 11000
i_add1 = 1111, i_add2 = 1111, o_result = 11110
任意位宽的超前进位加法器
逻辑设计
使用参数化的方式定义位宽为 WIDTH,且使用generate for循环语句来进行全加器例化以及进位产生,设计文件如下:
`include "full_adder.v"module carry_lookahead_adder#(parameter WIDTH = 3)(input [WIDTH-1:0] i_add1,input [WIDTH-1:0] i_add2,output [WIDTH:0] o_result);wire [WIDTH:0] w_C;wire [WIDTH-1:0] w_G, w_P, w_SUM;// Create the Full Addersgenvar ii;generatefor (ii=0; ii<WIDTH; ii=ii+1) beginfull_adder full_adder_inst( .i_bit1(i_add1[ii]),.i_bit2(i_add2[ii]),.i_carry(w_C[ii]),.o_sum(w_SUM[ii]),.o_carry());endendgenerate// Create the Generate (G) Terms: Gi=Ai*Bi// Create the Propagate Terms: Pi=Ai+Bi// Create the Carry Terms:genvar jj;generatefor (jj=0; jj<WIDTH; jj=jj+1) beginassign w_G[jj] = i_add1[jj] & i_add2[jj];assign w_P[jj] = i_add1[jj] | i_add2[jj];assign w_C[jj+1] = w_G[jj] | (w_P[jj] & w_C[jj]);endendgenerateassign w_C[0] = 1'b0; // no carry input on first adderassign o_result = {w_C[WIDTH], w_SUM}; // Verilog Concatenation
- 注意要对第一个进位进行置0,因为第一个全加器没有进位。
功能仿真
功能仿真同上一个tb文件类似,这里不在赘余了。
参考资料
- 参考资料1
- 参考资料2
交个朋友
个人微信公众号:FPGA LAB,左下角二维码;
知乎:李锐博恩,右下角二维码。
FPGA/IC技术交流2020
Verilog设计实例(5)详解全类别加法器(二)相关推荐
- Verilog设计实例(4)详解全类别加法器(一)
博文目录 写在前面 正文 半加器 设计代码 测试文件 行为仿真波形图 全加器 设计文件 设计完整文件 行为仿真 纹波进位加法器 2bit数据等波纹加法设计 参数化的等波纹加法器设计 参考资料 交个朋友 ...
- yii mysql 事务处理_Yii2中事务的使用实例代码详解
前言 一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题. 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全 ...
- (38)System Verilog类class复制详解
(38)System Verilog类class复制详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog类class复制详解 5)结语 ...
- (34)System Verilog类的多对象详解
(34)System Verilog类的多对象详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog类的多对象详解 5)结语 1.2 F ...
- (35)System Verilog类静态变量详解
(35)System Verilog类静态变量详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog类静态变量详解 5)结语 1.2 F ...
- (17)System Verilog枚举类型enum详解
(17)System Verilog枚举类型enum详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog枚举类型enum详解 5)结语 ...
- (15)System Verilog结构体struct详解
(15)System Verilog结构体struct详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog结构体struct详解 5) ...
- Java设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- Redis设计与实现详解二:Redis数据库实现
Redis设计与实现详解一:数据结构与对象 Redis设计与实现详解三:多机功能实现 Redis设计与实现详解四:其他单机功能 数据库 服务器中的数据库 Redis服务器将所有数据库都保存在服务器状态 ...
最新文章
- ae中英文切换_AE技巧,AE CC软件如何切换中英文版
- java的编译及运行
- 详解 Java 的八大基本类型,写得非常好!
- EasyExcle使用小结
- JavaScript从入门到放弃 -(二)继承
- 《软件项目管理(第二版)》期中考试试题总结/复习资料
- java 读取1m文件_java的FileInputStream类读取文件
- 《黑客帝国》中的代码雨让人身临其境!利用Python轻松实现!
- 2010年的最后一天,我又辞工(日记)
- 防火墙透明模式下虚拟系统配置实例
- IOS 10 适配系列 _3_ Xcode 8 GM seed
- Qt知识回顾(九)——2D绘画
- 固态硬盘 格式化 linux,ssd固态硬盘格式化图文详细教程
- python 音乐相册_App Store 上的“魔力相册-音乐相册、视频电子相册制作工具”...
- shell中的EOF用法
- 数据结构 c语言(严蔚敏) 总结 + 代码
- Chap.6 总结《CL: An Introduction》 (Vyvyan Evans)
- 好玩的python3代码_python好玩的项目—色情图片识别代码分享
- 【Jlink烧录自动化】一台电脑连接 多个Jlink 用 J-flash批处理程序烧写多个单片机(生产批量烧录)
- SolidWorks中为何直径或半径标注前总显示<MOD-DIAM>