半加器

如果不考虑来自低位的进位将两个1二进制数相加,称为半加。

实现半加运算的逻辑电路称为半加器。

真值表

>> 逻辑表达式和
\begin{align}\notag
s = a{b}' + {a}'b
\end{align}
>> 逻辑表达式进位输出
\begin{align}\notag
co = ab
\end{align}

verilog code

module halfadder(
output s, //sum
output co, //carry
input a,
input b
); assign s = a ^ b;
assign co = a & b;
//assign {co,s} = a + b; endmodule

testbench

module halfadder_tb;

wire  s;
wire co;
reg a;
reg b; initial
begin
a = 0;
b = 0;
#10 a = 0 ;b = 0;
#10 a = 0 ;b = 1;
#10 a = 1 ;b = 0;
#10 a = 1 ;b = 1;
#10 $finish;
end initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end halfadder u_halfadder(
.s(s),
.co(co),
.a(a),
.b(b)
); endmodule


全加器

在将两位多位二进制数相加时,除了最低位以外,每位都应该考虑来自低位的进位,即将两个对应位的加数和来自低位的进位3个数相加。这种运算称为全加,所用的电路称为全加器。

真值表

逻辑表达式和

\begin{align}\notag
s = {({a}'{b}'{ci}' + a{b}'ci + {a}'bci + ab{ci}'})'
\end{align}
>> 逻辑表达式进位输出
\begin{align}\notag
co = {({a}'{b}' + {b}'{ci}' + {a}'{ci}')}'
\end{align}

verilog code

module fulladder(
output s, //sum
output co, //carry to high bit
input a,
input b,
input ci //carry from low bit
);
//RTL level
assign s = ~((~a&~b&~ci)||(a&~b&ci)||(~a&b&ci)||(a&b&~ci));
assign co = ~((~a&~b)||(~b&~ci)||(~a&~ci)); //assign {co,s} = a + b + ci; endmodule

testbench

module fulladder_tb;

wire  s;
wire co;
reg a;
reg b;
reg ci; initial
begin
ci = 0; a = 0 ;b = 0;
#10 ci = 0; a = 0 ;b = 1;
#10 ci = 0; a = 1 ;b = 0;
#10 ci = 0; a = 1 ;b = 1;
#10 ci = 1; a = 0 ;b = 0;
#10 ci = 1; a = 0 ;b = 1;
#10 ci = 1; a = 1 ;b = 0;
#10 ci = 1; a = 1 ;b = 1;
#10 $finish;
end initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end fulladder u_fulladder(
.s(s),
.co(co),
.a(a),
.b(b),
.ci(ci)
); endmodule


多位加法器

串行进位加法器

依次将低位全加器的进位输出co接到全加器的进位输入端ci,就可以构成多位加法器。

显然,每一位的相加结果都必须等到低一位的进位产生才能建立起来,因此,这种结构的电路称为串行进位加法器(或称为行波进位加法器)。

verilog code (fulladder为上面所述的全加器)

module serialadder(
output [3:0] s,
output co,
input [3:0] a,
input [3:0] b,
input ci
);
wire [3:0] co_tmp; fulladder u_add0(
.s(s[0]), //sum
.co(co_tmp[0]), //carry to high bit
.a(a[0]),
.b(b[0]),
.ci(ci) //carry from low bit
); fulladder u_add1(
.s(s[1]), //sum
.co(co_tmp[1]), //carry to high bit
.a(a[1]),
.b(b[1]),
.ci(co_tmp[0]) //carry from low bit
); fulladder u_add2(
.s(s[2]), //sum
.co(co_tmp[2]), //carry to high bit
.a(a[2]),
.b(b[2]),
.ci(co_tmp[1]) //carry from low bit
); fulladder u_add3(
.s(s[3]), //sum
.co(co_tmp[3]), //carry to high bit
.a(a[3]),
.b(b[3]),
.ci(co_tmp[2]) //carry from low bit
); assign co = co_tmp[3]; endmodule

testbench

