数値の符号を反転する 2 の補数では、通常、すべてのビットを否定して 1 を追加します。たとえば、次のようになります。
011 (3)
100 + 1 = 101 (-3)
VHDL では次のとおりです。
a <= std_logic_vector(unsigned(not(a)) + 1);
このように、シンセサイザーは N ビットの加算器を使用します。
加算器を使用せずに、別のより効率的なソリューションはありますか?
数値の符号を反転する 2 の補数では、通常、すべてのビットを否定して 1 を追加します。たとえば、次のようになります。
011 (3)
100 + 1 = 101 (-3)
VHDL では次のとおりです。
a <= std_logic_vector(unsigned(not(a)) + 1);
このように、シンセサイザーは N ビットの加算器を使用します。
加算器を使用せずに、別のより効率的なソリューションはありますか?
もっと簡単な方法はないと思いますが、加算器はおそらくあなたが思っているほど悪くはありません。
32 ビットの数値を反転しようとしている場合、合成ツールは 32 ビットの加算器構造で開始する可能性があります。ただし、B
入力が常に 1 に接続されていることを確認すると、未使用のゲート (1 つのピンがグランドに接続された AND ゲート、1 つのピンがロジック 1 に接続された OR ゲートなど) により、多くの構造が「くり抜かれる」可能性があります。 )。
したがって、残っているのは、入力数値をインクリメントするだけの合理的に効率的なロジックの塊になると思います。
2 の補数のビット パターンを作成しようとしているだけの場合は、単項-
も機能します。
a = 3'b001 ; // 1
b = -a ; //3'b111 -1
c = ~a + 1 ; //3'b111 -1
+
Tim はまた、単項 - を使用して or を暗示するという理由だけで、合成ツールがこれを自由に最適化できることを正しく指摘しました。
全加算器には 3 つの入力 (A、B、Carry_in) と 2 つの出力 (Sum Carry_out) があります。私たちの使用では、2 番目の入力は 1 ビット幅しかなく、LSB にはキャリーがないため、「全加算器」は必要ありません。
ここでは、2 つの入力 (A、B) と 2 つの出力 (サム キャリー) を持つ半加算器が最適です。
LSB の場合、半加算器 B 入力はハイになり、+1
. 残りのビット B 入力は、前のビットからキャリーを伝搬するために使用されます。
半加算器が必要であることを Verilog に書き込む方法を私が知っている方法はありませんが、任意のサイズの数値に 1 ビットを加えたものは、全加算器ではなく半加算器のみを必要とします。