admin 管理员组

文章数量: 1086019


2023年12月17日发(作者:linux递归删除文件夹)

Booth乘法器设计

1. 实验目的

要求掌握Booth算法原理,并根据算法设计Booth乘法器模块以及设计test_bench,最后在Robei可视化仿真软件经行功能实现和仿真验证。

2.实验原理

1951年,A.D Booth在其论文“A Signed binary multiplication technique”中提出一种快速乘法算法,即Booth算法,是为了解决有符号乘法运算中复杂的符号修正问题而提出一种乘法算法。乘法器中若乘数为有符号数,扩展其最高位;若是无符号数,则做一位0扩展。

Booth算法的基础基于二进制数加法的特性,其基本思想为当x乘以一个二进制数时可以将乘数中连续的1序列变换为(2i-2j),其中i>j,然后利用二进制数乘法的特性等于将2i乘以x向左移i位,只需一个加法器和一个移位寄存器便可实现该段数据的(2i-2j)乘以x乘法运算,i>j,从而有效减少总体需要的加法运算次数。

假设乘数和被乘数均为n位,那么Booth算法的具体执行过程以下六个步骤:

(1) 设置一个2n+1位的p空间,并将初始化为0;

(2) 将乘数填入p[n:1]中;

(3) 从p空间的最低位依次开始向左扫描,每次扫描两位,并判断所扫描的两位二进制数为表1中的何种情况;

表1. Booth算法的加码操作

B[i]

0

0

1

1

B[i-1]

0

1

0

1

加码操作

0(无操作)

1(加被乘数)

1(减被乘数,即加被乘数的补码)

0(无操作)

(4) 判断p[2n]位,如果是逻辑0右移一位补0,如果是逻辑1就右移一位补1;

(5) 重复步骤(3)(4),循环n次;

(6) 最终p空间的p[2n:1]就是乘数和被乘数的乘积。

下图1显示Booth乘法器模块的设计:

start_sig

done_sig

Booth乘法器模块的设计

a[7:0]

Booth_multiplier

SI

b[7:0] product[15:0]

图1. Booth乘法器模块的设计

3.实验内容

3.1 Booth_multiplier模型设计

1) 新建一个模型命名为 Booth_multiplier,类型为 module,同时具备 5 输入 2 输出,每个引脚的属性和名称参照下图2经行对应的修改。

Name

clk

rst_n

start_sig

a

b

done_sig

product

Inout

input

input

input

input

input

output

output

DataType

wire

wire

wire

wire

wire

wire

wire

Datasize

1

1

1

8

8

1

16

clock

Function

negedge reset

start signal

multiplier a

multiplicand b

done signal

product

图2. Booth_multiplier引脚的属性

图3. Booth_multiplier界面图

2) 添加代码。点击模型下方的 Code添加代码。

代码:

/********************************/

reg[3:0] i;

reg[7:0] ra;

reg[7:0] rs;

reg[16:0] rp;

reg[3:0] x;

reg isdone;

always @(posedge clk or negedge rst_n)

if(!rst_n)

begin

i<=4'd0;

ra<=8'd0;

rs<=8'd0;

rp<=17'd0;

x<=4'd0;

isdone<=1'b0;

end

else if(start_sig)

case(i)

0:

begin

ra<=a;

rs<=(~a+1);

rp<={8'd0,b,1'b0};

i<=i+1;

end

1:

if(x==8)

begin

x<=4'd0;

i<=i+2;

end

else if(rp[1:0]==2'b01)

begin

rp<={rp[16:9]+ra,rp[8:0]};

i<=i+1;

end

else if(rp[1:0]==2'b10)

begin

rp<={rp[16:9]+rs,rp[8:0]};

i<=i+1;

end

else

i<=i+1;

2:

begin

rp<={rp[16],rp[16:1]};

x<=x+1;

i<=i-1;

end

3:

begin

isdone<=1'b1;

i<=i+1;

end

4:

begin

isdone<=1'b0;

i<=4'd0;

end

endcase

assign product=rp[16:1];

assign done_sig=isdone;

/********************************/

3) 保存模型到一个文件夹(文件夹路径不能有空格和中文)中,运行并检查有无错误输出。

3.2 Booth_multiplie_test测试文件的设计

1) 新建一个 5输入 2 输出的Booth_multiplie_test测试文件,记得将 Module Type 设置为

“testbench”,各个引脚配置如图4所示。

Name

clk

rst_n

start_sig

a

b

done_sig

product

Inout

input

input

input

input

input

output

output

DataType

reg

reg

reg

reg

reg

wire

wire

Datasize

1

1

1

8

8

1

16

Function

clock

negedge reset

start signal

multiplier a

multilcand b

done signal

product

图4. Booth_multiplie_test测试文件引脚的属性

2) 另存为测试文件。将测试文件保存到上面创建的模型所在的文件夹下。

3) 加入模型。 在 Toolbox 工具箱的 Current 栏里,会出现模型,单击该模型并在

Booth_multiplie _test上添加,并连接引脚,如下图5所示:

图5. Booth_multiplie _test界面图

4) 输入激励。点击测试模块下方的“Code”,输入激励算法。激励代码在结束

的时候要用$finish 结束。

测试代码:

/***********************************/

initial

begin

clk=1'b0;

rst_n=1'b1;

#10 rst_n=1'b0;

#100 rst_n=1'b1;

#10000 $finish;

end

always #10 clk=~clk;

reg[3:0] i;

always @(posedge clk or negedge rst_n)

if(!rst_n)

begin

i<=4'd0;

a<=8'd0;

b<=8'd0;

start_sig<=1'b0;

end

else

case(i)

0:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd1;

b<=8'd1;

start_sig<=1'b1;

end

1:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd2;

b<=8'd2;

start_sig<=1'b1;

end

2:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd3;

b<=8'd3;

start_sig<=1'b1;

end

3:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd4;

b<=8'd4;

start_sig<=1'b1;

end

4:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd5;

b<=8'd5;

start_sig<=1'b1;

end

5:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd6;

b<=8'd6;

start_sig<=1'b1;

end

6:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd7;

b<=8'd7;

start_sig<=1'b1;

end

7:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd8;

b<=8'd8;

start_sig<=1'b1;

end

8:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd7;

b<=8'd7;

start_sig<=1'b1;

end

9:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd8;

b<=8'd8;

start_sig<=1'b1;

end

10:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd9;

b<=8'd9;

start_sig<=1'b1;

end

11:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd10;

b<=8'd10;

start_sig<=1'b1;

end

12:

if(done_sig)

begin

start_sig<=1'b0;

i<=i+1;

end

else

begin

a<=8'd100;

b<=8'd100;

start_sig<=1'b1;

end

13:

begin

i<=4'd13;

end

endcase

/***********************************/

5) 执行仿真并查看波形。查看输出信息。检查没有错误之后查看波形。点击右侧 Workspace

中的信号,进行添加并查看分析仿真结果。如图6所示:

图_multiplier _test的仿真波形

4.问题与思考

1)挑战题:同学们可能发现以上的设计的Booth乘法器消耗时钟太长,下面同学们采用流水线操作方式设计一个高速的Booth乘法器。


本文标签: 算法 设计 乘法器