CPU設計初探
習慣了“實踐-理論-實踐”的學習模式,對硬件知之甚少卻學完了《計算機組成原理》,我努力嘗試讓自己找到這門課的感覺。沒有FPGA的試驗器材,也沒有多少真實芯片在身邊,於是我拾起《數字電路》,準備在虛擬環境下,用Proteus設計一個簡單的虛擬CPU。
現在的網絡確實方便,我找到兩篇最滿意的文章就設計好一個最簡單的了。
起初使用wikipedia,查閱了CPU design詞條,瞭解到CPU主要是有Finite-state Machin,其間經歷了一次設計失敗:
當時翻了幾遍《計算機組成原理》來找設計的切入點,指令設計被我認爲是起點。於是不假思索地列出22種指令,並按6-bit二進制串編好碼,等所有指令格式確定以後,問題便出現了:①製作CPU需要哪些芯片?②如何讓搭好的CPU自動運轉?③BUS是怎麼使用的?
對於①,我仔細查看了學校實驗箱上的芯片型號,包括
74LS299(8-bit REG),
74LS381(ALU),
74LS74/175/273/374(D-Type Flip-Flops),
74LS245(BusTransceiver),
74LS139(2 line to 4 line Decoder),
6116(2K*8 SRAM),
8255(Programmable Peripheral Interface),
74LS240/244(Buffer)
74LS393(4-bit Counter)
74LS161(Synchronous 4-bit Counter)
芯片類型有了,但是還是不會用啊,只能打開proteus,把相應芯片找出來,再到網上下載各自的datasheet,這才逐漸清楚每個芯片具體的功用。進入下一步,設計再次卡殼了。誰連誰以什麼方式連,②和③怎麼解決?
對於③,我用74LS273配合總線嘗試:
在figure 2.中,當片選有效時,更改data有時會出現警告信號,也就是有管腳出現0,1不確定信號。後來看了Magic-1的設計,才明白兩種地方總線應該分開(如figure 3.)這樣③也就解決了。
而對於②,確實經歷了一個漫長的過程。
我先繞開問題②。爲了便於觀察,我捨棄使用RAM芯片,每次指令通過開關確定(figure 4.)。但很快就發現,當某開關沒有閉合時,其中一邊是沒有信號的,這樣設計不合理,於是我學會了使用下拉電阻(figure 5.),這樣開關閉合時是高電平,釋放時是低電平。
接着我立即用了4個74LS273,但當時竟然把這個芯片當寄存器使用,現在纔想起應該按figrue 6.設計寄存器。當時的4個74LS273我準備用作AR、DR、PC和IR的,其實沒有一個有用,最後我留了一個74LS273作IR緩衝器(figure 7.)。
設想了很多方案,逐步化簡後,我決定只使用兩個指令nop(00)和add(01),nop用來放空操作,而add則使用add imval,讓ACC <- ACC + imval,這樣也就省去了AR和DR。
將add分解後,有:
ADD1: REG <- D[3..0], ACC <- ACC + REG
ADD2: (goto FETCH1)
而取指和譯指微指令有:
FETCH1: IR <- D[7..6]
FETCH2: decode(IR)
有了FETCH1,FETCH2,ADD1,ADD2是還不能夠設計出figure 8.所示的譯指電路的。這個問題的解決還要歸功於④手動激發CPU運行的探索。
對於④,新接觸真是無從下手。把電子版的《Computer System Organization And Architecuture》中第6章CPU Design看了看,再結合FSM的資料,明白這部分需要使用計數器。再回到剛纔的4條微指令:
0000 FETCH1: IR <- D[7..6]
0001 FETCH2: decode(IR)
0010 ADD1: REG <- D[3..0], ACC <- ACC + REG
0011 ADD2: (goto FETCH1)
得到一個FSM:
計數器有/PL(並行加載)和MR(清零)這兩個信號控制,故完整的微指令有:
0000 FETCH1: IR <- D[7..6],MR = 1, /PL = 1
[act=1] MR = 0, /PL = 1
0001 FETCH2: decode(IR), MR = 0, /PL = 0
0010 ADD1: REG <- D[3..0], ACC <- ACC + REG, MR = 0, /PL = 1
0011 ADD2: MR = 1, /PL = 1
注:
當act=0時,0000和0011狀態下 MR = 1
act是觸發CPU運行的信號,高電平爲觸發
總結上面的微指令有:
/PL = FETCH2
MR = act and (C0000 or C0011) = not (act or ((not C000) and (not C0011)))
其電路設計如figure 9.。同樣的,figure 8.中IR=00則狀態機仍爲0000,IR=1則狀態機爲0010,故譯指器這樣就設計完畢了。到這裏②也就解決了。只要/PL有效,MR無效,計數器就會自動工作並帶着CPU運行啦~
最後,我把電路統一起來,並加上ACC,則有figure 10.:
把電路完整放入Proteus中,單擊運行開始模擬。將S6=1,S7=0,再設置S3 S2 S1 S0,單擊ACT按鈕,電路運轉正常,ACC中將存儲累加後的結果,CPU設計完成。
但這個CPU並沒有中斷功能,也沒有使用流水線技術,故下一步要考慮增加這兩部分了。總體來說,設計比較成功。^_^
參考文獻
[1] Magic-1 Homebrew CPU [OL/A] www.homebrewcpu.com/Magic1.pdf
[2] John.D.Capinelli, Computer System Organization and Architecture[M] Addison-Wesley, October 2000, p217-235
[3] CPU Design[OL/A] en.wikipedia.org/wiki/CPU_Design
[4] Finite-state Machin[OL/A] en.wikipedia.org/wiki/Finite-state_Machin
[5] Lecture 14: FSM and Basic CPU Design[OL/A] www.cs.utah.edu/~rajeev/cs3810/slides/3810-14.pdf