基于Verilog的32位并行进位加法器设计

2023-05-16

1、功能概述:
先行进位加法器是对普通的全加器进行改良而设计成的并行加法器,主要是针对普通全加器串联时互相进位产生的延迟进行了改良。超前进位加法器是通过增加了一个不是十分复杂的逻辑电路来做到这点的。
设二进制加法器第i位为Ai,Bi,输出为Si,进位输入为Ci,进位输出为Ci+1,则有:
Si=Ai⊕Bi⊕Ci (1-1)
Ci+1 =Ai * Bi+ Ai Ci+ BiCi =Ai * Bi+(Ai+Bi)* Ci (1-2)
令Gi = Ai * Bi , Pi = Ai+Bi,则Ci+1= Gi+ Pi *Ci
当Ai和Bi都为1时,Gi = 1, 产生进位Ci+1 = 1
当Ai和Bi有一个为1时,Pi = 1,传递进位Ci+1= Ci
因此Gi定义为进位产生信号,Pi定义为进位传递信号。Gi的优先级比Pi高,也就是说:当Gi = 1时(当然此时也有Pi = 1),无条件产生进位,而不管Ci是多少;当Gi=0而Pi=1时,进位输出为Ci,跟Ci之前的逻辑有关。
下面推导4位超前进位加法器。设4位加数和被加数为A和B,进位输入为Cin,进位输出为Cout,对于第i位的进位产生Gi = Ai·Bi ,进位传递Pi=Ai+Bi , i=0,1,2,3。于是这各级进位输出,递归的展开Ci,有:
C0 = Cin
C1=G0 + P0·C0
C2=G1 + P1·C1 = G1 + P1·G0 + P1·P0 ▪C0
C3=G2 + P2·C2 = G2 + P2·G1 + P2·P1·G0 + P2·P1·P0·C0
C4=G3 + P3·C3 = G3 + P3·G2 + P3·P2·G1 + P3·P2·P1·G0 + P3·P2·P1·P0·C0 (1-3)
Cout=C4
由此可以看出,各级的进位彼此独立产生,只与输入数据Ai、Bi和Cin有关,将各级间的进位级联传播给去掉了,因此减小了进位产生的延迟。每个等式与只有三级延迟的电路对应,第一级延迟对应进位产生信号和进位传递信号,后两级延迟对应上面的积之和。实现上述逻辑表达式(1-3)的电路称为超前进位部件(Carry Lookahead Unit),也称为CLA部件。通过这种进位方式实现的加法器称为超前进位加法器。因为各个进位是并行产生的,所以是一种并行进位加法器。
从公式(1-3)可知,更多位数的CLA部件只会增加逻辑门的输入端个数,而不会增加门的级数,因此,如果采用超前进位方式实现更多位的加法器,从理论上讲,门延迟不变。但是由于CLA部件中连线数量和输入端个数的增多,使得电路中需要具有大驱动信号和大扇入门,这会大大增加门的延迟,起不到提高电路性能的作用。因此更多位数的加法器可通过4位CLA部件和4位超前进位加法器来实现,如图2所示。
将式(1-3)中进位C4的逻辑方程改写为:
C4=Gm0 + Pm0·C0 (1-4)
C4表示4位加法器的进位输出,Pm0、Gm0分别表示4位加法器的进位传递输出和进位产生输出,分别为:
Pm0 = P3·P2·P1·P0
Gm0 = G3 + P3·G2 + P3·P2·G1 + P3·P2·P1·G0
将式(1-4)应用于4个4位先行进位加法器,则有:
C4=Gm0 + Pm0·C0
C8= Gm1 + Pm1·C4 = Gm1 + Pm1·Gm0 + Pm1·Pm0 ▪C0
C12= Gm2 + Pm2·C8 = Gm2 + Pm2·Gm1 + Pm2·Pm1·Gm0 + Pm2·Pm1·Pm0·C0
C16=Gm3+Pm3·C12=Gm3+Pm3·Gm2+Pm3·Pm2·Gm1+Pm3·Pm2·Pm1·Gm0+Pm3·Pm2·Pm1·Pm0·C0 (1-5)
比较式(1-3)和式(1-5),可以看出这两组进位逻辑表达式是类似的。不过式(1-3)表示的是组内进位,式(1-5)表示的是组间的进位。实现逻辑方程组(1-5)的电路称为成组先行进位部件。图1a为所设计的32位超前进位加法器的结构框图,该加法器采用三级超前进位加法器设计,组内和组间均采用超前进位。由8个4位超前进位加法器与3个BCLA部件构成。图1b为采用超前进位和进位选择实现的32位先行进位加法器结构图。

