---
image: https://i.imgur.com/Me4F7TI.png
---
# 利用自製CPU的過程帶出原理與實作
[TOC]
利用自由資源,以「製作一顆cpu需要的知識」作為起點
不講多餘的東西,一步一步堆疊,最後把cpu實作出來
然後用幾個小專題驗證這個cpu的功能
有「專題導向」的意味
**這是一份發展中的筆記,意思就是想到什麼寫什麼**
## 0.前言
無論是學習歷程或是產業發展
都應該像金字塔
都需要底層的石塊推疊才能拱出塔頂的頂石
為什麼我希望推廣CPU的知識科普化?
首先,這是因為從我的「電學科普化」的精神延伸而來。因為我們現在身處的世界,電力已經無所不在,因此電學知識必須普及化。同樣,又因爲我們身處資訊時代,資訊設備無所不在,因此我們必須將資訊知識普及化。而此同時,由於自造者運動(Maker Movement)的緣故,原本只在工程師桌上出現的實驗電路,走入了基礎教育的殿堂。有時候因為成本的緣故,電路板並沒有太多的自我保護能力,因此損壞情形時有多聞,這往往是電學與資訊相關知識不足所致。如果大家都能花一點時間,將電學與資訊的知識藉由整理而精煉化後並吸收,相信也能少走很多冤枉路。(或許有試誤派會來戰😊)
資訊產品中,核心一定是CPU。不管這個CPU有時會是MCU或是MCP,但是核心一定是相似的結構。就程式設計者的角度來說,其實只需要知道CPU的模型就可以,例如指令集、暫存器等構成的抽象模型。但是由於前面提到的自造者運動,將MCU等單晶片也普及化了,而這些MCU的應用最主要就是用軟體控制硬體,因此程式設計者就變成不能只認識抽象模型,而是連硬體原理都必須有概念,這樣才能夠駕馭這些裝置。
拜現代技術進步所賜,設計一顆CPU已經是非常簡單的事情了。如果說可以從頭到尾設計一顆CPU,以解題導向的方式同時認識其原理,此時不玩更待何時?而我剛好以前有用CPLD設計過一顆自己的CPU作為畢業專題,我自己是覺得CPU一點也不難理解,並且經過這個專題過程讓我對於軟硬體整合更得心應手,因此我覺得可以來分享怎麼設計一顆CPU,相信可以幫助有興趣的朋友對CPU硬體運作更有慨念,也就能對於將來遇到的問題解答有所幫助。
對於章節安排的哲學,用一句話形容:「先見林再見樹」。雖然描述CPU這一個龐大概念還是需要一塊一塊基石慢慢堆疊,但是一開始如果能夠先以鳥瞰的方式見到全局,我覺得對於龐大系統的認知過程有幫助。
我不是學有專精,也不是獨到見解,更沒有堅實的學理基礎,我想做的這些事情,僅僅只是拋磚引玉。我相信能人志士比比皆是。但如果能有一點點貢獻讓需要的人收到,那就很滿足了。
## 1.從基本電學到數位電子學
透過線上電路模擬器 http://www.falstad.com/circuit/
### 1.1 電子實驗
幾個小玩意兒電路開場
#### 1.1.1 無穩態多諧振盪
電子電路的Hello World
#### 1.1.2 555IC
課本上或多或少都有聽過甚至玩過,維基百科甚至有條目!
#### 1.1.3 電晶體電路
電晶體是基本主動式元件
#### 1.1.4 運算放大器
運算放大器是一種類比IC
#### 1.1.5 數位電路
數位電路也大多IC化
所以IC不一定都是數位的
#### 1.1.6 繼電器電路
繼電器也可以是循序控制的基本元件
很久很久以前的電腦也有用繼電器做的
![](https://i.imgur.com/ieGJAc6.gif)
### 1.2 電路原理
電路像瀑布(能量由高流向低)、像水管系統(電子元件類比於管路元件)
電路理論相通於其他物理系統
#### 1.2.1 電壓
伽瓦尼發現青蛙腿生物電、伏打發明伏打堆、希貝克發現希貝克熱電效應
電壓又可稱電動勢(potential)在沒有電流流動之前,就有一股能量蓄積在一處,並且與另一處有能量差別,彼此之間就會形成電動勢,就會有電壓差。
#### 1.2.2 電流
厄斯特、安培
厄斯特發現載體電流會產生作用力於磁針之上。安培找到方程式描述這個現象。當兩處不同能量蓄積處之間搭上一個電導體,就會形成電流流動。早年還未知原子的結構,因此誤以為電流流動的方向是由正極流向負極。後來得之真正流動的是電子,而電子是從負極流向正極而形成電子流,但已經多年積非成是,而且電子流與電流僅僅是正負號的差別而已,除非場合特殊需要區別(例如真空管)否則就約定俗成,維持電流的定義。
#### 1.2.3 RLC
歐姆、亨利、法拉第
歐姆是理論基礎扎實的實驗科學家
亨利是美國史密森尼學會首任會長
法拉第是自學成才的皇家學會院士
#### 1.2.4 電晶體
從脈絡來說,在電晶體之前還有真空管,可是跟我們主題無關先不提
電晶體可以視為一種電子開關,有一種用電流來作動開關稱為BJT,另一種用電壓來做動開關MOSFET。電晶體有很多種類,這裡先提這兩種。
![](https://i.imgur.com/hblzEHW.gif)
### 1.3 電路圖識圖
常見電路圖元件、電路圖繪製原則
電路圖是用來描述電路零件之間的連接與紀錄注意事項,以便生產或維修之用,在電的世界,看得懂電路圖是基本要求。
常見元件就是電阻R電感L電容C
另外還有輔助性質的符號:電壓源與接地點
其次是電晶體與IC
電路圖秉持「左進右出」「上源下地」原則
### 1.4 數位邏輯
AND, OR, NOT邏輯閘、用電晶體實作邏輯閘、實驗幾個邏輯電路、組合邏輯與循序邏輯的概念
數位電路基本是由邏輯閘組成,邏輯閘是由電晶體組成,或者有更簡單的用二極體組成。邏輯閘是為了將數位邏輯的理論現實化而存在的。
常見的有AND、OR、NOT三種
AND閘,又稱「及閘」,其~~真值表~~特性為:「有1必為1」,意指當輸入之中無論多少,只要有一隻輸入為邏輯0,則輸出必為邏輯0。只有全部輸入皆為邏輯1,則輸出才會為邏輯1。
OR閘,又稱「或閘」,特性為「有1必為1」,意指輸入只要一隻為邏輯1則輸出必為邏輯1。
NOT又稱反閘,是將輸入邏輯「反相」,輸入邏輯0則輸出邏輯1,反之亦然。
三個邏輯閘單獨觀察時,很難明白他們的實際用途。因此數位電路經常都是這些基本元件的組合,才能構成有意義的應用,而CPU大概是邏輯閘們最雄偉的應用了。
~~正反器~~
克勞德夏儂 凡納爾布希 差分分析儀
布林
### 1.5 數字系統與運算
遇到了所以說一下。因為邏輯閘的運作是建立在二進位數字系統,所以必須補充二進位數字系統的觀念。
加減乘除可以濃縮成只有加法!!
邏輯也是一種運算
移位功能所需結構不多,但可以加速一些運算
## 2.從數位邏輯到CPU
本來想透過intel quartus lite做vhdl編譯與模擬(可看合成電路與波形)
候選替代方案:ghdl + gtkwave(只能看合成後波形,看不到合成的電路) [^first]
[^first]:https://pondahai.medium.com/ghdl-%E4%B8%80%E6%AC%BE%E9%96%8B%E6%BA%90%E7%9A%84vhdl%E6%A8%A1%E6%93%AC%E5%99%A8%E4%BB%A5%E5%8F%8Agtkwave-%E4%B8%80%E6%AC%BE%E9%96%8B%E6%BA%90%E7%9A%84%E6%B3%A2%E5%BD%A2%E8%A7%80%E5%AF%9F%E5%99%A8-%E4%B8%80%E5%80%8B%E4%BA%8C%E4%BD%8D%E5%85%83%E5%85%A8%E5%8A%A0%E6%B3%95%E5%99%A8%E7%9A%84%E5%AF%A6%E4%BD%9C-3d155644a871
後來伴伴學社團有朋友說logisim可以試試看
### 2.1 電腦
歷史、齒輪、馬達、繼電器、真空管、電晶體、IC、多晶片、單晶片
大家或許都知道從十八世紀織布機開始講,可是沒有說明為什麼要這樣做,以及當時時空環境下的限制
如何在有限資源下完成工作?還有就是如何協助人類從事反覆的工作?
目的是大量且避免人為錯誤。
巴斯卡(對就是那個pascal)發明巴斯卡計算器
巴貝奇與愛達~~
巴貝奇發明差分儀
愛達負責筆記與分析
愛達是共筆女王!
*愛達 拜倫 雪萊 瑪麗雪萊 科學怪人*
科學與浪漫那麼地近
我認為科學就是浪漫主義的具體作法
~~小等一下,雖然感覺那個年代很浪漫,先不要陷入貴古賤今的迷思~~
問:為什麼當時需要這一類機器?
大航海時代:日月星辰指引水手回家的方向
當兵學過三角定位法
羅盤\\
太陽/ ------ 航海定位 ------ 大航海時代
時鐘/
航海定位<-六分儀+日月星辰+航海天文曆<-計算員
歷史就像一條鏈,都有其脈絡
就像《新教倫理與資本主義精神》Die protestantische Ethik und der Geist des Kapitalismus, 馬克斯·韋伯在探討資本主義精神的由來一樣
牛頓與大航海時代之於現代科技也可以如是說
另外還有人口普查
稅務等等需求,引發人們發明機器來輔助計算
所謂的電腦,不僅僅只有數位的,也有類比的、機械的
安提基特拉機械(渾天儀?)
轟炸機投彈導航
youtube找關鍵字analog computer
提出訊息熵的克勞德。夏儂,他的老師萬尼瓦爾。布什就是曾研究機械式類比電腦
#### 小結
* 電腦是算術機器
* 計算機本質上是一種用來記錄數字,用數字運算並以數值形式給出結果的機器 取自:控制論,諾伯特維納
* 複雜的問題會拆解成個別的算術問題
* 指揮電腦執行算術問題並獲取結果
* 將個別結果統整最終呈現解答
* 用來指揮電腦運作的資料稱作機器碼
* 用文字來代表機器碼使人類易讀的程式語言稱作組合語言
* 組合語言的類別依功能分別為:搬移、算術與邏輯、條件判斷與分支以及其他
* 運用程式語言解決問題的過程稱作程式設計
### 2.2 CPU架構
計算機概論(電腦概論)中常見CPU方塊圖
從這個方塊圖出發,探討當中的每一個方塊
應該如何實作?
用問題導向思考來帶出CPU應該要有的功能
現代看到的架構是不斷迭代與歸納的結果(脈絡)
哈佛架構(馬克一號)
普林斯頓架構(馮紐曼)
這些CPU架構是歸納後的結果
研究CPU架構是為了高效率執行算術
電腦架構是硬體
缺乏可變性
程式設計可以調配這些硬體架構
把這些硬體視為一種資源
除了一次解決一道算術問題
甚至可以進一步考慮硬體在同一時間段中的閒置再利用
### 2.3 數位邏輯如何組出CPU架構
CPU的架構方塊,都是比較大的概念,用數位邏輯的基本元件需要一些組合才能構成CPU中的方塊。例如加法器、暫存器、栓鎖器、計數器。
* 邏輯閘
* 加法器、半加全加你家?
這些是組合邏輯
* 暫存器
* 栓鎖器
* 計數器
* 正反器(這是樹,以上是林)
這些是循序邏輯
一句話講完CPU動作
計數器控制組合邏輯產生循序信號控制栓鎖器把資料送進加法器產生結果後再被栓鎖器傳給暫存器,噠啦~CPU就完成啦!!
註:AI巴德幫我歸納:
> 計數器控制組合邏輯產生循序信號,控制栓鎖器把資料送進加法器計算,結果存入暫存器。
以下列程式為例,解釋程式運作過程
```python=
print (" * ")
print (" *** ")
print ("*****")
print (" * ")
print (" * ")
print (" *** ")
```
資料 * 字串(資料型別)放在資料記憶體或是資料區塊
程式print化成mov指令(編譯或是直譯)
把資料記憶體搬進cpu暫存
再把暫存器資料搬到外部「影像記憶體」
螢幕類比成一組二維記憶體區塊名為「影像記憶體」
影像記憶體有什麼資料,螢幕上就顯示什麼
#### 一定要透過CPU嗎?
直接把資料區塊的資料搬到影像記憶體也是可以
但那是一種特例作法,名為「直接記憶體存取(DMA)」
而且DMA也是要經過CPU的指令設定才會運作(無風不起浪)
### 2.4 開一個CPU規格:
?位元、單匯流排、位址匯流排、資料匯流排、通用輸出入
指令集:?
輔助電路:鍵盤、七段顯示器、蜂鳴器
介面:串列埠
### 2.5 設計與模擬
一個2位元上數計數器的展示,全由nmos構成
{%vimeo 563544569 %}
或用繼電器?
## 3.從電路圖到PCB
透過kicad
或用麵包版?
## 4.從工具到實作
透過雙手+$$
對於實作,似乎變成兩種方向
一是完完全全製作CPU,從底層無論是VHDL或是電晶體,甚至是繼電器。這個方法是確確實實理解CPU運作過程並且可以針對數位邏輯電路的實作,缺點是太過複雜,除錯不易,運作過程的觀察也不易。
另一種是硬體模擬(emulation)。利用現有MCU,以軟體的方式模擬出這個CPU應該會有的動作,然後也可以實際連接外部電路。這個方法可以非常簡化CPU的實作過程,容易除錯,也可以利用顯示裝置對運作過程加以顯示。
## 5.驗證
### 自走車?
### 音樂合成器?
### 遊戲機?
### BASIC直譯器?
---
~~hackmd 程式碼著色 沒有支援vhdl~~
20220324支援了!!感謝hackmd
```vhdl=
entity adder is
-- `i0`, `i1`, and the carry-in `ci` are inputs of the adder.
-- `s` is the sum output, `co` is the carry-out.
port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit);
end adder;
architecture rtl of adder is
begin
-- This full-adder architecture contains two concurrent assignments.
-- Compute the sum.
s <= i0 xor i1 xor ci;
-- Compute the carry.
co <= (i0 and i1) or (i0 and ci) or (i1 and ci);
end rtl;
```
## 6.想像圖
這個想像圖是想利用atmel mega32u4(arduino leonardo)
將cpu切開「控制單元」「算數邏輯單元」「暫存器庫」「程式記憶體」放在32u4裡面
透過arduino ide把cpu的機器碼寫在陣列變數裡面
其餘「輸出入(鍵盤與七段)」「GPIO」則是拉出來外部電路
同時轉換板上印上CPU結構,並且以LED燈做為內部動作指示燈
![想像圖](https://i.imgur.com/Me4F7TI.png)
第二種想像
![](https://i.imgur.com/Qqvp9Yw.png)
第三種想像(單一指令電腦)
![](https://i.imgur.com/XNW8uSN.png)
## 1980年代,西德電視節目中的紙質電腦
以「紙上談兵」方式向大眾介紹CPU中的指令運作原理
https://en.wikipedia.org/wiki/WDR_paper_computer
## 實體圖靈機
有人把當初寫在課本裡的想像圖靈機具象化(一部機器走在紙帶上)
https://hackaday.com/2016/07/12/a-very-modern-turing-machine-build/
## 一個新理解的架構:單一指令集電腦
這是在一次網路衝浪中(好像是hackaday的網站先看到一篇講實體圖靈機)發現的,這種電腦架構的指令集只有一個指令,但可以做到圖靈完備
或許,可以先從這個架構開始,用ttl實現?
https://en.wikipedia.org/wiki/One-instruction_set_computer
單一指令電腦有多種形式,其中一種較常見為:
https://esolangs.org/wiki/Subleq
subleq A B C
B-A 相減後結果放於B
若結果小於等於零則跳到C執行否則執行下一條指令
為
因為只有一個指令,因此通常不列出指令
根據說明,運算元皆為直接定址
舉例:
3 4 6
7 7 7
3 4 0
4:7 - 3:7 = 0, 0->4, 6->PC
4:0 - 3:7 = -7, -7->4, 0->PC
4:-7 - 3:7 = -14, -14->4, 6->PC
## logisim 模擬subleq
於是我規劃一套用TTL IC構成的subleq CPU
並且在logisim上面模擬完成!
![](https://i.imgur.com/FcuyXhz.png)
## 補充:後來修改成資料與位址全16位元寬
因為在實際程式運作中
有找到一套別人寫的subleq巨集組譯器
裡面的範例程式提到使用經過自身計算的目標位址
如果我的subleq資料只有8位元
那麼位址的16位元寬就無法計算
所以必須把資料匯流排也提升到16位元寬
雖然會把資料路徑的元件擴增一倍
但是控制電路卻不用改動
這個設計架構符合可擴展性😊
![d16a16ttl功能說明方塊圖](https://hackmd.io/_uploads/r1tKrek4p.jpg)
## 使用繞線板的實作照片
![IMG_2964](https://hackmd.io/_uploads/S1BJwly4p.jpg)
## 搭配STM32L476RG作為模擬記憶體
![IMG_2960](https://hackmd.io/_uploads/B1N-DgyVT.jpg)
## 終於可以跟我的CPU實體玩剪刀石頭布
{%vimeo 883825719 %}
###### tags: `cpu`