module serialadder_tb;
wire [3:0] s;
wire co;
reg [3:0] a;
reg [3:0] b;
reg ci; initial
begin
a = 4'b0000; b = 4'b0000; ci = 0;
#10 a = 4'b1111; b = 4'b1111; ci = 0;
#10 a = 4'b1100; b = 4'b1001; ci = 0;
#10 a = 4'b0111; b = 4'b0110; ci = 0;
#10 a = 4'b0101; b = 4'b0101; ci = 1;
#10 a = 4'b1110; b = 4'b1001; ci = 1;
#10 a = 4'b0010; b = 4'b0110; ci = 1;
#10 a = 4'b0110; b = 4'b1100; ci = 1;
#10 $finish;
end initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end serialadder u_serialadder(
.s(s),
.co(co),
.a(a),
.b(b),
.ci(ci)
); endmodule




超前进位加法器

超前进位信号的产生原理

  • ab = 1 --> co = 1
  • a + b = 1,且ci = 1 --> co =1

两位多位数中第i位相加产生的进位输出co(i)可以表示位

\begin{align}\notag
co_{i} = a_{i}b_{i} + (a_{i} + b_{i})(ci_{i})
\end{align}

>> 从全加器的真值表写出第i位和s(i)的逻辑式:
\begin{align}\notag
s_{i} = a_{i}{b_{i}}'{ci_{i}}' + {a_{i}}'b_{i}{ci_{i}}' + {a_{i}}'{b_{i}}'ci_{i} + (a_{i} + b_{i})ci_{i}
\end{align}
>> 上式变换位异或函数位:
\begin{align}\notag
s_{i} = a_{i} \oplus b_{i} \oplus ci_{i}
\end{align}

verilog code

module carry_look_aheadadder(
output [3:0] s,
output co,
input [3:0] a,
input [3:0] b,
input ci
);
wire [3:0] co_tmp;
wire [3:0] cin; assign cin[3:0] = {co_tmp[2:0],ci}; //计算中间进位
assign co_tmp[0] = a[0]&b[0] || (a[0] || b[0])&(cin[0]);
assign co_tmp[1] = a[1]&b[1] || (a[1] || b[1])&(cin[1]);
assign co_tmp[2] = a[2]&b[2] || (a[2] || b[2])&(cin[2]);
assign co_tmp[3] = a[3]&b[3] || (a[3] || b[3])&(cin[3]); //计算和
assign s[0] = a[0] ^ b[0] ^ cin[0];
assign s[1] = a[1] ^ b[1] ^ cin[1];
assign s[2] = a[2] ^ b[2] ^ cin[2];
assign s[3] = a[3] ^ b[3] ^ cin[3]; assign co = co_tmp[3];
endmodule

testbench

module carry_look_aheadadder_tb;
wire [3:0] s;
wire co;
reg [3:0] a;
reg [3:0] b;
reg ci; initial
begin
a = 4'b0000; b = 4'b0000; ci = 0;
#10 a = 4'b1111; b = 4'b1111; ci = 0;
#10 a = 4'b1100; b = 4'b1001; ci = 0;
#10 a = 4'b0111; b = 4'b0110; ci = 0;
#10 a = 4'b0101; b = 4'b0101; ci = 1;
#10 a = 4'b1110; b = 4'b1001; ci = 1;
#10 a = 4'b0010; b = 4'b0110; ci = 1;
#10 a = 4'b0110; b = 4'b1100; ci = 1;
#10 $finish;
end initial begin
$fsdbDumpfile("test.fsdb");
$fsdbDumpvars();
end carry_look_aheadadder u_carry_look_aheadadder(
.s(s),
.co(co),
.a(a),
.b(b),
.ci(ci)
); endmodule

参考资料

[1] 数字电子技术基础(第五版) 阎石主编