2、结构框图
在这里插入图片描述
(a) 32位超前进位加法器结构图

//一位全加器
module adder(X,Y,Cin,F,Cout);

  input X,Y,Cin;
  output F,Cout;
  
  assign F = X ^ Y ^ Cin;
  assign Cout = (X ^ Y) & Cin | X & Y;
endmodule 
//一位全加器测试代码
`timescale 1ns/1ns
module adder_tb;

    reg x;
	reg y;
	reg cin;
	wire f;
	wire cout;
		
	 adder adder(
	            .X(x),
	            .Y(y),
				.Cin(cin),
				.F(f),
				.Cout(cout)
			);

 initial begin 
    
	 x = 0;
	 y = 0;
	 cin = 0;
	 
  #5  x = 0;y = 1;cin = 1;
  #5  x = 1;y = 0;cin = 1;
  #5  x = 1;y = 0;cin = 0;	 
 end
endmodule 
/******************4位CLA部件************************/
module CLA(c0,c1,c2,c3,c4,p1,p2,p3,p4,g1,g2,g3,g4);
   
	 input c0,g1,g2,g3,g4,p1,p2,p3,p4;
	 output c1,c2,c3,c4;
	 
	 assign    c1 = g1 ^ (p1 & c0),
	          c2 = g2 ^ (p2 & g1) ^ (p2 & p1 & c0),
			  c3 = g3 ^ (p3 & g2) ^ (p3 & p2 & g1) ^ (p3 & p2 & p1 & c0),
			  c4 = g4 ^ (p4 & g3) ^ (p4 & p3 & g2) ^ (p4 & p3 & p2 & g1) ^(p4 & p3 & p2 & p1 & c0);
	 
endmodule 
//四位并行进位加法器
module adder_4(x,y,c0,c4,F,Gm,Pm);
     input [4:1] x;
	  input [4:1] y;
	  input c0;
	  output c4,Gm,Pm;
	  output [4:1] F;
	  	  
	  wire p1,p2,p3,p4,g1,g2,g3,g4;
	  wire c1,c2,c3;
	  adder adder1(
	             .X(x[1]),
					 .Y(y[1]),
					 .Cin(c0),
					 .F(F[1]),
					 .Cout()
				);
		
	  adder adder2(
	             .X(x[2]),
					 .Y(y[2]),
					 .Cin(c1),
					 .F(F[2]),
					 .Cout()
				);	
		
	 adder adder3(
	             .X(x[3]),
					 .Y(y[3]),
					 .Cin(c2),
					 .F(F[3]),
					 .Cout()
				);
			
	adder adder4(
	             .X(x[4]),
					 .Y(y[4]),
					 .Cin(c3),
					 .F(F[4]),
					 .Cout()
				);		
		
		CLA CLA(
			.c0(c0),
			.c1(c1),
			.c2(c2),
			.c3(c3),
			.c4(c4),
			.p1(p1),
			.p2(p2),
			.p3(p3),
			.p4(p4),
			.g1(g1),
			.g2(g2),
			.g3(g3),
			.g4(g4)
		);
				
		
	  
  assign   p1 = x[1] ^ y[1],	  
           p2 = x[2] ^ y[2],
		   p3 = x[3] ^ y[3],
		   p4 = x[4] ^ y[4];

  assign   g1 = x[1] & y[1],
           g2 = x[2] & y[2],
		   g3 = x[3] & y[3],
		   g4 = x[4] & y[4];

  assign Pm = p1 & p2 & p3 & p4,
         Gm = g4 ^ (p4 & g3) ^ (p4 & p3 & g2) ^ (p4 & p3 & p2 & g1);

endmodule 
//四位并行进位加法器测试代码
`timescale 1ns/1ns
module adder_4_tb;

    reg [4:1] x;
	reg [4:1] y;
	reg c0;
	wire c4;
	wire [4:1] F;
	integer i,j;

  adder_4 adder_4(
	  .x(x),
	  .y(y),
	  .c0(c0),
	  .c4(c4),
	  .F(F),
	  .Pm(),
	  .Gm()
  );
  
  
  initial begin
    x = 4'd0; y = 4'd0; c0 = 0;
	 
	#5;
	for (i = 0; i < 16; i = i + 1)begin
	    for (j = 0 ; j < 16; j = j + 1) begin
		     y = y + 1;
			  #5;
		 end
		 
		 x = x + 1;
		 #5;
	end	
	
	#5; c0 = 1; x = 4'd0; y = 4'd0;
	for (i = 0; i < 16; i = i + 1)begin
	    for (j = 0 ; j < 16; j = j + 1) begin
		     y = y + 1;
			  #5;
		 end
		 
		 x = x + 1;
		 #5;
	end
	$stop;   
  end
