胡世昌
(沈陽師范大學 軟件學院,沈陽 110034)
“不聞不若聞之,聞之不若見之,見之不若知之,知之不若行之。學至于行之而止矣?!痹谟布n程教學中,人們一直在探索更好的實驗改革方案[1-3]。對于計算機組成原理課程教學,“行之”的境界,應該是能夠設計一臺簡單的計算機。這種設計應該是從“0”和“1”開始,根據(jù)數(shù)字電路基礎知識,結合計算機組成原理課程的內(nèi)容,實現(xiàn)滿足要求的簡單計算機,而不應是半成品的簡單連接和驗證。這種實現(xiàn)同樣不應該受限于任何教材,講解《計算機組成原理》時,有的講解順序是運算器→存儲器→控制器[4],有的講解順序是存儲器→運算器→控制器,先設計哪一個環(huán)節(jié),都不能影響最終設計出一個簡單計算機這樣的目標。綜合考慮成本、方便性,logisim-evolution仿真軟件(https://github.com/reds-heig/logisim-evolution)是一個不錯的選擇。
機器的指令集選擇圖靈完備的單指令SUBLEQ[6]來實現(xiàn)算術運算和轉移,單指令集計算機[7-8]適合教學。為簡化設計,把減法指令分成有跳轉(SJ)和無跳轉(SN)2條指令,用與非指令(NA)實現(xiàn)邏輯運算[9],共需實現(xiàn)3條運算指令。
由于存儲系統(tǒng)具有地址線16根、數(shù)據(jù)線8根,如果采用直接尋址,2個操作數(shù)的地址就需要訪存4次才能取回對應地址的4個字節(jié),為了減少存儲器的訪問次數(shù)、縮短運算指令的長度,采用基址尋址,為此需要增加設置基地址指令(BA)。
由此得到了必須具備的4條指令,需要2位二進制碼對這4條指令進行編碼,如表1所示。
表1 指令編碼
“無跳轉減”運算指令SN、“與非”運算指令NA的長度都是1個字節(jié),指令格式為pp aaa bbb, D7D6兩位(pp)表示操作碼,D5D4D3三位(aaa)是A操作數(shù)的形式地址,D2D1D0三位(bbb)是B操作數(shù)的形式地址,它們作為有效地址的低3位,與基地址共同構成16位有效地址,基地址僅僅負責提供有效地址的高13位?!霸O置基地址”指令(BA)是3字節(jié)指令,它的3個字節(jié)分別是(x表示0或1):00xxxxxx,基地址低字節(jié),基地址高字節(jié)。Subleq A,B,C是3字節(jié)指令,它的3個字節(jié)分別是:01aaabbb,C地址低字節(jié),C地址高字節(jié)。
需要3個字節(jié),第1字節(jié)的二進制表示為00xxxxxx,其中x表示該位取值0或1;采用低字節(jié)在前的方法表示數(shù)字,所以第2字節(jié)是00(H),第3字節(jié)是10(H)。于是得到設置基地址指令的十六進制表示為00 00 10(H)。
指令目標是1000地址單元的內(nèi)容和1001地址單元的內(nèi)容做減法,結果放在1001地址單元,不跳轉。它是1字節(jié)指令,對應的二進制表示為10 000 001,轉換成十六進制表示為81(H)。
指令系統(tǒng)中沒有專門的停機指令,可跳到預先設定的某個循環(huán)地址,如0FFD,讓機器進入無限循環(huán)。
2.3.1 設置基地址為0000
這是一個3字節(jié)指令,代碼為00 00 00(H)。
2.3.2 無條件跳轉到0FFD地址
利用Subleq指令實現(xiàn),具體方法是讓0000地址單元的內(nèi)容減去0000地址單元的內(nèi)容,這個結果顯然必定為零,從而發(fā)生跳轉。又因為0000地址單元在ROM中,所以不可能真正寫入,也就不會改變程序。指令所對應的3個字節(jié)是:第1字節(jié)包含操作碼,其二進制代碼為01 000 000,對應十六進制40(H);第2字節(jié)包含跳轉的低位地址,這里為FD(H);第3字節(jié)包含跳轉的高位地址,這里為0F(H)。于是得到無條件跳轉指令的十六進制代碼為40 FD 0F(H)。
2.3.3 完整測試代碼
實現(xiàn)“(1000)-(1001)→ 1001功能,之后無限循環(huán)”的整個程序代碼由10個字節(jié)構成,內(nèi)容是00 00 10 81 00 00 00 40 FD 0F(H)。
實現(xiàn)上述功能的算術邏輯單元只需8位減法器和8位與非門即可,運算方式選擇輸入端S0N1為0時做減法運算,為1時做與非運算;輸出F表示運算結果,狀態(tài)標志leq在運算結果小于或等于0時置1。
這個ALU雖然簡單,但需要譯碼、尋址,所以能夠作為實現(xiàn)的例子來使用,而且給學生留下了更多的改進空間,可以去實現(xiàn)更加復雜的ALU。
ALU需要2個輸入寄存器保存輸入數(shù)據(jù),分別稱為A和X,它們可以分別用來保存參與運算的2個操作數(shù)A和B。為保存Subleq的跳轉目的地址C,設置專用寄存器CL和CH,CL用于保存C的低字節(jié),CH用于保存C的高字節(jié),它們連接到程序計數(shù)器PC的數(shù)據(jù)輸入端,以便改變PC的值。
對應設置基地址指令base,相應設置了基址寄存器,基址寄存器的位數(shù)最少應該是13位,與指令中所給出的低3位結合,才能訪問所有的內(nèi)存空間。為了設計上的方便,本CPU中采用16位基址寄存器(低3位不用),對應2個8位寄存器BAL和BAH,其中BAL用于保存基地址的低字節(jié),BAH用于保存基地址的高字節(jié)。
有效地址的高13位來自寄存器BAL和BAH,低3位來自指令中的aaa和bbb部分。實現(xiàn)電路如圖2所示,有效地址的低3位由指令寄存器中直接給出,高13位則由BAL和BAH給出,共同形成A操作數(shù)和B操作數(shù)的有效地址。
這樣就需要6個寄存器:A、X、CL和CH、BAL和BAH。此外,還需要指令寄存器IR、程序計數(shù)器PC和內(nèi)存地址寄存器MAR。由于例題相對簡單,內(nèi)存數(shù)據(jù)寄存器MDR可以不用。
指令譯碼器是一個2線-4線譯碼器,指令寄存器(IR)的最高2位作為指令譯碼器的輸入,指令譯碼器的4個輸出分別代表BA、SJ、SN、NA指令,高電平有效。例如當BA=1時,表明指令譯碼器中保存的是設置基地址指令。
完整的CPU如圖2所示,包括ALU、寄存器、指令譯碼器和控制單元CU(控制器)??刂茊卧妮斎氚◤臀?、時鐘、使能信號、指令譯碼器的輸出信號BA、SJ、SN、NA和ALU的狀態(tài)標志leq,輸出是用于三態(tài)門和寄存器的控制信號。為控制數(shù)據(jù)的流動,添加了必要的三態(tài)門,并給各個寄存器提供寫使能控制信號,這些控制信號的來源是控制單元的輸出。
確定了輸入和輸出信號之后,就可以設計控制器??刂茊卧跁r鐘的控制下,根據(jù)不同的輸入信號,有序地輸出一系列相應的控制信號,控制ALU、寄存器、存儲器和I/O設備去執(zhí)行一系列的動作(微操作),來完成輸入信號所規(guī)定的功能。所以設計控制單元的第一步,就是確定不同輸入信號所對應的一系列微操作。
規(guī)定寄存器和RAM都由時鐘上升沿觸發(fā),所有控制信號都是高電平有效。
第1個時鐘(T0)上升沿之后,給出MARi信號,MAR寄存器準備接受內(nèi)存地址輸入。
第2個時鐘(T1)上升沿之后,內(nèi)存地址寫入MAR,寫入后內(nèi)存地址才能出現(xiàn)在地址總線(AB)上。同時可以給出讀內(nèi)存命令(R1_W0=1,MEMREQ0=0)。
第3個時鐘(T2)上升沿之后,“讀內(nèi)存”命令發(fā)揮作用,內(nèi)存單元的內(nèi)容被讀出到數(shù)據(jù)總線(DB)上。需要注意的是,如果讀信號在第3個時鐘上升沿到來時已經(jīng)消失(R1_W0=0,MEMREQ0=0),將會變成“寫內(nèi)存”命令,所以必須確保第3個時鐘上升沿到來時,讀信號依然有效。解決方案是把讀命令加寬為2個時鐘周期,在第2、3節(jié)拍中都確保讀命令(R1_W0=0,MEMREQ0=0)有效。
本機只有取指和執(zhí)行2個階段,可用T觸發(fā)器構成工作階段寄存器STG,當STGi=1時,T觸發(fā)器翻轉。F0E1=0表示取指階段,F(xiàn)0E1=1表示執(zhí)行階段;經(jīng)1輸入2輸出譯碼器譯碼后,F(xiàn)E=1表示取指階段,EX=1表示執(zhí)行階段。對應電路如圖3所示。
7.3.1 取指令第1字節(jié)
表2 取指周期-讀入第1個字節(jié)
7.3.2 根據(jù)指令操作碼確定后續(xù)操作
T2上升沿,指令碼進入CPU內(nèi)部DB,還沒有進入IR,此時不能譯碼;T3上升沿,指令碼才能進入IR,所以在T3節(jié)拍才可以得到譯碼結果,并根據(jù)譯碼結果,從T3節(jié)拍開始執(zhí)行不同的微操作序列。
T3~T8節(jié)拍中各個指令的微操作如下:
1)設置基地址指令(BA):從內(nèi)存中取出2字節(jié)地址存入基址寄存器,之后進入下一條指令的取指周期,如表3所示。
表3 取指周期-設置基地址
2)Subleq 指令(SJ):從內(nèi)存中取出2字節(jié)地址存入C寄存器,之后進入執(zhí)行周期,完成減法運算(表4)。為了標識CPU進入了執(zhí)行周期,設置STGi來改變執(zhí)行階段寄存器STG的值。
表4 取指周期-Subleq
3)無跳轉減指令SN、與非指令NA:在T3~T8節(jié)拍中沒有具體操作,只需更改STG即可(表5)。
表5 取指周期-SN和NA
BA指令沒有執(zhí)行周期,SJ、SN、NA指令的執(zhí)行周期基本相同,如表6所示。
表6 執(zhí)行周期
綜合取指周期和執(zhí)行周期的微操作信號表,可得到控制信號的邏輯表達式,例如
STGi=FE·(SJ·T8+(SN+NA)·T8)+
EX·(SJ+SN+NA)·T8,
PCi=EX·SJ·T8·leq。
其他表達式不一一列舉。根據(jù)表達式,就可以得到相應的組合邏輯電路圖,例如STGi以及設置指令周期狀態(tài)的寄存器如圖4所示。
首先根據(jù)前文分析中所得到的控制信號出現(xiàn)的先后順序,寫出控制存儲器中每一個地址單元的內(nèi)容,如表7所示。根據(jù)表中所列的控制信號,可知控制信號需要17位;因為控制存儲器的地址編號有27個(對應表中的編號0~26),可知下地址字段需要5位;二者相加,可知控制存儲器的位寬應該是22。
表7 微程序控制器的代碼
表中第2列表示指令當前所處的工作階段,其中FE表示取指周期的第1階段(取指令的第1字節(jié))。組合邏輯控制器的FE階段只需要3個時鐘周期,微程序控制器的FE階段卻需要4個時鐘周期,這是因為組合邏輯電路可以在1個時鐘周期(T3)內(nèi)完成譯碼以及根據(jù)譯碼結果確定相應微操作的工作,而微程序控制方案中則需要2個時鐘周期,前一時鐘周期完成譯碼并根據(jù)譯碼結果確定下一個微地址,在下一時鐘周期才能把所確定的微地址寫入控制存儲器CMAR(這是由存儲器的工作特性所決定的)。
下地址字段決定了下一條指令的地址,用來修改CMAR,其含義有如下幾類:(1)第3行表示根據(jù)指令寄存器中的操作碼字段的譯碼結果決定下地址,BA轉地址4,SJ轉地址10,SN轉地址17,SA轉地址18。(2)第26行表示如果當前指令是SJ指令且計算結果小于等于0(leq),則轉地址16(給PC賦值,以便實現(xiàn)指令跳轉);否則直接轉CMAR地址0(取下一條指令)。(3)轉下地址字段給定地址(當前地址加1,或地址0、或地址19)。
控制存儲器(控存)的下一條指令地址來自CMAR寄存器,其來源有3個:(1)當前地址為3時,選擇來自指令操作碼所決定的地址(4、10、17或18);(2)當前地址為26、指令為SJ、且leq為真時,選擇地址16;(3)其余情況,直接來自控存的下地址字段。
當前地址為3和26的兩種情況,需要借助硬件實現(xiàn),如圖5所示。
其余情況則直接使用下地址字段即可。由此可得控制存儲器每個單元內(nèi)容,如0地址單元的內(nèi)容為10 0100 0000 0000 0000 0001(B),或者240001(H);1地址單元的內(nèi)容為00 0011 0000 0000 0000 0010(B),或者030002(H);其他地址單元的內(nèi)容依次類推。把所得到的每個地址單元的內(nèi)容寫入控制存儲器,就完成了微程序控制器的設計。
各部件設計完畢以后,連接起來,就構成了一臺具有CPU和存儲器的簡單的機器。在步驟3已經(jīng)設計好了測試方案,只需運行測試代碼即可驗證所設計的計算機是否正確。在0000地址單元的起始部分(這里是ROM)填入用十六進制表示的指令序列00 00 10 81 00 00 00 40 FD 0F,并在1000地址單元存入數(shù)據(jù)A,1001地址單元存入數(shù)據(jù)B,運行程序,運行后應該在1001地址單元得到A-B的結果。如果結果正確,就說明這個由10個字節(jié)組成的程序確實實現(xiàn)了(1000)-(1001)→1001這個功能;之后機器進入無限循環(huán)。
本設計側重于介紹一種低成本的、直觀的方法,學會從基本邏輯電路開始,快速地設計一臺簡單計算機,它服務于《計算機組成原理》課程的教學,僅以計算機的設計和實現(xiàn)為目的,對運算程序在空間和時間上的資源消耗未加考慮。
在課程教學中,給了學生3種選擇:獨立設計(自行設計一個簡單的計算機,指令集不要求完備)、讀懂老師給的設計并改進、單純讀懂。要求不論是設計還是改進,都不能重復。43名學生中,在選擇環(huán)節(jié)有8名選擇了獨立設計,2名選擇改進,33名選擇了單純讀懂;最終完成時,有2名學生放棄了獨立設計。這說明,要求所有學生掌握計算機的設計還不現(xiàn)實,更加復雜的指令系統(tǒng)的設計暫時還不宜引入。
在計算機組成原理課程中,使用logisim-evlution設計簡單計算機,有益且可行。在條件允許的情況下,本設計可以有更多改進的地方,比如考慮使用多總線、更多的通用寄存器、RAM采用下降沿觸發(fā)、仿真cache的實現(xiàn)、增加指令等。在邏輯電路的實現(xiàn)過程中,會發(fā)現(xiàn)根據(jù)邏輯表達式畫邏輯圖這個步驟,可以借助自動化工具來完成,從而在時間允許的條件下引入硬件描述語言實現(xiàn)。