乘以 15 的改进方法是什么?

What is the improve way to multiplying by 15?

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

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

但是有什么改进的方法可以将 a 乘以 15 吗?

我认为有两种方法是这样的

1.result = a<<4 -1;

2.result = {a,3'b1111_1111};

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

更新:

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

有谁知道最好的方法吗?

更新 这样怎么样?

案例一

结果 = {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

我不确定还有什么是最好的方法。

最干净的 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

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

总有a*16 - a。 2 的幂的静态乘法在硬件中基本上是免费的;它只是 LSB 的硬编码 0。所以你只需要一个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