verilog 实现加法器的更多相关文章

  1. verilog流水线加法器

    四位加法器 两级加法实现 verilog code module pipeliningadder( output reg [3:0] s, output reg co, input [3:0] a, ...

  2. 【FPGA学习】Verilog之加法器

    在fpga工程应用设计中,随处可见加法器,乘法器等等.现在将一些常用模块和心得体会先记录下来,以便日后使用. 一位半加器: module halfadder(cout,sum,a,b); output ...

  3. verilog设计加法器

    概述 本文利用了硬件行为描述.数据流描述.结构描述三种方法分别写了几个加法器 一位半加法器 即两个一位的二进制数相加,得到其正常相加的结果的最后一位. 仿真波形图 硬件行为描述 设计文件 123456 ...

  4. 剑指Offer - 九度1507 - 不用加减乘除做加法

    剑指Offer - 九度1507 - 不用加减乘除做加法2013-11-29 20:00 题目描述: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 输入: 输入可能包 ...

  5. Verilog 加法器和减法器(8)-串行加法器

    如果对速度要求不高,我们也可以使用串行加法器.下面通过状态机来实现串行加法器的功能. 设A=an-1an-2-a0, B=bn-1bn-2-b0,是要相加的两个无符号数,相加的和为:sum=sn-1s ...

  6. Verilog 加法器和减法器(4)

    类似于行波进位加法器,用串联的方法也能够实现多位二进制数的减法操作.  比如下图是4位二进制减法逻辑电路图. 8位二进制减法的verilog代码如下: module subn(x, y, d,cin) ...

  7. 第一个Verilog程序:通用加法器

    Verilog作为一门硬件描述语言,快速掌握它的方法就是不断的练习,反复动手实践,通过例子掌握隐藏在语句背后的硬件电路.下面是第一个需要学习的Verilog例子: )( :] a, :] b, inp ...

  8. 多路选择器,加法器原理及verilog实现

    1.数据选择器是指经过选择,把多个通道的数据传到唯一的公共数据通道上.实现数据选择功能的逻辑电路称为数据选择器,它的作用相当于多个输入的单刀多掷开关.本例程以四选一数据选择器(电平触发)为例. 四选一 ...

  9. Verilog 加法器和减法器(7)

    在计算机中浮点数 表示通常采用IEEE754规定的格式,具体参考以下文章. https://www.cnblogs.com/mikewolf2002/p/10095995.html 下面我们在Veri ...

随机推荐

  1. JS跨域请求之JSONP

    在项目开发中遇到跨域的问题,一般都是通过JSONP来解决的.但是JSONP到底是个什么东西呢,实现的原理又是什么呢.在项目的空闲时间可以好好的来研究一下了. JSONP的产生 1.众所周知,Ajax请 ...

  2. JS的作用域和作用域链

    每个函数都有自己的作用域,当执行流进入一个函数时,函数就会被推入栈中,而在函数执行之后,栈将其执行环境弹出,把控制权放回给之前的作用域,全局作用域是最外围的一个作用域,因此,所有全局变量和函数都是作为 ...

  3. css单位rem---移动端至宝

    1.rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位.简单的说它就是一个相对单位.看到rem大 家一定会想起em单位em(font  ...

  4. C库专题(Day1)

    <assert.h> C库宏-assert()   定义:#define assert(ignore) ((void)0) void assert(int experession); ex ...

  5. arcmap从excel坐标数据生成点shp文件

    概述 今天试图在ArcMap中将excel数据转成点文件,在"Display XY Data"的时候,无法选择X,Y字段,很是纳闷,原来Excel中列的格式是文本,导致无法选择.有 ...

  6. MySQL sql 执行步骤

    基本步骤是  1.from  2.join on  3.where  4.group by  5.having  6.order by  7.select  8.distinct ,sum,...  ...

  7. C#中对Excel进行操作

    工作中要处理一批数据,主要是处理从别处导出来的Excel表格(大概有一千多行,三十多列),拿到表格对Excel表格进行分析,按照一定的规则进行拆分成为一万多行的数据:首先这个需求要用程序进行处理的背景 ...

  8. C++ Primer 5th 第1章 开始

    *****代码在Ubuntu g++ 5.31 / clang++ 3.8(C++11)下编写调试***** 每个C++程序必须有一个main( )函数,main( )函数的返回值也必须是int类型, ...

  9. JqueryUI插件网络连接

    operamasks_UI官网 http://ui.operamasks.org/website/homepage.html EasyUI官网 http://www.jeasyui.com/index ...

  10. spi ssp

    SSP(Synchronous Serial Port 同步串行口)某些微处理器所含有的一个通信模块(或支持的通信模式),用来和外围串行部件或其他微处理器进行通信,这些外围部件可以是串行E2PROM. ...