加法器

在電子學中，加法器（adder）是一種用於執行加法運算的數位電路部件，是構成電子計算機核心微處理器中算術邏輯單元的基礎。在這些電子系統中，加法器主要負責計算地址、索引等數據。除此之外，加法器也是其他一些硬體，例如二進位數的乘法器的重要組成部分。

儘管可以為不同計數系統設計專門的加法器，但是由於數位電路通常以二進位為基礎，因此二進位加法器在實際應用中最為普遍。在數字電路中，二進位數的減法可以通過加一個負數來間接完成。為了使負數的計算能夠直接用加法器來完成，計算中的負數可以使用二補數（補碼）來表示，具體的細節可以參考數位電路相關的書籍。

## 半加器

<image>

（half adder）的功能是將兩個一位二進位數相加。它有兩個輸出：

- 和：記作 S，來自對應的英語 Sum。
- 進位：記作 C，來自對應的英語 Carry一位的數字。因此，這兩個一位二進位數的和用十進位表示即等於2C + S。右圖是一個最簡單的半加器設計，使用一個異或門來產生 S，一個與門來產生 C。和 S 的布爾邏輯是 A'B+AB，進位 C 的布爾邏輯是 AB。如果再添加一個或門處理兩個半加器的進位信號，就構成了一個全加器。

半加器將兩個輸入位加和，產生進位與和，是半加器的兩個輸出。半加器的輸入變量叫做被加數或被加位。輸出變量為和與進位。

半加器的真值表如下：

輸入｜輸出

A｜B｜C｜S

0｜0｜0｜0

1｜0｜0｜1

0｜1｜0｜1

1｜1｜1｜0

## 全加器

<image>

全加器（full adder）將兩個一位二進位數相加，並根據接收到的低位進位信號，輸出和、進位輸出。全加器的三個輸入信號為兩個加數A、B和低位進位Cin。全加器通常可以通過級聯（cascade）的方式，構成多位（如8位、16位、32位）二進位數加法器的基本部分。全加器的輸出和半加器類似，包括向高位的進位信號Cout和本位的和信號S，相加結果的總和用十進位表達為$\mathrm{sum} = 2 \times C_{out} + S$。一位全加器的真值表為：

<image>

輸入｜輸出

A｜B｜Cin｜Cout｜S

0｜0｜0｜0｜0

1｜0｜0｜0｜1

0｜1｜0｜0｜1

1｜1｜0｜1｜0

0｜0｜1｜0｜1

1｜0｜1｜1｜0

0｜1｜1｜1｜0

1｜1｜1｜1｜1

在實際的應用中，全加器可以通過不同的方式製造，例如直接利用電晶體級的電路，或者由其他現成的邏輯門來構成。和、進位信號對應的邏輯函數表達式分別為$S = A \oplus B \oplus C_{in}$以及$C_{out} = (A \cdot B) + (B \cdot C) + (A \cdot C)$。另一種全加器電路與之前的方式略有不同，它用一個異或門來代替或門對其中兩個輸入信號進行求和，其進位信號對應的邏輯函數表達式分別為$C_{out} = (A \cdot B) + (C_{in} \cdot (A \oplus B))$。通過適當的邏輯函數變化，可以證明它與前面的計算方法結果一致。

在這個實現中，將最後的或門換成異或門不會影響邏輯。如果電路使用的是每個晶片上只有一種閘的簡單積體電路晶片，僅使用兩種閘會比較方便。

全加器可以用兩個半加器來構造，將輸入端A和B連接到一個半加器上，然後將其和輸出信號與進位輸入信號分別作為第二個半加器的兩個輸入，並將兩個進位輸出信號進行邏輯或運算。全加器的關鍵路徑（critical path，即經歷最多邏輯門的路徑）經過兩個異或門，終止於和位 $s$。假定異或門耗費3個延遲來完成，一個全加器的關鍵路徑上施加的延遲等於

$$T_{FA} = 2 \cdot T_{XOR} = 2 \cdot 3 D = 6 D$$

進位模塊(carry-block)包括2個邏輯門，因此延遲為

$$T_c = 2 D$$

全加器還可以使用一個三輸入的異或門來求和，再使用一個兩級與或結構來實現進位信號對應的積之和（sum of products）式。

## 多位加法器

### 波紋進位加法器（脈動進位加法器）

<image>

可以使用多個一位全加器來構成N位加法器，其中對應低位的全加器將其進位輸出信號Cout連接到高一位的全加器的進入輸入端Cin。這種構成多位加法器的形式被稱為「波紋進位加法器」或「脈動進位加法器」（ripple-carry adder），「波紋」形象地描述了進位信號依次向前傳遞的情形。如果不需要連接其他進位信號，則最低位的全加器可以用半加器替換。

