0

我正在尝试按如下方式实现乘以 15。

module mul15( 
output [10:0] result, 
input [3:0] a
 ); 
assign result =   a*15;
 endmodule

但是是否有任何改进的方法可以将 a 乘以 15?

我认为有两种这样的方式

1.结果 = a<<4 -1;

2.结果 = {a,3'b1111_1111};

Ans 我认为最好的方法是 2。但我也不确定综合方面。

更新:

如果我在 {a,3'b1111_1111} 处乘以 0 怎么办?这是 255 而不是 0。

有谁知道最好的方法?

更新这种方式怎么样?

情况1

结果 = {a,8'b0}+ {a,7'b0}+ {a,6'b0}+ {a,5'b0}+ {a,4'b0}+ {a,7'b0}+ {a,3'b0}+ {a,2'b0}+ {a,1'b0}+ a; 但它看起来使用了 8 个加法器。

案例2

结果 = a<<8 -1

我不确定其他最好的方法是什么。

4

2 回答 2

3

总是有的a*16 - a。2的幂的静态乘法在硬件上基本是免费的;它只是将 0 硬编码到 LSB。所以你只需要一个 11 位全减法器,它是一个全加器和一些反相器。

其他形式:

result = a<<4 - a;
result = {a,4'b0} - a; // unsigned full-subtractor
result = {a,4'b0} + ~a + 1'b1; // unsigned full-adder w/ carry in, 2's complement
result = {{3{a[3]}},a,4'b0} + ~{ {7{a[3]}}, a} + 1'b1; // signed full-adder w/ carry in, 2's complement
于 2015-02-11T00:46:21.203 回答
2

最干净的 RTL 版本如您在问题中所述:

module mul15( 
  input      [3:0] a
  output reg [7:0] result, 
); 
  always @* begin
    result = a * 4'd15;
  end
endmodule

二进制的被乘数 15 是 4'b1111;即 8 + 4 + 2 + 1。

它可以分解为这些 2 的幂的总和,而不是乘数。2 的幂只是桶形移位。这就是移位和加法乘数的工作方式。

module mul15( 
  input      [3:0] a
  output reg [7:0] result, 
); 
  always @* begin
    //        8        4        2       1 =>15
    result = (a<<3) + (a<<2) + (a<<1) + a;
  end
endmodule

为了最大限度地减少所需的加法器数量,可以使用CSD 。16-1 中的 15:

module mul15( 
  input      [3:0] a
  output reg [7:0] result, 
); 
  always @* begin
    //        16    - 1 =>15
    result = (a<<4) - a;
  end
endmodule

使用现代综合工具,这些都应该产生相同的结果。因此,拥有更易读的代码可以清楚地说明工具的意图,使其可以根据需要自由优化。

于 2015-02-11T00:44:42.023 回答