booth乘法器 c语言,二进制乘法器的FPGA实现(常规和Booth乘法器)
二进制乘法器的主要操作就是加发法操作和移位操作。
我们知道计算机存储数据都是以二进制形式进行存储的,以4位数为例解释一下被乘数和乘数如何操作,首先把被乘数扩展成2倍的位宽,高4位为0,低4位为被乘数,结果为8为0,
先检测乘数的最低位,如果是1,则被乘数和结果想加,然后乘数右移,被乘数左移,如果是0,则被乘数左移,乘数右移。依次类推。
如下图:开始,product=00000000,Mcand=00000110,
Mer[0]==1,product==product+Mcand==00000110;Mer=0010,Mcand==00001100;
Mer[0]==0,Mer==0001,Mcand==00011000;
Mer[0]==1,product==product+Mcand==00011110;Mer=0000,Mcand==00110000;
Mer[0]==0,Mcand==01100000,Mer==0000;
end,product==00011110
代码入下:
module multiplier (clk,rst_n,multiplier,multiplicand,start,done,product);
input clk;//50M
input rst_n;
input [7:0]multiplier;
input [7:0]multiplicand;
input start;
output done;
output [15:0]product;
reg [2:0]i;
reg isdone;
reg [15:0]temp;
reg isneg;
reg [7:0]Mer;
reg [15:0]Mcand;
reg [2:0]cnt;
always @ (posedge clk or negedge rst_n)
if(!rst_n)
begin
i<=1'b0;
isdone<=1'b0;
temp<=16'd0;
Mer<=8'd0;
Mcand<=1'b0;
isneg<=1'b0;
cnt<=1'b0;
end
else if (start)
case
(i)
0:
begin i<=i+1'b1;
isneg<=multiplier[7]^multiplicand[7];
Mer<=multiplier[7]?(~multiplier+1'b1):multiplier;
Mcand<={multiplicand[7]?(~multiplicand+1'b1):multiplicand}&16'h00ff;
temp<=16'd0;
cnt<=1'b0;
end
1:
if(cnt==6)
i<=3'd3;
else if
(Mer[0]) begin temp<=temp+Mcand;
i<=i+1'b1;
end
else
i<=i+1'b1;
2: begin
Mer<=Mer>>1;
Mcand<=Mcand<<1;
i<=i-1'b1;
cnt<=cnt+1'b1;
end
3:begin isdone<=1'b1;
i<=i+1'b1;
end
4:begin isdone<=1'b0;
i<=1'b0;
end
default
:i<=3'b000;
endcase
assign done=isdone;
assign product=isneg?(~temp+1'b1):temp;
endmodule
加粗行用于执行加法操作,斜体部分用于执行移位操作。
测试代码:
`timescale 1 ns/ 1
ps
module multiplier_vlg_tst();
reg clk;
reg [7:0] multiplicand;
reg [7:0] multiplier;
reg rst_n;
reg start;
wire done;
wire [15:0] product;
multiplier i1 (
.clk(clk),
.done(done),
.multiplicand(multiplicand),
.multiplier(multiplier),
.product(product),
.rst_n(rst_n),
.start(start)
);
initial
begin
rst_n=0;
#30;
rst_n=1;
clk=1;
forever #10 clk=~clk;
end
reg [3:0]i;
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin i<=4'd0;
start<=1'b0;
multiplier<=8'd0;
multiplicand<=8'd0;
end
else
case(i)
0:
if (done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd2;
multiplicand<=8'd10;
start<=1'b1;
end
1:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd10;
multiplicand<=8'd2;
start<=1'b1;
end
2:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd20;
multiplicand<=8'd5;
start<=1'b1;
end
3:
if
(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd2;
multiplicand<=8'b11110110;
//-10
start<=1'b1;
end
4:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11111110;
//-2
multiplicand<=8'd10;
start<=1'b1;
end
5:
if
(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11110110;
//-10
multiplicand<=8'd2;
start<=1'b1;
end
6:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11111110;
//-2
multiplicand<=8'b11110110;
//-10
start<=1'b1;
end
7:
if (done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11110110;
//-10
multiplicand<=8'b11111110;
//-2
start<=1'b1;
end
8:i<=4'd8;
default:i<=4'd8;
endcase
endmodule
仿真结果:
结果看出:8位有符号的数,7位标志数的大小,一位符号位,所以每一位数据都要进行加和移操作耗2个时钟周期,共消耗2*7=14个时钟周期。所以无论8位多大的数都消耗14个时钟周期用于计算。
修改之后二进制乘法器
module multiplier
(clk,rst_n,multiplier,multiplicand,start,done,product);
input
clk;//50M
input rst_n;
input
[7:0]multiplier;
input [7:0]multiplicand;
input start;
output done;
output [15:0]product;
reg [1:0]i;
reg isdone;
reg [15:0]temp;
reg isneg;
reg [7:0]Mer;
reg [15:0]Mcand;
reg [2:0]cnt;
always @ (posedge clk or negedge rst_n)
if(!rst_n) begin
i<=1'b0;
isdone<=1'b0;
temp<=16'd0;
Mer<=8'd0;
Mcand<=1'b0;
isneg<=1'b0;
cnt<=1'b0;
end
else if (start)
case (i)
0:
begin
i<=i+1'b1;
isneg<=multiplier[7]^multiplicand[7];
Mer<=multiplier[7]?(~multiplier+1'b1):multiplier;
Mcand<={multiplicand[7]?(~multiplicand+1'b1):multiplicand}&16'h00ff;
temp<=16'd0;
cnt<=1'b0;
end
1:
if(cnt==6)
i<=2'd2;
else if
(Mer[0]) begin temp<=temp+Mcand;
Mer<=Mer>>1;
Mcand<=Mcand<<1;
cnt<=cnt+1'b1;
end
else
begin
Mer<=Mer>>1;
Mcand<=Mcand<<1;
cnt<=cnt+1'b1;
end
2:
begin
isdone<=1'b1;
55
i<=i+1'b1;
end
3:begin
isdone<=1'b0;
i<=1'b0;
end
default
:i<=2'b00;
endcase
assign done=isdone;
assign
product=isneg?(~temp+1'b1):temp;
endmodule
行把加法和移位放在一起。
测试代码无变化,如下:
`timescale 1 ns/ 1 ps
module multiplier_vlg_tst();
reg clk;
reg [7:0] multiplicand;
reg [7:0] multiplier;
reg rst_n;
reg start;
wire done;
wire [15:0] product;
multiplier i1 (
.clk(clk),
.done(done),
.multiplicand(multiplicand),
.multiplier(multiplier),
.product(product),
.rst_n(rst_n),
.start(start)
);
initial
begin
rst_n=0;
#30;
rst_n=1;
clk=1;
forever #10 clk=~clk;
end
reg [3:0]i;
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin i<=4'd0;
start<=1'b0;
multiplier<=8'd0;
multiplicand<=8'd0;
end
else
case(i)
0:
if (done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd2;
multiplicand<=8'd10;
start<=1'b1;
end
1:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd10;
multiplicand<=8'd2;
start<=1'b1;
end
2:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd20;
multiplicand<=8'd5;
start<=1'b1;
end
3:
if
(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'd2;
multiplicand<=8'b11110110;
//-10
start<=1'b1;
end
4:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11111110;
//-2
multiplicand<=8'd10;
start<=1'b1;
end
5:
if
(done)
begin
start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11110110;
//-10
multiplicand<=8'd2;
start<=1'b1;
end
6:
if
(done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11111110;
//-2
multiplicand<=8'b11110110;
//-10
start<=1'b1;
end
7:
if (done)
begin start<=1'b0;
i<=i+1'b1;
end
else
begin
multiplier<=8'b11110110;
//-10
multiplicand<=8'b11111110;
//-2
start<=1'b1;
end
8:i<=4'd8;
default:i<=4'd8;
endcase
endmodule
仿真结果:
从结果中可以看出只消耗了7个时钟周期用于计算,比前面的二进制加法器的用于计算消耗的时钟周期少了一倍。
Booth乘法器
它是对乘数重新编码,以减少乘法运算所需要的加法运算次数,他是只对乘数重新编码,而被乘数保持不变。得到的形式称为基4重新编码或比特对编码。使用booth乘法可以对两个数直接相乘,不需要考虑正数和负数。
具体操作:以8位为例
Product定义为17为用于保存结果,初始为product={8’b0,乘数,1’b0}
定义两个8位寄存器:A和B,A=被乘数,B=被乘数取反加1;
如果product最低两位为,01,product高8位加A,然后product右移一位;
如果product最低两位为10,product高8位加B,然后product右移一位;
如果product最低两位为11或00, product右移一位;
直到8位右移结束。
booth乘法器 c语言,二进制乘法器的FPGA实现(常规和Booth乘法器)相关推荐
- c语言4位二进制乘法器设计,四位二进制乘法器 c语言.doc
<四位二进制乘法器 c语言.doc>由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关<四位二进制乘法器 c语言.doc>文档请在天天文库搜索. 1.//四 ...
- vhdl语言入门_从当初汇编、C语言入手,到如今FPGA开发已然十年,总结出“三多”!...
从大学时代第一次接触FPGA至今已有10多年的时间,至今记得当初第一次在EDA实验平台上完成数字秒表.抢答器.密码锁等实验时那个兴奋劲.当时由于没有接触到HDL硬件描述语言,设计都是在MAX+plus ...
- 基于vivado(语言Verilog)的FPGA学习(3)——FPGA理论知识
基于vivado(语言Verilog)的FPGA学习(3)--FPGA理论知识 文章目录 基于vivado(语言Verilog)的FPGA学习(3)--FPGA理论知识 1. FPGA介绍 1.1.F ...
- C语言二进制转换为八进制(附完整源码)
C语言二进制转换为八进制 C语言二进制转换为八进制完整源码 C语言二进制转换为八进制完整源码 #include <stdio.h>// Function that returns the ...
- C语言二进制转换为十六进制(附完整源码)
C语言二进制转换为十六进制 C语言二进制转换为十六进制完整源码 C语言二进制转换为十六进制完整源码 #include <stdio.h>int main() {long int binar ...
- c语言二进制转十进制(附完整源码)
c语言二进制转十进制 c语言二进制转十进制完整源码 c语言二进制转十进制完整源码 #include <stdio.h>int main() {int remainder, number = ...
- C语言---二进制和文本文件的备份
C语言-二进制和文本文件的备份 学习参考: https://www.cnblogs.com/jackytang/p/9011127.html 代码: #include <stdio.h> ...
- c语言 二进制压缩算法_使用C ++解释的二进制搜索算法
c语言 二进制压缩算法 by Pablo E. Cortez 由Pablo E.Cortez 使用C ++解释的二进制搜索算法 (Binary Search Algorithms Explained ...
- C语言二进制求数集子集
C语言二进制求数集子集 题目:编写一个程序,对输入的正整数n,输出{0,1,-,n-1}的所有子集.例如,输入3时,输出如下: {}, {0}, {1}, {0,1}, {2}, {0,2}, {2, ...
最新文章
- 深入浅出聚类算法!如何对王者英雄聚类分析,探索英雄之间的秘密
- 使用C++基于Socket编程实现文件下载(改进-封装成类)
- 鸟哥的Linux私房菜10.16 vim程序编辑器
- SQLServer 2012 报表服务部署配置(1)
- scala------------:: , +:, :+, :::, +++的区别
- Handler延迟事件使用
- HttpURLConnection简单用法
- SpringMVC工作原理 1
- javascript 设计模式_用英雄联盟的方式讲解JavaScript设计模式(二)
- dlut-KFQ人工智能导论答案1
- 2014,都要好好的~
- 设计模式笔记之六:生产消费者模式
- 十分钟一起学会ResNet残差网络
- 安装SQL server 提示重新启动计算机失败
- 怎么查看ofd格式电子发票? 2种简单方法免费查看
- ARCGIS 给面文件“挖洞”——Erase的用法
- 计算机磁盘管理分盘可以撤销吗,电脑磁盘出现随便分盘不合理,怎么样重新分盘...
- 现在有哪些好用的企业报表软件?
- 摄像机码流平滑参数解析
- Linux攻关之基础模块十 特殊权限