波紋進位加法器的電路布局形式較為簡單，設計這種電路花費時間較短。然而，波紋進位加法器的進位輸出、輸入所經過的路徑上比其他布局方式具有較多的邏輯閘，高位的計算必須等待低位的進位輸出信號被計算出來才能開始，因此造成了更大的延遲時間。

下面簡單計算信號在加法器中的延遲。每一個全加器具有三級邏輯函數。在一個32位的波紋進位加法器中，有32個全加器，隨之產生的邏輯閘延遲則可以根據關鍵路徑的延遲時間來決定，即2倍的最高位全加器輸入信號、進位輸出延遲，加上31乘以3倍的其他全加器上的延遲，總共等於95倍的邏輯閘延遲。一個 n 位波紋進位加法器的最壞情形延遲方程為

$$T_{CRA}(n) = T_{HA} + (n-1) \cdot T_c + T_s = T_{FA} + (n-1) \cdot T_c = 6 D + (n-1) \cdot 2 D = (n+2) \cdot 2 D$$

從位位置0到進位輸出的進位有一點不同：

$$T_{CRA_{[0:c_{out}]}} = T_{HA} + n \cdot T_c = 3 D + n \cdot 2 D$$

輸入進位必須經過 n 個進位生成器模塊來得到進位輸出的效果

$$T_{CRA_{[c_0:c_n]}}(n) = n \cdot T_c = n \cdot 2 D$$

交替進位極性和優化的與或非門的設計可以減少一半的延遲時間。

### 超前進位加法器

<image>

為了減少多位二進位數加減計算所需的時間，工程師設計了一種比脈動進位加法器速度更快的加法器電路，這種加法器被稱為「超前進位加法器」（carry-lookahead adder）。

下面簡述超前進位加法器的主要原理。我們先來考慮構成多位加法器的單個全加器從其低一位獲得的進位信號$c_{i+1} = (x_i \cdot y_i) + (x_i \cdot c_i) + (y_i \cdot c_i)$，我們可以將它變換為$c_{i+1} = (x_i \cdot y_i) + ( x_i + y_i ) \cdot c_i$。現在為二進位數的每一位構建兩個新信號：

- 生成（Generate）信號：$G_i = x_i \cdot y_i$
- 傳輸（Propagate）信號：$P_i = x_i + y_i$

於是，某位全加器從低一位獲得的進位可以表示為$c_{i+1} = G_i + P_i \cdot c_i$，例如次低位全加器從最低位獲得的進位為$c_1 = G_0 + P_0 \cdot c_0$，而從最低位開始第三位的那個全加器獲得的進位信號則為$c_2 = G_1 + P_1 \cdot c_1$。在多位脈動進位加法器中，$c_2$必須連接到低一位的進位輸出信號，如果使用這種方式構成多位全加器，則邏輯門的延遲會發生累加，導致降低電路的計算效率下降。超前進位加法器採取的方式是，將$c_1$的邏輯函數代入到$c_2$，即$c_2 = G_1 + P_1 \cdot ( G_0 + P_0 \cdot c_0 )$，於是，這一位的進位輸出就只取決於$x_1$、$y_1$、$x_0$、$y_0$、$c_0$幾個信號，而這幾個信號都是計算電路外部的已知信號，而非低一位的計算結果。上面考慮的是從最低位開始第三位的情況。採用類似的代入方法，可以用各位的生成信號$G_i$、傳輸信號$P_i$，以及最低位從外部獲取的進位信號$c_0$來表示多位全加器的所有進位信號。

<image>

通過列出多位加法器各位的進位輸出，可以發現高位的進位輸出表達式（積之和式）涉及的變量更多，對應的邏輯電路連線會變得更複雜，而且在實際應用中會遭遇邏輯門的扇入問題。因此有必要對位數過高的全加器進行邏輯劃分，如將六十四位全加器分為四個十六位超前進位加法器來實現（如右圖）。多位二進位數加法器的標準晶片通常具有超前進位的組成形式，例如:7400系列的7483、74283晶片。

## 延伸

- 全加器
- 半加器
- 減法器
- 波紋進位加法器
- 超前進位加法器

## 外部連結

- Hardware algorithms for arithmetic modules, includes description of several adder layouts with figures.
- 8-bit Full Adder and Subtractor, a demonstration of an interactive Full Adder built in JavaScript solely for learning purposes.