|
——《穿越計算機的迷霧》整理和總結 究竟是如何設計的電路,具有計算和控制的智力?
這一點也不高深。本系列文章從初中學的最簡單的電路圖說起,看看能不能從最初的有一個繼電器的電路,畫到一個簡單的CPU。電路圖用multisim12.0繪制,這樣就可以看到效果了。
(注:雖然現代計算機是用半導體材料制作芯片的,但是電路原理和繼電器材料沒有不同。本人愚鈍,只理解了繼電器,還沒有研究電子管、晶體管這些器件的工作原理。而繼電器原理簡單,用作講解數字電路原理再好不過。)
PS:需要本文的multisim12電路圖文件的話,麻煩點個贊并留下你的Email~
從電池、開關和繼電器開始
o_001%e7%94%b5%e6%ba%90%e5%bc%80%e5%85%b3%e5%92%8c%e7%81%af%e6%b3%a1.gif (24.67 KB, 下載次數: 288)
下載附件
2016-1-30 01:23 上傳
上圖左上角是一個很普通的電路,由電池、開關電流表和燈泡組成。這個是初中物理學過的。
上圖右上角是對左上角電路的簡單變形,用VCC代替了電池,用接地符號實現了回路。相當于把電池拆開來畫了。電路功能是一樣的。本文此后的電路圖一般都采用VCC和接地表示電源。因為你會發現只有這樣的畫法能夠讓我們方便理解之后的電路圖。
然后往下看,第三個電路圖,那個圈圈里圈著個K的藍色的東西,表示的是繼電器。當繼電器左側有電流通過時,右側的電路就斷開;反之則聯通。(對應地,也有那種左側有電流通過時,右側的電路就聯通;反之則斷開的繼電器,稍后會用到)這個電路想讓你知道的是,可以用繼電器實現這樣的功能:控制左側的電路的通斷,即可改變右側電路的通斷。換個方式說,就是左側的電路通斷情況決定了右側的電路的通斷情況。再往抽象了說,就是左側電路代表了"輸入"(Input)這個概念,右側電路代表了"輸出"(Output)這個概念。繼電器則代表了"計算"(或者"算法"、"處理"等)(CPU)這個概念。硬件就是用這種電器設備的固有物理性質提供了最初的計算能力。
再往下看第四個電路圖,它和第三個的區別就在于用VCC和接地符號代替了電池。初次看電路,我們有必要經歷一次從電池到VCC和接地符號的過渡。以后的電路圖,我們將直接使用VCC和接地符號,請務必在此處適應這樣的畫法。
然后是最下邊這個電路。和第四個電路相比,它用一個"非門"的符號代替了"繼電器、右側電路電源和繼電器的接地"這三個符號。也就是說一個"非門"實際上就是"繼電器、右側電路電源和繼電器的接地"這三個東西的組合,而且畫的時候省略了電源和接地符號。
之前在學校里學數字電路,我就是想不明白邏輯門的電源在哪兒,整個電路的通路在哪兒,所以一直學不好。現在有個這個電路圖,感覺一切豁然開朗。
用繼電器做個與門剛剛我們用繼電器做出了"非門"。可以看到只要用一個繼電器就可以了。與門的電路如下圖所示。
o_002%e7%94%a8%e7%bb%a7%e7%94%b5%e5%99%a8%e5%81%9a%e4%b8%8e%e9%97%a8%e7%94%b5%e8%b7%af.gif (16.59 KB, 下載次數: 280)
下載附件
2016-1-30 01:23 上傳
與門由兩個繼電器(這兩個繼電器用的都是跟做非門的繼電器通斷情形相反的那種)構成,只有當兩個繼電器左側都通電時,右側電路才能聯通。這樣就實現了"與"的功能。"與門"的符號是一個躺著封口的U形。
注:本文里我做的電路圖片都是GIF格式的,你可以在瀏覽器里看到隨著開關的開閉,輸入和輸出電路上的燈泡是如何變化的。每個圖上都有(bitzhuwei*cnblogs*com)標識我的博客地址,不過每個GIF圖的最后一幀都去掉了這個標識。這樣,看到一幀沒有標識的時候,就知道下一幀將是GIF圖的第一幀了。
用繼電器做個或門"非門"、"與門"做出來了,"或門"也就不難理解了,直接上圖大家體會吧。(導線交叉的地方,如果有個紅點,表示是聯通的,否則就是互不相干的)"或門"的符號像一個子彈。
o_003%e7%94%a8%e7%bb%a7%e7%94%b5%e5%99%a8%e5%81%9a%e6%88%96%e9%97%a8%e7%94%b5%e8%b7%af.gif (16.73 KB, 下載次數: 300)
下載附件
2016-1-30 01:23 上傳
用繼電器做個異或門"異或門"的功能是:左側的兩個輸入電路一個聯通另一個不聯通時,右側電路聯通;否則右側電路不聯通。這次先畫符號,大家可以先自己嘗試用繼電器畫"異或門",鍛煉一下思維,然后再向下看答案。
o_005%e7%94%a8%e7%bb%a7%e7%94%b5%e5%99%a8%e5%81%9a%e5%bc%82%e6%88%96%e9%97%a8%e7%94%b5%e8%b7%af2.gif (10.34 KB, 下載次數: 303)
下載附件
2016-1-30 01:23 上傳
答案揭曉!"異或門"的實現如下圖所示。乍看很復雜,其實是有邏輯的。最右邊的兩個繼電器其實是一個"或門",最左邊兩個繼電器是兩個"非門",中間兩上兩下共四個繼電器,是兩個"與門"。這樣就好理解了。AB兩個輸入電路為A通、B不通的時候,整個"異或門"會通過下方的路線使燈泡亮;若A不通、B通,則會通過上方的線路使燈泡亮。其他情況燈泡都不會亮。
o_004%e7%94%a8%e7%bb%a7%e7%94%b5%e5%99%a8%e5%81%9a%e5%bc%82%e6%88%96%e9%97%a8%e7%94%b5%e8%b7%af1.gif (22.5 KB, 下載次數: 280)
下載附件
2016-1-30 01:23 上傳
做一些看起來可用的東西與或非異或邏輯門電路雖然重要,卻離構造CPU相距較遠,做出來似乎也沒什么成就感。那么我們用這些過于基礎的器件,做一些有用的東西吧!
小小約定為了表達方便,我們約定一下,邏輯門電路的輸入(輸出)線上有電流的時候,我們說輸入為1(輸出為1),否則就說輸入為0(輸出為0)。
振蕩器振蕩器能夠不斷地輸出0、1、0、1、0、1、0、1……這樣的信號。這種東西雖然一時說不上有什么用,不過一定是有用到的時候的。振蕩器做起來也簡單得離譜。看下圖所示電路。
o_006%e6%8c%af%e8%8d%a1%e5%99%a82.gif (12.38 KB, 下載次數: 290)
下載附件
2016-1-30 01:23 上傳
把非門的輸出端連到輸入端上。當輸出為1時,輸入也就成了1,那么輸出就得變成0;然后輸入也跟著變成0,這樣輸出又變回了1。循環翻轉無休無止。振蕩器能翻轉多快,就看繼電器的反應有多快了。(現代計算機用晶體管代替了繼電器,晶體管比繼電器翻轉速度快得多,所以能夠得到的頻率更高,計算機的速度更快。而且晶體管比繼電器省電)話說multisim12仿真的翻轉速度也夠可以的,本人截圖也費了不少勁。
順便給一個用繼電器做振蕩器的實際應用的例子:上學的時候上下課的鈴聲就是用繼電器做的振蕩器完成的。0101信號用錘子敲打鐵盔表達了出來。
加法器剛剛約定了,用1和0表示電路的通斷。電路只有通斷這兩種狀態,所以計算機只用0和1來表示數,這就是二進制啊。關于二進制和十進制的內容別人寫得太多了,我就不提啦。要計算兩個多位二進制數的和,可以分別計算各個數位上的結果,而各個數位的計算方法又是相同的,即"被加數+加數=>和的值+進位的值"。這用邏輯門表示如下圖。
o_007%e5%8a%a0%e6%b3%95%e5%99%a81.gif (14.39 KB, 下載次數: 305)
下載附件
2016-1-30 01:23 上傳
A和B表示加數和被加數,C表示前一位計算的進位的值,C1燈泡表示本次計算的進位的值,S1燈泡表示本次計算的和的值。我找了半天,也沒在multisim12里找到一位二進制數的加法器件的符號,大家看這個圖就可以了。
241605146231188.png (1.97 KB, 下載次數: 310)
下載附件
2016-1-30 01:23 上傳
要計算多位數,把單位數加法器首尾相連就可以了,如下圖所示。這兩張圖是從《穿越計算機的迷霧》中拿來的。如果侵權,請告訴我,不然我就偷個懶不自己畫啦。
241605149826143.png (6.3 KB, 下載次數: 300)
下載附件
2016-1-30 01:23 上傳
寄存器學匯編的時候聽過這個東西,"寄存"這個詞讓我感覺寄人籬下可憐巴巴的。寄存器的功能是把數據(約定里說的0和1,實際就是電路的通斷狀態)保存下來,以后還可以取出來用。寄存器這東西比之前的器件都復雜,需要一步一步來做。
R-S觸發器先看下面這個電路,這是各種有存儲功能的器件的基礎。
o_009R-S%e8%a7%a6%e5%8f%91%e5%99%a81.gif (9.12 KB, 下載次數: 285)
下載附件
2016-1-30 01:23 上傳
上圖展示的是在R和S開關都斷開的情況下啟動電路得到的結果。《穿越計算機的迷霧》里說這種情況下,哪個燈泡亮是不一定的,就看哪個邏輯門轉的快了。不過我用multisim12仿真的時候,兩個燈泡是在忽亮忽滅不停地閃。這可以說是非正常人類使用R-S觸發器的情況。下面再看看正常人類使用R-S觸發器的情況。
o_009R-S%e8%a7%a6%e5%8f%91%e5%99%a82.gif (10.29 KB, 下載次數: 308)
下載附件
2016-1-30 01:23 上傳
R-S觸發器的R是Reset,意思是把Q燈泡重置為0,S是Set,意思是把Q燈泡置為1。可以看到,只閉合S,則Q亮NQ不亮;只閉合R,則Q不亮NQ亮;同時閉合RS,則Q和NQ都不亮;同時斷開RS,則Q和NQ保持剛才的狀態不變。
D觸發器既然要保存數據,我們就要求只在希望保存某個數據的時候存進去,否則就不理他。所以我們給R-S觸發器加一個新的輸入作為控制端,只有控制端為1的時候才能保存新來的數據。這里也把RS端合并為一個D端,用一個非門實現了只能使R和S有且只有一個開關是閉合的(即要么Q燈泡變為1要么Q燈泡變為0)。
o_010D%e8%a7%a6%e5%8f%91%e5%99%a8.gif (10.59 KB, 下載次數: 271)
下載附件
2016-1-30 01:23 上傳
D觸發器的符號我也沒在multisim里找到,大家看這個吧。
241605165297871.png (1.67 KB, 下載次數: 283)
下載附件
2016-1-30 01:23 上傳
上升沿D觸發器我們只希望在某一瞬間把數據存起來,而不是像D觸發器那樣,控制端為1的整個時間端都會保存新數據。(這樣最安全)于是我們在D觸發器基礎上設計了上升沿D觸發器。這個觸發器只在控制端從0變為1的瞬間存儲新數據。是不是很奇妙的設計?
o_011%e4%b8%8a%e5%8d%87%e6%b2%bfD%e8%a7%a6%e5%8f%91%e5%99%a8.gif (23.48 KB, 下載次數: 326)
下載附件
2016-1-30 01:23 上傳
上升沿D觸發器使用了兩個D觸發器,再加一個非門,就OK了。平時,我們把要存儲的數據(D開關)放好。然后,當控制端CP為斷開時,圖中上面那個D觸發器是能夠存數據的,但是下面那個存不了。就是說新數據已經到了兩個D觸發器之間的導線上。在控制端CP閉合的瞬間,上面的D觸發器無法再存新數據了,而下面的D觸發器可以存新數據了,那么它存的是哪個新數據?只能是剛剛在兩個D觸發器之間的導線上的數據了。這個瞬間之后,新數據無法通過上面的D觸發器,自然也就無法保存了。
這次我終于在multisim12里找到了上升沿D觸發器的符號。
乒乓觸發器這是個有點類似振蕩器的器件。兩者的區別在于,振蕩器是自動地改變輸出,乒乓觸發器是在輸入一個上升沿的時候改變輸出。電路圖如下所示。
o_013%e4%b9%92%e4%b9%93%e8%a7%a6%e5%8f%91%e5%99%a8.gif (23.56 KB, 下載次數: 288)
下載附件
2016-1-30 01:23 上傳
可以看出,乒乓觸發器其實就是把上升沿D觸發器的非Q輸出端接到了輸入端。很顯然每次存的新數據總是和輸出信號相反。
乒乓觸發器可以用來做計數器。計數器有這樣的功能:每收到一個上升沿的信號,就增加1。例如下圖所示的能統計二進制的00000到11111(即0到31)這32個數。計數器的每一位計數器件都是一個乒乓觸發器。燈泡亮表示1,燈泡滅表示0。
o_014%e8%ae%a1%e6%95%b0%e5%99%a8.gif (35.39 KB, 下載次數: 288)
下載附件
2016-1-30 01:23 上傳
走馬燈利用上升沿D觸發器還可以做"走馬燈"。走馬燈是每次都讓前面一個燈泡亮的設備,最后一個燈泡亮過之后,又從第一個燈泡開始亮,循環往復。下圖所示電路就是一個有5個燈泡循環走馬的走馬燈。為了在電路剛接通的時候讓第一個燈亮起來,我加了兩個開關S1和S2,大家可以分析一下怎么用S1和S2。這有助于加深體會上升沿D觸發器的功能,并加速對更復雜器件的理解。
o_012%e8%b5%b0%e9%a9%ac%e7%81%af.gif (22.24 KB, 下載次數: 283)
下載附件
2016-1-30 01:23 上傳
寄存器終于到這個小玩意了!
能保存5位二進制數的寄存器如下圖所示。其實就是5個上升沿D觸發器并列起來而已。
o_015%e5%af%84%e5%ad%98%e5%99%a8.gif (21.29 KB, 下載次數: 263)
下載附件
2016-1-30 01:23 上傳
想保存數據的時候,調整好D0、D1、D2、D3、D4五個開關(實際應用的時候就可能是其他電路的輸出導線了),然后斷開再閉合一下控制端的開關S5即可,數據就保存到了5個上升沿D觸發器的Q端。
我這里只畫了保存5位數的寄存器,是因為再畫就太大了,在word里圖就看不清楚了。我們知道現在計算機的寄存器已經到32位或者64位了。那就是有32或64個并列的上升沿D觸發器組成一個寄存器。我們也看到了一個上升沿D觸發器需要幾十個繼電器(晶體管),那么一個寄存器就需要上千個繼電器(晶體管)了。而CPU里包含的寄存器、加法器等運算器還有各種控制器,其包含的繼電器(晶體管)數目上百萬也就很好理解了。內存條里的內存也是用上升沿D觸發器和一個門電路組成存儲一位(一個bit,8個bit是一個字節)的存儲結構的,其包含的繼電器(晶體管)數目可想而知有多少。
中場休息到這里,做CPU需要的基礎器件就差不多全了。不過再寫下去就太長了,不利于理解和記憶。因此暫且中場休息,下一篇再繼續介紹如何構造一個簡單的CPU。
前面介紹的各自器件,可以用下表描述其繼承關系。(索性把下一篇文章要介紹的器件也列出來了)
繼電器
|
|
|
|
|
|
|
|
| 非門電路
|
|
|
|
|
|
|
| 與門電路
|
|
|
|
|
|
|
| 或門電路
|
|
|
|
|
|
|
| 異或門電路
|
|
|
|
|
|
| 振蕩器
|
|
|
|
|
|
|
| 加法器
|
|
|
|
|
|
|
| 寄存器
|
|
|
|
|
|
|
|
| R-S
| D
| D↑
| 乒乓
| 計數器
|
|
|
|
|
|
| 走馬燈
|
|
|
|
|
|
|
| 寄存器
| 多個數的加法器
|
|
|
|
|
|
| 存儲器
| 多bit存儲器
| 多字存儲器
| 有地址譯碼器的存儲器
| 控制器
|
|
|
|
|
|
|
|
| 手動
|
|
|
|
|
|
|
| 半自動
|
|
|
|
|
|
|
| 全自動
|
|
|
|
|
|
|
自言自語自大學始,學軟件工程至今已有7年。一共找到這么幾本好書:《穿越計算機的迷霧》、《Orange'S OS:一個操作系統的實現》、《CLR via C#》。
讀《穿》就是為了弄明白一個問題:為什么計算機能夠計算?《穿》在下面這張圖中讓我明白了我一直想不明白的問題。
241605217329481.png (39.71 KB, 下載次數: 314)
下載附件
2016-1-30 01:23 上傳
讀《Orange》也是為了弄明白一個問題:進程到底是什么?
讀《CLR via C#》還是為了弄明白一個問題:.NET虛擬機里都有什么?
想知道的東西還有很多,抓緊一切機會去求索~
上一篇已經從電池、開關、燈泡和繼電器開始,畫出了設計CPU所需的基本器件。這些器件將成為設計CPU的磚瓦木料。這一篇就用這些基本器件做一個CPU的雛形。
本篇所需基礎器件
傳輸門下圖所示的傳輸門的作用是:當左邊的"~1G"端輸入為0時,左側的1A4、1A3、1A2、1A1會直接傳輸到右側對應的1Y*,就像一條線直接從1A*連接到1Y*一樣;當左邊的"~1G"端輸入為1時,左側的1A4、1A3、1A2、1A1都不能傳輸到右側對應的1Y*,就像從1A*到1Y*的連線被剪斷了一樣。
注:本文里我做的電路圖片都是GIF格式的,你可以在瀏覽器里看到隨著開關的開閉,輸入和輸出電路上的燈泡是如何變化的。每個圖上都有(bitzhuwei*cnblogs*com)標識我的博客地址,不過每個GIF圖的最后一幀都去掉了這個標識。這樣,看到一幀沒有標識的時候,就知道下一幀將是GIF圖的第一幀了。
o_016%e4%bc%a0%e8%be%93%e9%97%a8%e7%94%b5%e8%b7%af%e6%b5%8b%e8%af%95.gif (34.66 KB, 下載次數: 307)
下載附件
2016-1-30 01:23 上傳
傳輸門的原理很簡單,就是在每個1A*到1Y*之間的連線上放個繼電器而已,如下圖所示。(取自《穿》)
220935057798046.png (3.13 KB, 下載次數: 276)
下載附件
2016-1-30 01:23 上傳
寄存器在上一篇已經說明了寄存器的原理,這里僅僅是為了說明"74LS194"這個帶有各種無聊管腳的四位寄存器的用法。將"~CLR"、"S1"和"S0"置為1,"SR"和"SL"置為0,然后,"74LS194"就是一個簡單的四位寄存器了。(本人在multisim12.0里只找到了這個靠譜的四位寄存器,湊合用吧。)
o_017%e5%af%84%e5%ad%98%e5%99%a8%e6%b5%8b%e8%af%95.gif (22.06 KB, 下載次數: 303)
下載附件
2016-1-30 01:23 上傳
數值顯示器為了更直觀地看到CPU的運算結果,我們將使用"DCD_HEX"這個東西。它能夠把輸入的"0101"顯示為"5",把"1010"顯示為"A"。
o_018%e5%9b%9b%e4%bd%8d%e6%95%b0%e5%80%bc%e6%98%be%e7%a4%ba%e5%99%a8.gif (12.99 KB, 下載次數: 288)
下載附件
2016-1-30 01:23 上傳
本文還要用一個四位的加法器,直接在下面這個簡陋的CPU里看就好了,不再單獨展示。
一個簡陋的CPU現在一切就緒,可以開始設計CPU了!
CPU包括運算器和控制器兩部分。我們首先做出運算器,然后逐步實現控制器,最后感受一下用機器語言編程的過程。本文實現的CPU雖然功能及其簡陋,但是能夠傳達出當前真實CPU的原理。
運算器和手動控制器現在我們要做的這個CPU,字長是4位,只能做兩個數的加法。實現了運算器和手動版的控制器的CPU如下圖所示。我們把這個版本稱為version1的CPU。
o_019%e6%89%8b%e5%8a%a8CPU_V2.gif (70.8 KB, 下載次數: 304)
下載附件
2016-1-30 01:23 上傳
上圖中,"Add"是加法器,能執行兩個4位數的加法運算。"RA"和"TR"是寄存器,"GAA"和"GBA"是傳輸門。"4""3""2""1"用來準備需要相加的數據(0到15),"KTR""KRA""KGA""KGB"是用來控制傳輸門通斷和寄存器脈沖的開關。
在上圖所示的GIF動畫中,顯示了"5+1+2+4"這個過程。這個過程可以分為4個步驟:①加載一個數值(Load);②加上一個數值(Add);③加上一個數值(Add);④加上一個數值(Add)。具體來說,每一個步驟要做的事情是:
指令
| 內容
| 加載一個數(Load)
| 準備數據(0101); KGB↓, KGA↑; KRA↓↑
| 加一個數(Add)
| 準備數據(0001); KGB↓, KGA↑; KTR↓↑; KGA↓, KGB↑; KRA↓↑
| 加一個數(Add)
| 準備數據(0002); KGB↓, KGA↑; KTR↓↑; KGA↓, KGB↑; KRA↓↑
| 加一個數(Add)
| 準備數據(0004); KGB↓, KGA↑; KTR↓↑; KGA↓, KGB↑; KRA↓↑
|
你可以看到,每次執行(Add)這一步,要做的事情(搬動開關)是一樣的,規律性極強。這意味著可以用簡化的方式控制"KTR""KRA""KGA""KGB"這幾個開關的狀態。經過簡化的CPU就有一定的自動化控制的性質了,如下圖所示。我們把這個版本的CPU稱為version2的CPU。
o_020%e5%8d%8a%e8%87%aa%e5%8a%a8CPU.gif (59.87 KB, 下載次數: 274)
下載附件
2016-1-30 01:23 上傳
Verison2要比剛才的verison1進化了一些。為便于理解,我們保留原來的"KTR""KRA""KGA""KGB"這四個開關(把它們挪到了右上角,因為實在沒地方放了),但讓它們永遠保持閉合的狀態。這是想說明:version2里新增的電路只是實現了更加自動化地控制"KTR""KRA""KGA""KGB"的開閉,它沒有改變version1中電路的工作流程。
Version2中的"KLoad"和"KAdd"開關分別代表了"Load"和"Add"這兩個指令。當"KLoad"閉合時,表示CPU要進行加載操作,這會把"4""3""2""1"上的數據存入寄存器"RA";當"KAdd"閉合時,表示CPU要進行相加操作,這會把"4""3""2""1"上的數據與"RA"當前的數據相加,然后相加的結果又存儲到"RA"。
Version2中的"K0"和"K1"兩個開關會依次的開閉,即兩者總有一個是斷開且另一個是閉合的(若出現其它情況那就是電路設計錯了)。所以實際上"K0"和"K1"可以用一個"2位循環移位寄存器"代替。(為便于理解,仍然保留"K0"和"K1"這兩個開關,只不過讓它們永遠保持閉合的狀態)
Version2中,只需重復"準備指令,準備數據,執行指令(K↓↑↓↑)"這樣的操作,就能完成version1中的控制功能。這需要一個從"KLoad""KAdd""K0""K1"到"KTR""KRA""KGA""KGB"的轉換電路,即version2電路圖中的上半部分,如下圖所示。
220935084354101.png (2.29 KB, 下載次數: 296)
下載附件
2016-1-30 01:23 上傳
這需要一點點設計邏輯電路的知識,本文直接列出真值表,據此即可畫出轉換電路。(想知道如何推導的話,請查閱《穿》或者數字電路類書籍)
Kload
| Kadd
| K0
| K1
| KGA
| KRA
| KTR
| KGB
| 1
| 0
| 1
| 0
| 1
| 1
| 0
| 0
| 0
| 1
| 1
| 0
| 1
| 0
| 1
| 0
| 0
| 1
| 0
| 1
| 0
| 1
| 0
| 1
|
其中"KLoad""KAdd""K0""K1"為輸入,"KTR""KRA""KGA""KGB"為輸出。只有如上三種輸入情況下,輸出部分會有1;其它的輸入情況下,輸出全部為0,所以就不需要列出來了。
舉個例子,"KGA"="KLoad""~KAdd""K0""~K1" + "~KLoad""KAdd""K0""~K1"=("KLoad" ⊕"KAdd")"K0""~K1",據此可以畫出"KGA"的轉換電路。
在version2中,CPU要做的就是重復"準備指令,準備數據,執行指令(K↓↑↓↑)"這件事。其中執行指令這一步是完全重復完全自動化的(只要用振蕩器替換K就可以),而準備指令和準備數據還需要手工操作。每次要執行哪個指令、要準備的數據是多少,這都是沒有規律的,可改進的方法就是:把指令和數據按順序保存到一些特別的寄存器里,需要的時候取出來用。這些特別的寄存器,就是內存。
內存所謂飯前便后要洗手,一個完整的衛生間,除了有若干坑位,還得有洗手池配套。類似的,學習CPU的結構原理,也得把"內存"牽出來溜溜,否則無法說明計算機編程的本質。CPU+內存才是一個完整的計算機(核心),才能展現出CPU的功能。由此也能聯系到,將鼠標鍵盤顯示器等稱為"外部"設備的道理。
最基本的內存單元能夠存儲和讀寫一個位(bit),是由一個上升沿D觸發器和傳輸門組成,如下圖所示。傳輸門電路我沒有找到只有一位的,拿這個四位GAA的湊合看吧。
o_021%e4%bf%9d%e5%ad%98%e4%b8%80%e4%bd%8d%e7%9a%84%e5%ad%98%e5%82%a8%e5%99%a8.gif (33.66 KB, 下載次數: 301)
下載附件
2016-1-30 01:23 上傳
內存單元的符號如下圖所示。(取自《穿》)
220935091074729.png (1.82 KB, 下載次數: 266)
下載附件
2016-1-30 01:23 上傳
把8個bit單元的讀寫端分別連起來,就可以存儲一個字節(8bit)。下圖是能夠存儲5bit的內存單元。(取自《穿》)此圖所示的結構,我們稱之為"一層"。
220935094209401.png (14.77 KB, 下載次數: 296)
下載附件
2016-1-30 01:23 上傳
存儲4bit的一層的符號如下圖所示。這時我學會了multisim12里的"層次塊"這個東西,下圖就是用層次塊畫的,這樣可以將復雜的電路封裝起來,省地方了,還能復用。所以說模塊化的思想在硬件設計里就有了。("用層次塊替換…"和VS里的"Extract Method…"功能是何其類似!)
220935096076643.png (1.17 KB, 下載次數: 305)
下載附件
2016-1-30 01:23 上傳
用一層一層的內存單元,即可構成存儲器。對于有8層的存儲器,需要3個bit表示需要讀寫的層數(23=8)。地址譯碼器的作用是:輸入101時,輸出的第5個(從0開始計數)引腳為1,其余均為0。有了地址譯碼器,存儲器對外只需很少的地址線(例如10根)即可使用很多層(例如1024層)。這也符合了軟件設計中接口盡可能簡單的原則。本文所用的RAM存儲器的結構如下圖所示。其中左邊的"3-8translator"就是譯碼器。
220935104669214.png (90.81 KB, 下載次數: 303)
下載附件
2016-1-30 01:23 上傳
其層次塊符號如下圖所示。
220935108265171.png (1.04 KB, 下載次數: 312)
下載附件
2016-1-30 01:23 上傳
這個RAM有三條地址線(Addr3、Addr2和Addr1),能夠表示23=8個字(層),每個字的長度是4bit。這個小小的RAM剛好夠存儲(5+1+2+4)這個示例的指令和數據,下面就用這個RAM繼續進化CPU。
這里也順便把"3-8translator"譯碼器的電路實現貼出來吧,如下圖所示。
220935113411315.png (7.64 KB, 下載次數: 302)
下載附件
2016-1-30 01:23 上傳
9位循環移位寄存器在version2里用的"2位循環移動寄存器"只需要一個乒乓觸發器(詳見上一篇)就可以了,但是后面要做的全自動控制器,需要一個"9位循環移位寄存器",且這個寄存器要在加電時自動將第一個輸出管腳置為1,其余為0。具有這樣的功能的寄存器如下圖所示。
o_024%e4%b9%9d%e4%bd%8d%e5%be%aa%e7%8e%af%e7%a7%bb%e4%bd%8d%e5%af%84%e5%ad%98%e5%99%a8.gif (33.11 KB, 下載次數: 269)
下載附件
2016-1-30 01:23 上傳
如上圖所示,第二行有4個D↑觸發器,其中最左邊的那個負責第一個輸出管腳,即應該在加電時就置為1的那個管腳。這是通過左下方的電路實現的,其原理大家自己琢磨吧,無非是利用反饋電路實現了只生效一次這個功能而已。"9位循環移位寄存器"的符號如下圖所示,其中"D0"是第一個輸出管腳。
220935153101167.png (2.06 KB, 下載次數: 310)
下載附件
2016-1-30 01:23 上傳
還有一個3bit的計數器,在上一篇里已經提過計數器,這里直接上圖。
o_025%e4%b8%89%e4%bd%8d%e8%ae%a1%e6%95%b0%e5%99%a8.gif (26.27 KB, 下載次數: 290)
下載附件
2016-1-30 01:23 上傳
其層次塊表示如下圖所示。
o_Counter3bit.png (1.63 KB, 下載次數: 265)
下載附件
2016-1-30 01:23 上傳
自動控制器有了內存,我們就要把指令和數據存進去。存儲數據很好理解,是多少就寫入多少。存指令之前,我們需要為每條指令分配一個4位的編碼,比如0000表示Load,1111表示Add,然后用這個指令碼控制"KLoad"和"KAdd"的開閉,所以這又是一個轉換電路。有了這個轉換電路,就可以只用"K"開關來完成"準備指令、準備數據、執行"這些操作了。全部自動化的CPU如下圖所示。我們將這個版本的CPU稱為version3的CPU。
o_026%e5%85%a8%e8%87%aa%e5%8a%a8CPU.gif (62.23 KB, 下載次數: 268)
下載附件
2016-1-30 01:23 上傳
這里的"ALU"是用層次塊表示的version1里的電路,因為不這樣的話,電路太大,而且不容易重點突出自動控制器的工作流程。同樣的,"ShiftRegister9bit"、"Translator"、"Counter3bit"、"RAM8F4bit"都是層次塊表示的電路。
"ShiftRegister9bit"會依次將輸出端置為1,這可以從上方的三個數值顯示器看出來。"Counter3bit"是3bit的計數器。"RAM8F4bit"是8層(每層4bit)的內存。"Translator"實現了控制信號的自動控制,"Translator"的內部實現如下圖所示。
220935182633367.png (48.66 KB, 下載次數: 299)
下載附件
2016-1-30 01:23 上傳
Version3所示的下半部分展示了譯碼電路,即把代表指令的4bit信號轉換為指令信號的電路。由于我們指定Load和Add指令的代碼(0000和1111)都是很規則的,所以譯碼電路也比較簡單,如下圖所示。
220935186075093.png (926 Bytes, 下載次數: 279)
下載附件
2016-1-30 01:23 上傳
Version3的CPU用"9位循環移位寄存器"等器件實現了"取指令、分析指令,取數、執行"的全部自動化,其中取指令、分析指令、取數、執行分別占用了移位寄存器的t0- t2、t3、t4-t6、t7-t8這9個階段。
注:如果用振蕩器替換了"K",這個CPU會不停地運轉下去,這樣就得不到我們想要的結果0xC(十進制的12)了。所以還需要添加"停機"指令。不過到這里已經說清了CPU的控制器是如何一步步實現自動化的,不再繼續講述如何添加新的指令。
最原始的機器語言編程在給出上文的自動控制器里,我們只說了從內存里取指令和數據,而沒有說這些指令和數據是如何寫進去的。其實寫進去的過程就是(機器語言)編程的過程。最簡單的,你可以用撥動開關的方式,調整好要寫入的位置,再調整好要寫入的數值,把指令和數據一個字一個字地寫入內存。最初的計算機編程就是用類似這樣的方式(打孔紙帶)編程的。(這個過程實在無聊,本文就不展示了,有興趣的話自己拿multisim玩玩就好~)
用助記符和一些宏來代替機器碼,這就是匯編語言。用C語言這種方式封裝了匯編語言的編程方法,就是面向過程編程。用C++C# Java這樣的語言封裝了面向過程的語言,就是面向對象的編程方法。用if(..){…}代替JMP指令這種東西比較容易想象,但用"封裝繼承多態"這種飄渺的概念代替面向過程編程就有點困難了。我在另一篇文章《用C表達面向對象語言的機制——C#版》中作了分析和總結,現在終于算是從繼電器一路走到面向對象編程了。
總結本系列文章只此兩篇就結束了。貌似太少算不上一個系列,不過管他呢,反正問題寫清楚就行了。如果有誰想做個實用的CPU,不妨用VHDL。SystemC也是用于硬件設計的,是用C++寫的一個類庫。我本科的時候用過,也不錯。
感謝博客園眾多園友推薦的好書,寫本篇之前惡補了一陣,受益匪淺!現和我讀的幾本書一起陳列出來,方便查找。點擊推薦者即可跳轉到其博客上。
書名
| 作者
| 推薦者
| 《穿越計算機的迷霧》
| 李忠
| BIT祝威
| 《編碼:隱匿在計算機軟硬件背后的語言》(《編碼的奧秘》)
| Charles Petzold
(伍衛國, 王宣政, 孫燕妮 譯)
| armstronglaw, ClarkZhou, hywin, 天邊彩云, Create Chen, Florian
| 《計算機系統要素——從零開始構建現代計算機》
| Noam Nisan, Shimon Schocken
(周維, 宋磊, 陳曦 譯)
| 吳飛
| 《CPU自制入門》
| 水頭一壽, 米澤遼, 藤田裕士
(趙謙 譯)
| 平如水
| 《CPU芯片邏輯設計技術》
| 朱子玉, 李亞民
| 吳飛
| 《30天自制操作系統》
| 川合秀實
(周自恒, 李黎明, 曾祥江, 張文旭 譯)
| 薛遺山
| 《Orange'S:一個操作系統的實現》
| 于淵
| BIT祝威
|
本文作為整理和總結性質的文章,不求面面俱到,只為整理思路。想從燈泡開始一點一點地了解計算機的構成的話,建議看《編碼的奧秘-隱匿在計算機背后的軟硬件語言》(這一本的中文翻譯也不錯)。
后續
了解了硬件的設計原理,又寫過那么多的程序,下一步就該做個操作系統了。這次要寫個真實可用的操作系統出來,不必像研究CPU一樣只能弄個超簡化的仿真模型玩了。再次感謝博客園眾多園友推薦的好書,讀了這幾本書我才相信能在個把月內做出一個有圖形界面的操作系統。如果再把網絡協議和瀏覽器整進來,豈不就可以順利暢游網絡?
|
評分
-
查看全部評分
|