草庐IT

【数电】【verilog】加法器

李十一11 2023-04-12 原文

1.2输入1bit半加器

半加器的电路如下图所示:

 

module half adder(
	input wire A,
	input wire B,
	output wire C,
	output wire sum
);

//assign sum = (A == B) ? 0 : 1;  //这两种方式都可以实现
assign sum = A^B;
assign C= A&B;

endmodule 

2.2输入1bit全加器

 真值表:

 电路图(有很多不同的电路形式):

第一种,利用连续赋值语句实现: 

module full_add2
(
	input a,     	//加数
	input b,		//被加数
	input cin,		//进位输入
	output sum,		//结果输出
	output cout		//进位输出
);
	assign sum = a^b^cin;
	assign cout = (a&b)|((a^b)&cin);
endmodule

第二种,利用行为描述方式实现:

module full_add2
(
	input a,     	//加数
	input b,		//被加数
	input cin,		//进位输入
	output sum,		//结果输出
	output cout		//进位输出
);
	assign {cout,sum} = a+b+cin; //利用拼接的方式实现全加器
endmodule

第三种,利用两个一位半加器并联实现一个一位全加器,sum = a^b^cin,cout = (a&b)|((a^b)&cin):

module add_half(
   input                A   ,
   input                B   ,
   output	wire        S   ,
   output   wire        C   
);

assign S = A ^ B;
assign C = A & B;
endmodule

/***************************************************************/
module add_full(
   input                A   ,
   input                B   ,
   input                Ci  , 

   output	wire        S   ,
   output   wire        Co   
);
    wire [1:0] s, c;
    
    add_half m1 (
        .A(A),
        .B(B),
        .S(s[0]),
        .C(c[0]));
    
    add_half m2 (
        .A(s[0]),
        .B(Ci),
        .S(s[1]),
        .C(c[1]));
    
    assign S = s[1];
    assign Co = c[0] | c[1];
endmodule

3.4位串行加法器(全加器)

第一种,利用半加器生成全加器,再用全加器生成串行全加器:

