改进的展位乘法算法

时间:2015-06-27 08:01:35

标签: verilog computer-architecture

我使用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

2 个答案:

答案 0 :(得分:0)

我认为您的方法存在问题 - 我在您的代码上运行了以下测试平台,该代码对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分支时,值不正确。仔细检查你的逻辑。

此外,operate的值永远不会为2(您的case个选项之一),并且其值可能为-3(例如b=10),您可以使用#39; t覆盖。

答案 1 :(得分:0)

使用此Modified and Working代码和测试平台评估模块。

{{ csrf_token() }}

以下是测试平台

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