改进的摊位乘法算法
Modified booth multiplication algorithm
我使用ModelSim 来模拟摊位倍增。我有这段代码,但是当 b = 5
时它是真的,当我为 b
提供其他数字时,结果就像这样=65563.
我尝试了签名和未签名,但结果是错误的。
我只是困惑哪里有问题。
module multiply(p,a,b,clock);
output [15:0] p;
input [7:0] a,b;
input clock;
reg [15:0] p,ans;
integer i;
integer operate;
initial
begin
p=16'b0;
ans=16'b0;
end
always @(negedge clock)
begin
p=16'b0;
for(i=1;i<=7;i=i+2)
begin
if(i==1)
operate=b[0]-b[1]-b[1];
else
operate=b[i-1]-b[i-2]-b[i]-b[i];
case(operate)
1:
begin
ans=a;
ans=ans<<(i-1);
p=p+ans;
end
2:
begin
ans=a<<1;
ans=ans<<(i-1);
p=p+ans;
end
-1:
begin
ans=~a+1;
ans=ans<<(i-1);
p=p+ans;
end
-2:
begin
ans=a<<1;
ans=~ans+1;
ans=ans<<(i-1);
p=p+ans;
end
endcase
end
end
endmodule
我认为你的方法有问题 - 我 运行 对你的代码进行了以下测试,a
和 b
循环了 1-9。我建议试一试:
module tb();
reg clk;
reg [7:0]a;
reg [7:0]b;
wire [15:0] p;
integer i,j,k;
multiply inst (p,a,b,clk);
initial clk = 0;
always #5 clk=~clk;
initial
begin
a=0;
b=0;
for (j=1; j<10; j=j+1)
for (k=1; k<10; k=k+1)
begin
a=j;
b=k;
#20 $display("%d * %d = %d", a, b, p);
end
end
endmodule
结果如下:
1 * 1 = 1
1 * 2 = 65530
1 * 3 = 65531
1 * 4 = 4
1 * 5 = 5
1 * 6 = 65534
1 * 7 = 65535
1 * 8 = 65512
1 * 9 = 65513
2 * 1 = 2
2 * 2 = 65524
2 * 3 = 65526
2 * 4 = 8
2 * 5 = 10
2 * 6 = 65532
2 * 7 = 65534
2 * 8 = 65488
2 * 9 = 65490
...
我不确定每个 case
选项的目的是什么,但是当使用 operate=-1
或 -2
b运行ches 时,值不正确。在那里仔细检查你的逻辑。
此外,operate
的值永远不能为 2(您的 case
选项之一),并且可能有值 -3(例如 b=10
),这你还没有涵盖。
使用此修改后的工作代码和测试台评估模块。
module MBA_module(p,a,b,clock);
output [15:0] p;
input [7:0] a, b;
input clock;
reg [15:0] p,ans;
integer i, lookup_tbl;
integer operate;
initial
begin
p=16'b0;
ans=16'b0;
end
always @(negedge clock)
begin
p=16'b0;
for(i=1;i<=7;i=i+2)
begin
if(i==1)
lookup_tbl = 0;
else
lookup_tbl = b[i-2];
lookup_tbl = lookup_tbl + 4*b[i] + 2*b[i-1];
if(lookup_tbl == 0 || lookup_tbl == 7)
operate = 0;
else if(lookup_tbl == 3 || lookup_tbl == 4)
operate = 2;
else
operate = 1;
if(b[i] == 1)
operate = -1*operate;
case(operate)
1:
begin
ans=a;
ans=ans<<(i-1);
p=p+ans;
end
2:
begin
ans=a<<1;
ans=ans<<(i-1);
p=p+ans;
end
-1:
begin
ans=~a+1;
ans=ans<<(i-1);
p=p+ans;
end
-2:
begin
ans=a<<1;
ans=~ans+1;
ans=ans<<(i-1);
p=p+ans;
end
endcase
end
end
endmodule
下面是测试平台
module MBA_mod_tb;
// Inputs
reg [7:0] a;
reg [7:0] b;
reg clock;
// Outputs
wire [15:0] p;
// Variables
integer j,k;
// Instantiate the Unit Under Test (UUT)
MBA_module uut (
.p(p),
.a(a),
.b(b),
.clock(clock)
);
initial clock = 0;
always #5 clock = ~clock;
initial
begin
a=0;
b=0;
for (j=1; j<10; j=j+1)
for (k=1; k<11; k=k+1)
begin
a=j;
b=k;
#20 $display("%d * %d = %d", a, b, p);
end
end
endmodule
我使用ModelSim 来模拟摊位倍增。我有这段代码,但是当 b = 5
时它是真的,当我为 b
提供其他数字时,结果就像这样=65563.
我尝试了签名和未签名,但结果是错误的。
我只是困惑哪里有问题。
module multiply(p,a,b,clock);
output [15:0] p;
input [7:0] a,b;
input clock;
reg [15:0] p,ans;
integer i;
integer operate;
initial
begin
p=16'b0;
ans=16'b0;
end
always @(negedge clock)
begin
p=16'b0;
for(i=1;i<=7;i=i+2)
begin
if(i==1)
operate=b[0]-b[1]-b[1];
else
operate=b[i-1]-b[i-2]-b[i]-b[i];
case(operate)
1:
begin
ans=a;
ans=ans<<(i-1);
p=p+ans;
end
2:
begin
ans=a<<1;
ans=ans<<(i-1);
p=p+ans;
end
-1:
begin
ans=~a+1;
ans=ans<<(i-1);
p=p+ans;
end
-2:
begin
ans=a<<1;
ans=~ans+1;
ans=ans<<(i-1);
p=p+ans;
end
endcase
end
end
endmodule
我认为你的方法有问题 - 我 运行 对你的代码进行了以下测试,a
和 b
循环了 1-9。我建议试一试:
module tb();
reg clk;
reg [7:0]a;
reg [7:0]b;
wire [15:0] p;
integer i,j,k;
multiply inst (p,a,b,clk);
initial clk = 0;
always #5 clk=~clk;
initial
begin
a=0;
b=0;
for (j=1; j<10; j=j+1)
for (k=1; k<10; k=k+1)
begin
a=j;
b=k;
#20 $display("%d * %d = %d", a, b, p);
end
end
endmodule
结果如下:
1 * 1 = 1
1 * 2 = 65530
1 * 3 = 65531
1 * 4 = 4
1 * 5 = 5
1 * 6 = 65534
1 * 7 = 65535
1 * 8 = 65512
1 * 9 = 65513
2 * 1 = 2
2 * 2 = 65524
2 * 3 = 65526
2 * 4 = 8
2 * 5 = 10
2 * 6 = 65532
2 * 7 = 65534
2 * 8 = 65488
2 * 9 = 65490
...
我不确定每个 case
选项的目的是什么,但是当使用 operate=-1
或 -2
b运行ches 时,值不正确。在那里仔细检查你的逻辑。
此外,operate
的值永远不能为 2(您的 case
选项之一),并且可能有值 -3(例如 b=10
),这你还没有涵盖。
使用此修改后的工作代码和测试台评估模块。
module MBA_module(p,a,b,clock);
output [15:0] p;
input [7:0] a, b;
input clock;
reg [15:0] p,ans;
integer i, lookup_tbl;
integer operate;
initial
begin
p=16'b0;
ans=16'b0;
end
always @(negedge clock)
begin
p=16'b0;
for(i=1;i<=7;i=i+2)
begin
if(i==1)
lookup_tbl = 0;
else
lookup_tbl = b[i-2];
lookup_tbl = lookup_tbl + 4*b[i] + 2*b[i-1];
if(lookup_tbl == 0 || lookup_tbl == 7)
operate = 0;
else if(lookup_tbl == 3 || lookup_tbl == 4)
operate = 2;
else
operate = 1;
if(b[i] == 1)
operate = -1*operate;
case(operate)
1:
begin
ans=a;
ans=ans<<(i-1);
p=p+ans;
end
2:
begin
ans=a<<1;
ans=ans<<(i-1);
p=p+ans;
end
-1:
begin
ans=~a+1;
ans=ans<<(i-1);
p=p+ans;
end
-2:
begin
ans=a<<1;
ans=~ans+1;
ans=ans<<(i-1);
p=p+ans;
end
endcase
end
end
endmodule
下面是测试平台
module MBA_mod_tb;
// Inputs
reg [7:0] a;
reg [7:0] b;
reg clock;
// Outputs
wire [15:0] p;
// Variables
integer j,k;
// Instantiate the Unit Under Test (UUT)
MBA_module uut (
.p(p),
.a(a),
.b(b),
.clock(clock)
);
initial clock = 0;
always #5 clock = ~clock;
initial
begin
a=0;
b=0;
for (j=1; j<10; j=j+1)
for (k=1; k<11; k=k+1)
begin
a=j;
b=k;
#20 $display("%d * %d = %d", a, b, p);
end
end
endmodule