endmodule 
//16位CLA部件
module CLA_16(A,B,c0,S,px,gx);
   input [16:1] A;
	input [16:1] B;
	input c0;
	output gx,px;
	output [16:1] S;
	
	wire c4,c8,c12;
	wire Pm1,Gm1,Pm2,Gm2,Pm3,Gm3,Pm4,Gm4;
	
	adder_4 adder1(
	     .x(A[4:1]),
		  .y(B[4:1]),
		  .c0(c0),
		  .c4(),
		  .F(S[4:1]),
		  .Gm(Gm1),
		  .Pm(Pm1)
	);
	
	adder_4 adder2(
	     .x(A[8:5]),
		  .y(B[8:5]),
		  .c0(c4),
		  .c4(),
		  .F(S[8:5]),
		  .Gm(Gm2),
		  .Pm(Pm2)
	);
	
   adder_4 adder3(
	     .x(A[12:9]),
		  .y(B[12:9]),
		  .c0(c8),
		  .c4(),
		  .F(S[12:9]),
		  .Gm(Gm3),
		  .Pm(Pm3)
	);

   adder_4 adder4(
	     .x(A[16:13]),
		  .y(B[16:13]),
		  .c0(c12),
		  .c4(),
		  .F(S[16:13]),
		  .Gm(Gm4),
		  .Pm(Pm4)
	);
	
	assign   c4 = Gm1 ^ (Pm1 & c0),
	         c8 = Gm2 ^ (Pm2 & Gm1) ^ (Pm2 & Pm1 & c0),
			 c12 = Gm3 ^ (Pm3 & Gm2) ^ (Pm3 & Pm2 & Gm1) ^ (Pm3 & Pm2 & Pm1 & c0);
 
   assign  px = Pm1 & Pm2 & Pm3 & Pm4,
	       gx = Gm4 ^ (Pm4 & Gm3) ^ (Pm4 & Pm3 & Gm2) ^ (Pm4 & Pm3 & Pm2 & Gm1);
	       
endmodule 
//32位并行进位加法器顶层模块
module adder32(A,B,S,C32);
    input [32:1] A;
	 input [32:1] B;
	 output [32:1] S;
	 output C32;
	 
	 wire px1,gx1,px2,gx2;
	 wire c16;

  CLA_16 CLA1(
      .A(A[16:1]),
		.B(B[16:1]),
		.c0(0),
		.S(S[16:1]),
		.px(px1),
		.gx(gx1)
	);
  
  CLA_16 CLA2(
        .A(A[32:17]),
		  .B(B[32:17]),
		  .c0(c16),
		  .S(S[32:17]),
		  .px(px2),
		  .gx(gx2)
	);

  assign c16 = gx1 ^ (px1 && 0), //c0 = 0
         C32 = gx2 ^ (px2 && c16);