`timescale 1ns/1ns

module add_half(
   input                A   ,
   input                B   ,
 
   output	wire        S   ,
   output   wire        C   
);

assign S = A ^ B;
assign C = A & B;
endmodule

/***************************************************************/
module add_full(
   input                A   ,
   input                B   ,
   input                Ci  , 

   output	wire        S   ,
   output   wire        Co   
);

wire c_1;
wire c_2;
wire sum_1;

add_half add_half_1(
   .A   (A),
   .B   (B),
         
   .S   (sum_1),
   .C   (c_1)  
);
add_half add_half_2(
   .A   (sum_1),
   .B   (Ci),
         
   .S   (S),
   .C   (c_2)  
);

assign Co = c_1 | c_2;
endmodule
/******************************************************************/
module add_4(
   input         [3:0]  A   ,
   input         [3:0]  B   ,
   input                Ci  , 

   output	wire [3:0]  S   ,
   output   wire        Co   
);

wire [3:0] C;

add_full u1(
   .A   (A[0]),
   .B   (B[0]),
   .Ci  (Ci), 
          
   .S   (S[0]),
   .Co  (C[0])   
);
add_full u2(
   .A   (A[1]),
   .B   (B[1]),
   .Ci  (C[0]), 
          
   .S   (S[1]),
   .Co  (C[1])   
);
add_full u3(
   .A   (A[2]),
   .B   (B[2]),
   .Ci  (C[1]), 
          
   .S   (S[2]),
   .Co  (C[2])   
);
add_full u4(
   .A   (A[3]),
   .B   (B[3]),
   .Ci  (C[2]), 
          
   .S   (S[3]),
   .Co  (C[3])   
);
assign Co = C[3];

endmodule

第二种,利用拼接的方式来搭建电路:

//4位全加器,有低位向本位进位(即有输入进位)
module  four_bits_full_add(
  input  [3:0]a,b,
  input  cin,
  output cout,
  output [3:0]sum
);
  assign {cout,sum} = a + b + cin; 
endmodule

串行全加器是上面这样,但是这种结构的缺点是,必须要等到上一片的结果算出来之后下一片才能进行工作,当级数很高的时候计算的时间将是每一片时间的n倍,会出现组合逻辑延时过长的问题。此时另一种进位方法——超前进位加法器就可以解决这一延时过高的问题。

4.4位超前进位加法器

根据上面的讲解,我们可以得到:

 然后根据下面公式:

 带入到上面,得到:

 我们定义下面两个式子分别为进位传输函数和进位产生函数:

代入可以得到:

 最后,4位的超前进位加法器可以得到下面这些式子:

这里实在看不懂可以翻一番数电的超前进位加法器的内容。

 verilog代码如下:0

module four_bits_fast_adder(cout,sum,a,b,cin);
  output [3:0]sum;  //数据累加和本位
  output		  cout;  //输出进位
  input  [3:0]a,b;  //需要相加的数
  input       cin;  //输入进位
  wire	 [4:0]g,p,c;  //分别对应Gi、Pi和Ci
  
  assign  c[0] = cin;  //最低进位为输入进位
  assign  P = a | b;  // Pi = Ai·Bi
  assign  g = a & b;  // Gi = Ai+Bi
  assign  c[1] = g[0] | (p[0]&c[0]);  
  assign  c[2] = g[1] | ( p[1]&(g[0] | (p[0]&c[0]) );
  assign  c[3] = g[2] | (p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))));
  assign  c[4] = g[3] | (p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));
  assign  sum = p ^ c[3:0];  
  assign  cout = c[4];
endmodule

 超前进位加法器就是用电路的复杂度来换时间。

有关【数电】【verilog】加法器的更多相关文章

  1. Verilog使用inout信号的方法 - 2

    目录一、inout在设计文件中的使用方法1.1、inout的第一种使用方法1.2、inout实现的第二种使用方法1.3、inout使用总结 二、inout在仿真测试中的使用方法一、inout在设计文件中的使用方法在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPIFlash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。1.1、inout的第一种使用方法  实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电

  2. JavaScript 加法/求和循环 - 2

    我正在尝试添加以下内容,但它一直连接并返回一个字符串。varnums=[1.99,5.11,2.99];vartotal=0;nums.forEach(function(i){total+=parseFloat(i).toFixed(2);});是的,我需要它来返回/加上小数。不确定要做什么 最佳答案 如果你想要一个更实用的方法,你也可以使用Array.reduce:varnums=[1.99,5.11,2.99];varsum=nums.reduce(function(prev,cur){returnprev+cur;},0);最

  3. JavaScript 赋值改变了加法运算语义? - 2

    如果你评估{}+1你得到1,但是如果你将相同的表达式分配给一个变量,比如x={}+1,该变量将保存一个字符串"[objectObject]1"。为什么赋值会改变右侧表达式的语义?右边的表达式不应该是“上下文无关的”吗? 最佳答案 {}+1被解释为后跟+1的代码块,其计算结果为1。奥托:x={}+1被评估为newObject()加上1如果您将原始语句更改为:newObject()+1您将看到[objectObject]1"作为结果。 关于JavaScript赋值改变了加法运算语义?,我们在

  4. vscode搭建Verilog HDL开发环境 - 2

      工欲善其事,必先利其器。应该没有多少人会使用Quartus和vivado这些软件自带的编辑器吧,原因在于这些编辑器效率很低,VerilogHDL代码格式比较固定,通常可以利用代码片段补全加快书写。基本上代码写完之后才会打开Quartus或者vivado建立工程,这其实要求编辑器需要有代码检错的功能,否则可能编译时一直报错,什么信号没定义,信号定义错误之类的。Vscode利用插件可以实现此功能,可以达到一次设计就通过编译和仿真。1、vscode安装及解决下载速度慢  首先通过VisualStudioCode-CodeEditing.Redefined安装vscode软件,如图1下载64位vs

  5. MCDF实验4:魔龙的狂舞(从verilog到SV的入门lab4) - 2

    前言:验证结构与实验3是相同的,但需要验证的对象是完整的mcdf。对比之前新添加了reg寄存器模块(选择数据),formatter模块(数据打包)。种一棵树最好的时间是十年前,其次是现在。不是吗?实验3结构包含moinitor、checker、generator、initiator、test,这已经是一个完整的仿真结构,实验4可以说是实验3结构的复制粘贴。实验4将设计变得更复杂,添加了reg寄存器模块,formatter模块。验证过程完全相同,需要像实验3的验证过程一样对这两个模块也做仿真验证。设计中reg的功能是可以选择从哪个fifo接收数据,并且可以判断fifo余量(之前是margin),

  6. javascript - 为什么+=(加法赋值,加上等于)在 Node 中这么慢? - 2

    这个问题在这里已经有了答案:Whatdoescompoundlet/constassignmentmean?(1个回答)关闭5年前。在某些版本的node中,a+=b明显比a=a+b慢,但在浏览器和更高版本中类似。是什么导致它们运行如此不同?nodev6.10.0(V85.1.281.93),慢75%,或者反向快4倍nodev8.0.0(V85.8.283.41),慢86%,或者反向快7倍nodev8.2.1(V85.8.283.41),慢86%,或者反向快7倍nodev8.3.0(V86.0.286.52),类似nodev8.7.0(v86.1.534.42),类似nodev8.9.2

  7. javascript - 帮助 double 加法 - 2

    我正在测试我的一些代码,在javascript中我添加了.1+.2,它给了我.30000000000000004而不是.3。我不明白这一点。但是当我添加.1+.3时,它给了我.4。我用谷歌搜索并找到了关于double加法的内容。但我不知道它是什么。 最佳答案 这是强制性链接:WhatEveryComputerScientistShouldKnowAboutFloating-PointArithmetic基本上,有许多以10为底的数字无法用大多数计算机使用的浮点格式准确表示,因此您会遇到与您突出显示的问题类似的问题。

  8. 数字电路——加法器 - 2

    数字电路——加法器组合电路(可略过)加法器半加器全加器我们之前了解了门,电路就是门的组合。电路又可以分为两大类,组合电路和时序电路。但作为计算机和编程的知识铺垫,我们要了解的是组合电路的使用方法。所以本篇讲的是组合电路的运算(电路的布尔运算。)推导过程略看也行。建议还是看看,了解一下。组合电路(可略过)输出仅由输入值确定的电路把一个门的输出作为另一个门的输入,就可以把门组合电路.如上图,两个与门的输出被用作或门的输入。注意:A同时是两个与门的输入。两条交叉的连接线的交汇处没有连接点,应该看做是一条连接线跨做了一条,他们互不影响电路分析我们倒着看,按照门来分析如果X=1则说明,D和E至少有一个是

  9. verilog设计抢答器【附源码】 - 2

    抢答器设计1、实验平台2、实验目的2.1、实验内容3、实验流程3.1、实验原理3.2、系统架构3.3、子功能模块设计3.3.1、中央控制模块模块框图信号定义设计文件3.3.2、数码管驱动模块设计文件3.3.3LED驱动模块3.3.4、按键消抖模块3.4仿真验证3.4、板级验证3.4.1、顶层文件4、总结1、实验平台软件:PC、QuartusPrime18.1、Modelsim10.5b硬件:AlteraFPGA开发板(EP4CE6E22F17C8)2、实验目的1、掌握数码管动态刷新原理2、逻辑练习2.1、实验内容基于开发板上的8位8段数码管和4个机械按键,制作一个抢答器,相关要求如下:1、 设

  10. go - 为什么浮点加法不精确? - 2

    这个问题在这里已经有了答案:Isfloatingpointmathbroken?(31个答案)Whyarefloatingpointnumbersinaccurate?(5个答案)关闭3年前。我发现了以下奇怪的行为。添加一些float会导致“随机”准确度。所以我先跑go版本go1.12darwin/amd64在带有Inteli72,6Ghz的macOSMojave(10.14.3)上行为发生在以下示例中:funcTestFloatingAddition(t*testing.T){f1:=float64(5)f2:=float64(12.1)f5:=float64(-12.1)f3:=f

随机推荐