博主最近在学习加法器乘法等等相关知识,在学习乘法器booth编码加Wallace树压缩时,发现在压缩部分积的时候用到了进位保留加法器(Carry Save Adder),博主对这种加法器不是很理解,而且拖了好久,我一直认为进位保留加法器就是一般的串行加法器,今天终于有所理解,在这里给大家分享一下。

  首先,我们举个例子,对于四位无符号数1011与1110相乘,我们可以得到如下式子:

          1  0  1  1
x 1 1 1 0
------------------------------
0 0 0 0 PP1
1 0 1 1 PP2
1 0 1 1 PP3
1 0 1 1 PP4
------------------------------
  乘积项中间结果有4个:PP1、PP2、PP3、PP4。由于进位保存加法器只能进行三个数的相加,因而可采用两个进位保存加法器实现。第一个进位保存加法器实现PP1、PP2、PP3的加法,第二个进位保存加法器将PP3和上一级的S和C相加。最终通过一个并行加法器输出积。计算过程如下:
第一个进位保存加法器
PP1: 0 0 0 0
PP2: 1 0 1 1 0
PP3: 1 0 1 1 0 0
---------------------------------------
sum1 1 1 1 0 1 0
c1 0 0 0 1 0 0
第二个进位保存加法器
carry_in: 1 0 1 1 0 0 0
sum1 0 1 1 1 0 1 0
c1 0 0 0 1 0 0 0
---------------------------------------
sum2: 1 1 0 1 0 1 0
c2: 0 0 1 1 0 0 0
并行加法器:
sum2: 1 1 0 1 0 1 0
c2: 0 1 1 0 0 0 0
---------------------------------------
result 1 0 0 1 1 0 1 0   我们注意到,在参与下一级运算的过程中,由于进位要用于高位的求和,故c1,c2均应左移一位求。算出来的结果为:10011010(154)。
所谓“进位保留”,便是进位不进上去,只在本位之间计算。
基于Wallace树的4位乘法器实现Verilog代码如下所示:

module wallace_multiplier(
input [3:0] a,
input [3:0] b,
output [7:0] result
);


wire [7:0] pp1;
wire [7:0] pp2;
wire [7:0] pp3;
wire [7:0] pp4;


wire [7:0] sum1;
wire [7:0] carry1;
wire [7:0] sum2;
wire [7:0] carry2;


assign pp1 = b[0] ? a : 'd0;
assign pp2 = b[1] ? a : 'd0;
assign pp3 = b[2] ? a : 'd0;
assign pp4 = b[3] ? a : 'd0;


assign result = sum2 + (carry2 << 1);


carry_save_adder u1_carry_save_adder(
pp1 ,
pp2 << 1'b1,
pp3 << 2'd2,
sum1 ,
carry1
);


carry_save_adder u2_carry_save_adder(
pp4 << 2'd3 ,
sum1 ,
carry1 << 1'b1,
sum2 ,
carry2
);
endmodule


module carry_save_adder
#(
parameter DATA_WIDTH = 7
)
(
input [DATA_WIDTH:0] a,
input [DATA_WIDTH:0] b,
input [DATA_WIDTH:0] cin,
output [DATA_WIDTH:0] sum,
output [DATA_WIDTH:0] cout
);


assign sum = a ^ b ^ cin;
assign cout = a & b | (a | b) & cin;


endmodule

testbench:

`timescale 1ns / 1ns

module wallace_multiplier_tb();

reg [3:0] a;
reg [3:0] b;
wire[7:0] result;

wallace_multiplier u_wallace_multiplier(
.a (a ),
.b (b ),
.result (result )
);

initial begin
a = 4'b0010;
b = 4'b0110;
#10;
a = 4'b0001;
b = 4'b1000;
#10;
a = 4'b1010;
b = 4'b0111;
#10;
a = 4'b1110;
b = 4'b0010;
#10;
a = 4'b1111;
b = 4'b1111;
#10;
a = 4'b0110;
b = 4'b1001;
end

endmodule

  仿真结果如下图:

  以上就是Wallace树型4位乘法器的实现了,我认为关键在于进位保留加法器(Carry Save Adder)的理解,希望能给大家带来帮助。  

 


最新文章

  1. to_string()的应用
  2. javascript实现列表的点击展开折叠
  3. Echarts3
  4. 收集Github上的iOS控件和开发资料
  5. 第五百八十六天至第六百零五天 how ccan I 坚持
  6. ifstream,fstream 读写文件问题,read读取字节不够
  7. Python 提取Twitter转发推文的元素(比方username)
  8. list-列表功能介绍
  9. tomcat-users.xml配置Manager登陆用户
  10. 【Beta】 第四次Daily Scrum Meeting
  11. 图像检索(5):基于OpenCV实现小型的图像数据库检索
  12. Springboot-001-解决nested exception is org.apache.ibatis.binding.BindingException: Parameter &#39;env&#39; not found. Available parameters are [arg1, arg0, param1, param2]
  13. 1; XHTML 基本知识
  14. docker-compose 案例
  15. hide server info
  16. 算法之LOWB三人组之插入排序
  17. easyui datagrid 单元格编辑(cell editing)
  18. 深入理解SVG坐标体系和transformations- viewport, viewBox,preserveAspectRatio
  19. npm i --save-dev prettier安装警告saveError enoent
  20. MyBait 符号大于 小于理解

热门文章

  1. php封装协议的两道题
  2. android studio学习----创建模拟器
  3. 使用Hybris的customer coupon进行促销活动(promotion)
  4. Kubernetes学习之pause容器
  5. 【前端_js】jQuery动态设置元素的样式
  6. Shell 编程 数组
  7. Alipay 支付类
  8. Git问题
  9. 使用Psi Probe监控Tomcat8.5
  10. PHP 多个字段自增或者自减