endmodule 
`timescale  1ns/1ns
module adder32_tb;

  reg [32:1] A;
  reg [32:1] B;
  wire [32:1] S;
  wire c32;
 
  adder32 adder32(
        .A(A),
		  .B(B),
		  .S(S),
		  .C32(c32)
		 );
		 
  initial begin
     A = 32'd0; B = 32'd0;
	  
	  #5;  A = 32'd 456;  B = 32'd234;
	  #5;  A = 32'd 245;  B = 32'd678;
	  $stop;  
  end
endmodule 

仿真图如下
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Verilog的32位并行进位加法器设计 的相关文章

  • 21,verilog之宏define介绍

    注 学习 交流就在博主的个人weixin公众号 FPGA动力联盟 留言或直接 博主weixin fpga start 私信 宏define提供用一个相对简单的文字来表示一大段真正有意义的文字作用 换句话说 就是综合软件见到定义的宏 就用这个
  • [从零开始学习FPGA编程-24]:进阶篇 - 基本组合电路-编码器与译码器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 125247358 目录 前言 Veri
  • Verilog 显示中不必要的空间

    我正在尝试以十进制显示一些 32 位值 除了 b 和前一个字符之间有奇怪数量的不必要的空格外 这工作正常 例如 如果我有一个 32 位 reg a 其十进制值为 33 我将使用类似的东西 initial begin display a d
  • 错误:“(vlog-2110) 非法引用网络”

    我在 SystemVerilog 中有一个简单的 FIFO 代码 我得到几个vlog 2110 illegal reference to net错误消息 我的错误消息后面是我的代码 错误信息 vlog work 工作 sv stats no
  • 如何在 Verilog 中将长语句分成行

    例如 我有一个很长的声明 display input data x output data x result x input data output data result 如何在 Verilog 中将其变成单语句和多行 您需要分解引用的字
  • 为什么我的输出没有被赋值?

    我正在为一个更大项目的一部分开发解码器 我有两个计数器充当该模块的输入 其中一个计数器计数 0 15 另一个计数器在第一个计数器达到 15 时递增一次 根据计数器的值 解码器输出不同的值 通常它是 0 1 或 1 但有时它必须是 0 707
  • 计算数组中的个数

    我试图在 Verilog 中计算 4 位二进制数中 1 的数量 但我的输出是意外的 我尝试了几种方法 这是我认为应该有效的方法 但事实并非如此 module ones one in input 3 0 in output 1 0 one a
  • Verilog HDL 循环语句错误:具有非常量循环条件的循环必须终止

    我对 Verilog 完全陌生 对于我在大学学习的课程 我必须很快了解它的很多内容 我正在摆弄我的 Altera DE2 板和 quartis2 并了解其细节 我正在尝试制作一个通过开关打开和关闭的计数器 到目前为止 计数器根据按键进行计数
  • 使用数据流模型的T触发器

    我正在尝试模拟 t flipflop 的工作 timescale 1ns 1ps module t flipflop input t input clk input clear output q output qbar wire sbar
  • EDAplayground 中不显示时钟波形

    当尝试在 EDA Playground 中显示时钟波形时 出现错误 执行中断或达到最大运行时间 如何显示波形 EDA Playground 上的代码 module test reg clk initial begin dumpfile du
  • 「Verilog学习笔记」 Johnson Counter

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module JC counter input clk input rst n output reg 3 0
  • [Verilog] Verilog 基本格式和语法

    主页 元存储博客 全文 3000 字 文章目录 1 声明格式 1 1 模块声明 1 2 输入输出声明 1 3 内部信号声明 1 4 内部逻辑声明
  • x 和 z 值在 Verilog 中到底代表什么?

    Verilog 标准定义了四种类型的位值 0 1 x 和 z 其中 0 表示低 1 表示高 x 表示未知 z 表示未驱动网络 有几个问题 x 是否意味着我们不知道该值是 0 还是 1 0 或 1 或 z 或者该值是未知的并且可以是 0 1
  • 使用forever和always语句

    以下两个代码都会生成一个时钟 我需要知道除了时钟生成之外 永远循环是否还有其他用途 我只在时钟一代中遇到过永远 如果只是为了这个目的 那岂不是毫无用处 initial begin clk 0 forever begin 5 clk clk
  • 如何生成异步复位verilog总是阻塞凿子

    Chisel 始终生成敏感度列表中仅包含时钟的块 always posedge clk begin end 是否可以将模块配置为使用异步重置并生成这样的始终块 always posedge clk or posedge reset begi
  • 「HDLBits题解」Gates4

    本专栏的目的是分享可以通过HDLBits仿真的Verilog代码 以提供参考 各位可同时参考我的代码和官方题解代码 或许会有所收益 题目链接 Gates4 HDLBits module top module input 3 0 in out
  • verilog 中的“<<”运算符

    我有一个verilog代码 其中有一行如下 parameter ADDR WIDTH 8 parameter RAM DEPTH 1 lt lt ADDR WIDTH 这里将存储什么RAM DEPTH以及什么是 lt lt 操作员在这里做
  • 如何获取值数组作为 plusargs?

    如何获取值数组作为参数 我需要从命令行获取一组未定义大小的命令 如何将这些参数放入数组或队列中 Eg CMDS READ WRITE READ N WRITE 它应该被带到一个数组中 value plusargs不支持数组 但支持字符串 看
  • 如何在 Verilog 中综合 While 循环?

    我尝试设计一个 Booth 乘法器 它在所有编译器中运行良好 包括 Modelsim Verilogger Extreme Aldec Active Hdl 和 Xilinx Isim 我知道模拟和综合是两个不同的过程 而且只有少数Veri
  • 使用正则表达式进行 Verilog 端口映射

    我有一个很长的端口映射 我想在其中替换一堆 SignalName i with SignalName SignalName i 我想我可以用正则表达式轻松地做到这一点 但我无法弄清楚如何做到这一点 有任何想法吗 假设 SignalData

随机推荐

  • STM32 【FreeRTOS HAL库】创建任务

    任务也不是很复杂的东西 简单得说 创建一个任务 你得提供它的执行函数 你得提供它的栈的大小 函数的执行空间 函数的优先级等重要的条件 因为任务在运行中 任务函数有调用关系 有局部变量 这些都保存在任务的栈里面 任务有可能被切换 有可能被暂停
  • 函数实现是否应该放在头文件

  • Microsoft Visual Studio C++2022 Windows 11 SDK环境

    Microsoft Visual Studio C 43 43 2022 Windows 11 SDK环境 1 安装2 环境变量本文为作者 难拳 原创 xff0c 转载请注明出处 1 安装 Visual Studio 2022适用于Wind
  • 【原创】浅谈指针(十)链表的写法

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475 前言 最近我又
  • AB实现双方通信

    题目要求 xff1a 通过C语言编写一个程序 xff0c 程序中需要有两个进程 xff0c 假设这两个进程是A和B xff0c 通过这两个进程模拟一个类似QQ聊天的情景 xff0c A进程和B进程分别代表通话一方 xff0c A进程能够发消
  • 串口传图显示

    串口传图 使用串口通信协议传输一张图像到SDRAM存储后VGA协议显示到屏幕 工程设计 图片生成 使用小梅哥资源中的Picture2Hex软件生成任意分辨率的图片 xff08 我这里选择640 480 xff09 matlab将得到合适分辨
  • Intel Realsense L515 ros节点时间戳不同步解决方法

    问题描述 在使用Intel Realsense L515的ros程序的时候 xff0c 会出现 frame 39 s span class token function time span domain is HARDWARE CLOCK
  • 宏定义(无参宏定义和带参宏定义)

    宏定义是比较常用的预处理指令 xff0c 即使用 标识符 来表示 替换列表 中的内容 标识符称为宏名 xff0c 在预处理过程中 xff0c 预处理器会把源程序中所有宏名 xff0c 替换成宏定义中替换列表中的内容 常见的宏定义有两种 xf
  • B6(B6AC)充电器中文简要说明书

    B6 xff08 B6AC xff09 充电器中文简要说明书 首先 xff0c 感谢模友们使用深圳比优德的B6充电器 深圳比优德动力产品技术有限公司致力于为全国模友提供最高性价比的动力产品 xff0c 公司所有产品均自主研发与自主生产 ww
  • c++STL库详细用法

    目录 1 什么是STL xff1f 2 STL内容介绍 2 1 容器 2 2 STL迭代器 2 3 算法 2 4 仿函数 2 4 1 概述 2 4 2 仿函数 functor 在编程语言中的应用 2 4 3 仿函数在STL中的定义 2 5
  • C语言之结构体对齐

    本次让我们来一起学习一下C语言中我们该如何将结构体内存对齐呢 xff1f 什么是结构体 xff1f span class token keyword struct span span class token class name A spa
  • STM32串口中断接收

    本次是结合项目 xff0c 来总结下在stm32CubeIDE开发环境下关于串口接收数据问题 xff1b 项目背景 xff1a 利用MODBUS通讯协议 串口中断的流程为 xff1a 1 在main c文件中对串口进行初始化操作 MX US
  • ORB-SLAM 学习笔记

    ORB SLAM 基本介绍 ORB SLAM 是西班牙 Zaragoza 大学的 Ra l Mur Arta 编写的视觉 SLAM 系统 它是一个完整的 SLAM 系统 xff0c 包括视觉里程计 跟踪 回环检测 xff0c 是一种完全基于
  • OCR(Optical Character Recognition,光学字符识别)问题

    应用场景 xff1a 在这个过程中由于场景的不确定性 xff0c 比如 xff1a 图片背景极其丰富 亮度不均衡 光照不均衡 残缺遮挡 文字扭曲 字体多样等等问题 xff0c 会带来极大的挑战 自然场景中文本具有多样性 xff1a 文本检测
  • OCR-文本检测方法

    基于回归的文本检测 基于回归文本检测方法和目标检测算法的方法相似 xff0c 文本检测方法只有两个类别 xff0c 图像中的文本视为待检测的目标 xff0c 其余部分视为背景 水平文本检测 早期基于深度学习的文本检测算法是从目标检测的方法改
  • C++中使用__FUNCTION__ ,__TIME__ ,__LINE__ ,__FILE__这几个宏的解释

    FUNCTION xff0c 34 TIME 34 xff0c LINE xff0c FILE 这几个宏是编译器自带的 xff0c 不是那个头文件定义的 FUNCION xff1a 函数名 TIME xff1a 文件运行的时间 LINE x
  • UART串口通信协议详解

    UART xff1a 通信异步收发器 xff0c 串行 异步通信总线 xff0c 两条数据线 xff08 收发 xff09 xff0c 全双工 xff08 可以同时接收和发送 xff09 一 UART帧格式 xff08 UART协议 xff
  • 基于FPGA的DDS信号发生器

    之前的博客讲到了DDS的基本原理 xff0c 现在用Verilog代码实现DDS 能够产生四种波形 xff0c 方波 xff0c 三角波 xff0c 正弦波 xff0c 锯齿波 xff0c 用按键来控制频率和选择波形 其中按键消抖模块来自小
  • C++的命名空间详解

    c 43 43 命名空间详解 命名空间的意义命名空间的定义命名空间的使用 命名空间的意义 在C C 43 43 中 xff0c 变量 函数和后面要学到的类都是大量存在的 xff0c 这些变量 函数和类的名称将都存在于全局作用域中 xff0c
  • 基于Verilog的32位并行进位加法器设计

    1 功能概述 xff1a 先行进位加法器是对普通的全加器进行改良而设计成的并行加法器 xff0c 主要是针对普通全加器串联时互相进位产生的延迟进行了改良 超前进位加法器是通过增加了一个不是十分复杂的逻辑电路来做到这点的 设二进制加法器第i位