原创 【数字IC】高级数字 IC 设计(6)Booth 乘法器设计

2023-3-18 21:34 678 8 8 分类: FPGA/CPLD 文集: 数字IC

乘法器想必大家都知道是干什么用的,普通的乘法器的实现是基于乘法可以转换成加法这一事实。比如 3×4 实际上可以理解成 3 个 4 相加。

笔者翻遍资料发现主要就是如下的三种类型的乘法器:

    普通类型的乘法器:主要体现用加法计算乘法的思想,引入“乘法计算”这一概念。

    LUT乘法器:主要体现FPGA设计中用空间换时间的思想。

    Booth乘法器(包括ModifiedBooth乘法器):主要体现硬件设计中位操作的优良特性。

本文给大家分享一下Booth乘法器的代码部分。

 基 4 RTL 代码

Plaintext
`timescale 1ns / 1ps


module Mul_Booth(
clk,a,b,product
);
input clk;
input [7:0] a;
input [7:0] b;
output [15:0] product;


reg [3:0] Booth4,Booth3,Booth2,Booth1;
wire [15:0] product1,product2,product3,product4;
wire [7:0] fb;
wire [8:0] fbb;
/*-----------------//基4 Booth 编码表----------------*/
always @(posedge clk) begin
case(a[7:5])
3'b000:Booth4=0;//0
3'b001:Booth4=1;//1
3'b010:Booth4=1;//1
3'b011:Booth4=2;//2
3'b100:Booth4=4;//-2
3'b101:Booth4=3;//-1
3'b110:Booth4=3;//-1
default:Booth4=0;//0
endcase
end
always @(posedge clk) begin
case(a[5:3])
3'b000:Booth3=0;
3'b001:Booth3=1;
3'b010:Booth3=1;
3'b011:Booth3=2;
3'b100:Booth3=4;
3'b101:Booth3=3;
3'b110:Booth3=3;
default:Booth3=0;
endcase
end
always @(posedge clk) begin
case(a[3:1])
3'b000:Booth2=0;
3'b001:Booth2=1;
3'b010:Booth2=1;
3'b011:Booth2=2;
3'b100:Booth2=4;
3'b101:Booth2=3;
3'b110:Booth2=3;
default:Booth2=0;
endcase
end
always @(posedge clk) begin
case({a[1:0],1'b0})
3'b000:Booth1=0;
3'b001:Booth1=1;
3'b010:Booth1=1;
3'b011:Booth1=2;
3'b100:Booth1=4;
3'b101:Booth1=3;
3'b110:Booth1=3;
default:Booth1=0;
endcase
end
/*--------------------部分积相加--------------------*/
assign product=product1+(product2<<2)+(product3<<4)+(product4<<6);


BuFenJi p1(.clk(clk),.Booth(Booth1),.b(b),.product(product1),.fb(fb),.fbb(fbb));
BuFenJi p2(.clk(clk),.Booth(Booth2),.b(b),.product(product2),.fb(fb),.fbb(fbb));
BuFenJi p3(.clk(clk),.Booth(Booth3),.b(b),.product(product3),.fb(fb),.fbb(fbb));
BuFenJi p4(.clk(clk),.Booth(Booth4),.b(b),.product(product4),.fb(fb),.fbb(fbb));


endmodule

 

Plaintext
`timescale 1ns / 1ps


module BuFenJi(
clk,Booth,b,product,fb,fbb
);
input clk;
input [3:0] Booth;
input [7:0] b;
output reg [15:0] product;
output wire [7:0] fb;
output wire [8:0] fbb;
/*-----------------//针对基4 Booth 编码表操作----------------*/
always @(posedge clk) begin
case(Booth)
3'd0:product=16'b0;
3'd1:begin
if(b[7]) product={8'b11111111,b[7:0]};
else product={8'b00000000,b[7:0]};end
3'd2:begin
if(b[7]) product={7'b1111111,b[7:0],1'b0};
else product={7'b0000000,b,1'b0};end
3'd4:begin
if(!b[7]) product={7'b1111111,fbb[8:0]};
else product={7'b0000000,fbb[8:0]};end//-2
default:begin
if(!b[7]) product={8'b11111111,fb[7:0]};
else product={8'b00000000,fb[7:0]};end
endcase
end
/*-----------------对于-1、-2事先求反加1----------------*/
assign fb =(~b[7:0]+8'b00000001);
assign fbb=~{b[7:0],1'b0}+1'b1;


endmodule

基 2 RTL 代码

Plaintext
`timescale 1ns / 1ps


module Multi_Booth(
clk,rst,a,b,result
);
input clk;
input rst;
input [WIDTH-1:0] a,b;
output [2*WIDTH-1:0] result;
parameter WIDTH=4;
reg [WIDTH-1:0] temp1,temp2;
reg tempq,nd;
reg [3:0] i;
assign result={temp2,temp1};
always @(posedge clk or negedge rst) begin
if(!rst)begin
temp1<=a;temp2<=0;tempq<=0;nd<=0;i<=0;end
else begin
if(i
if(!nd)
case({temp1[0],tempq})
2'b01:begin temp2<=temp2+b;nd<=1;end
2'b10:begin temp2<=temp2-b;nd<=1;end
default:begin
{temp2,temp1,tempq}<={temp2[WIDTH-1],temp2,temp1};
i<=i+1;
end
endcase
else begin
{temp2,temp1,tempq}<={temp2[WIDTH-1],temp2,temp1};
nd<=0;
i<=i+1;
end
end
end
end
endmodule

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /3 下一条