從零構造一臺計算機——布林代數到邏輯電路

kaiux發表於2021-07-27

最近在學習coursera上的一門課:Build a Modern Computer from First Principles: From Nand to Tetris,我會堅持更新這一系列的部落格,作為記錄自己學習的過程,同時也倒逼自己去把學會的東西再講出來,來深入理解。

其實我們生活中所有的電子裝置都是基於邏輯閘電路(後面會解釋)來構造的。這是很神奇的一件事情,我在中學的時候就好奇計算機是如何完成這一些複雜的操作的,我相信很多人也都好奇過。這門課的願景就是帶我們從一個最基礎的電路開始,構造出一個完整的計算機。

布林代數

在數學和數理邏輯中,邏輯代數(有時也稱開關代數、布林代數)是代數的一個分支,其變數的值僅為真和假兩種真值(通常記作 1 和 0)。邏輯代數是喬治·布林(George Boole)在他的第一本書《邏輯的數學分析》(1847年)中引入的,並在他的《思想規律的研究》(1854年)中更充分的提出了邏輯代數。

這段話來自維基百科,布林其實是一個人名,因為布林代數就是他提出的,所以用他的名字來命名。這裡不會深入講解布林代數,我們只講我們用得到的部分。

還是以數學為例,數學中最基礎的四則運算是,同樣的,布林代數也有很多計算方式,最基礎的是應該是:

在開始講具體的計算之前,我們需要把前提記住:布林代數變數的值僅為真和假兩種真值(通常記作 1 和 0,真為1,假為0)。

因為布林代數變數的值僅為真和假兩種真值,所以我們其實可以把所有的情況都列出來,形成一張表,這張表就是我們平時所說的真值表

的真值表如下:

x y x與y
0 0 0
0 1 0
1 0 0
1 1 1

從上面也可以看出,對於\(n\)個變數的真值表,會有\(2^n\)種情況。

x與y其實就是當xy都是1的時候,結果為1,也就是xy都是真的時候,結果為真。

你也可以有你自己的理解方式,比如我們一開始學加法的時候,老師告訴我們1+1=2其實就是一個蘋果加一個蘋果等於2個蘋果。那麼x與y你也可以這麼理解:假如你想出去旅遊要徵詢爸爸媽媽的意見,x代表爸爸的意見,x=1代表爸爸同意,y代表媽媽的意見,y=1代表媽媽同意,為0則是不同意。那麼的意思就是,爸爸媽媽都同意了,才是通過。

我們平時表述x加y用符號+來表示:x+y;同樣的,也有它的符號:\(x\)\(y\) \(\Rightarrow\) \(x \cdot y\)

的真值表如下:

x y x或y
0 0 0
0 1 1
1 0 1
1 1 1

用上面的例子來說,就是爸爸媽媽同意了,就算是通過了。

同樣地,符號表示如下:\(x\)\(y\) \(\Rightarrow\) \(x + y\)

和上面的有點不一樣,真值表如下:

x 非x
0 1
1 0

其實就是對x去相反的值,從字面意思也可以理解。

符號表示如下:非\(x\) \(\Rightarrow\) \(\overline{x}\)

與非

與非的字面意思是運算和運算的結合。

與非的真值表如下:

x y x與非y
0 0 1
0 1 1
1 0 1
1 1 0

與非就是對計算出來的結果,再做計算。其符號表示如下:\(x\)與非\(y\) \(\Rightarrow\) \(\overline{x \cdot y}\)

這裡把與非單獨拿出來講,是因為在電路中,我們可以用一個與非元件,構造出其餘所有的元件。這樣我們只需要弄懂一個電路圖即可。我們這節課的主旨是搞明白,如何從用電路表達布林邏輯,至於電路的效率等方面,則是硬體工程師們考慮的內容了。其實學習就是這樣,我們需要抓住主線,明確目的。如果我們陷入布林邏輯或者電路圖的細節中不可自拔,那就是路走偏了。

邏輯電路

邏輯電路是指完成邏輯運算的電路。這種電路,一般有若干個輸入端和一個 或幾個輸出端,當輸入訊號之間滿足某一特定邏輯關係時,電路就開通,有輸 出;否則,電路就關閉,無輸出。所以,這種電路又叫邏輯閘電路,簡稱閘電路。

這段話來自百度百科,可能比較拗口,我們直接來看實現。

與非門

如圖所示,I1I2是輸入,NPN是一個三極體(當I1I2加電的時候,上下兩端連通),我們用1表示有電,用0表示沒電,那麼只有當I1I2都是1的時候,Output才是0。我們可以用真值表中的例子來驗證一下。

為了簡化表示,我們用如下的符號來表示與非門:

到這裡我們邁出了第一步,我們用一個物理上真實存在的電路圖,表示出了一種布林運算邏輯。那麼下面我們就用這個電路圖來構造其餘的電路圖。

非門

非門的實現如下:

也就是我們只需要在電路圖上把與非門的2個輸入連起來,就可以得到一個非門:這個時候與非門的2個輸入永遠都是相等的,當2個輸入都是1的時候,輸出為0,當2個輸入都是0的時候,輸出為1。

非門的符號如下所示:

與門

類似地,與門的實現如下:

符號表示如下:

或門

或門的實現如下:

符號表示如下:

回顧

這一節我們實現了用電路去表示基礎的閘電路。邁出了關鍵的一步,但是一直用畫圖的方式去表達電路也比較麻煩,下一節我們會簡單學習一門硬體描述語言(HDL:hardware description language)來表示電路的實現方式,一步一步去抽象,實現更多的元件。從而構造出一個完整的電腦。

再聊一個題外話:抽象。抽象是軟體工程師很重要的一個技能。在這裡,我們用或非門構造出了非門與門或門,那麼我們可以把構造的過程理解成一個抽象的過程,構造出的閘電路可以直接供我們使用,而不必每次去畫幾個或非門,然後把他們連起來。當然目前的閘電路比較簡單,我們的感知不是很強烈,如果我們構造了一個由幾十個或非門構造出的某門,那麼抽象就顯得尤為重要了。其實平時寫程式碼也是如此,我們應該把公用的部分,抽象出一個模組或者一個工具類。

相關文章