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所示:
图6.Booth_multiplier _test的仿真波形
4.问题与思考
1)挑战题:同学们可能发现以上的设计的Booth乘法器消耗时钟太长,下面同学们采用流水线操作方式设计一个高速的Booth乘法器。
因篇幅问题不能全部显示,请点此查看更多更全内容