改进的摊位乘法算法

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

我认为你的方法有问题 - 我 运行 对你的代码进行了以下测试,ab 循环了 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