0

私は次のように15倍するように実装しようとしています。

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

しかし、a を 15 倍するための改善方法はありますか?

このように2通りあると思います

1.result = a<<4 -1;

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

回答 2が一番いい方法だと思いますが、合成の面もよくわかりません。

アップデート:

{a,3'b1111_1111} で 0 を乗算するとどうなりますか? これは 0 ではなく 255 です。

誰かが最善の方法を知っていますか?

更新 この方法はどうですか?

ケース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

結果 = <<8 -1

他に何が最善の方法なのかわかりません。

4

2 に答える 2

3

常にあります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
于 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 に答える