汪 濤,徐正安
(重慶大學 物理學院,重慶 401331)
精簡指令集計算機RISC (Reduced Instruction Set Computer)是一種執(zhí)行較少類型計算機指令的微處理器,起源于上世紀80年代的 MIPS主機 (即 RISC機),RISC機中采用的微處理器統(tǒng)稱RISC處理器。與一般的CPU相比,其不僅簡化了指令系統(tǒng),而且還通過簡化指令系統(tǒng)使計算機的結(jié)構(gòu)更加簡單合理,從而提高了計算機的運算速度。從實現(xiàn)的途徑看,RISC_CPU與一般的CPU的不同之處在于,它的時序控制信號形成部件是用硬布線邏輯實現(xiàn)的而不是采用微程序的控制方式,因此,與一般CPU相比它省去了讀取微指令的時間。
RISC_CPU與生活密切相關(guān),它已經(jīng)進入消費電子的各個領(lǐng)域,ARM、MIPS、PowerPC和51單片機等處理器都屬于RISC家族的一部分,在國際市場上RISC處理器占有巨大的市場份額,RISC的研發(fā)也是一個非常熱門的領(lǐng)域,只有認真理解RISC的原理才能更好地認識和掌握已有的RISC架構(gòu)的處理器。
利用現(xiàn)場可編程門陣列FPGA (Field Progamable Gate Array)的靈活性可以很方便地設計出RISC,利用Altera公司的EDA工具QuartusⅡ和Mentor公司的ModelSim可以設計出RISC的RTL模型并對這個模型進行仿真。本文介紹了一種8 bit簡單RISC的實現(xiàn)方法,在QuartusⅡ中搭建了模型,通過時序仿真對該模型進行了功能驗證。
本文設計的RISC具有8條指令,一律采用直接尋址地方式,采用哈佛結(jié)構(gòu),指令和數(shù)據(jù)存儲分別放在定制的ROM和RAM中。RISC_CPU的基本結(jié)構(gòu)圖1所示。
圖1 RISC_CPU的基本結(jié)構(gòu)
該RISC_CPU可以綜合到FPGA的具體電路中,因此,在完善外部電路和接口的情況下完全可以當做一臺真正的計算機來使用。該RISC_CPU的工作過程如下:首先,將預先編好的匯編指令代碼以11 bit二進制的形式存放在定制的ROM中 (在QuartusⅡ的MegaWizard中完成定制),將要處理的數(shù)據(jù)按地址順序存放在定制的RAM中;然后,有限狀態(tài)機(FSM)開始以 8個指令周期的工作模式開始工作,在這8個指令周期中完成指令和數(shù)據(jù)的加載,F(xiàn)SM產(chǎn)生的 8組標志信號(FLAG)完成對控制單元(CU)和算術(shù)邏輯單元(ALU)的控制;最后,由FSM產(chǎn)生的停止信號(HALT)終止程序的運行,并將程序的運行結(jié)果存儲在RAM的指定地址中。
這款 RISC的每條指令有 11 bit,高3 bit為操作碼,低8 bit為ROM和RAM地址,因此它的尋址空間為256 bit,對于簡單的匯編指令還是可以應付的。
本文設計的RISC主要由8條指令組成,它們的功能如下。
(1)HLT(opcode為 3’b000):停機操作。 該操作將空一個指令周期,即8個時鐘周期。
(2)SKZ(opcode 為 3’b001):為零跳過下一條語句。該操作先判斷當前alu中的結(jié)果是否為零,若是零就跳過下一條語句,否則繼續(xù)執(zhí)行。
(3)ADD(opcode為 3’b010):相加。該操作將累加器中的值與地址所指的存儲器或端口的數(shù)據(jù)相加,結(jié)果仍送回累加器中。
(4)AND(opcode為 3’b011):相與。該操作將累加器的值與地址所指的存儲器或端口的數(shù)據(jù)相與,結(jié)果仍送回累加器中。
(5)XOR(opcode為 3’b100):異或。該操作將累加器的值與指令中給出地址的數(shù)據(jù)異或,結(jié)果仍送回累加器中。
(6)LDA(opcode為 3’b101):讀數(shù)據(jù)。該操作將指令中給出地址的數(shù)據(jù)放入累加器。
(7)STO(opcode為 3’b110):寫數(shù)據(jù)。 該操作將累加器的數(shù)據(jù)放入指令中給出的地址。
(8)JMP(opcode為 3’b111):無條件跳轉(zhuǎn)語句。 該操作將跳轉(zhuǎn)至指令給出的目的地址,繼續(xù)執(zhí)行。
指令寄存器主要完成對指令的解碼,由于ROM中存儲的是11 bit數(shù)據(jù),因此需要在一個指令周期中完成指令的獲取,同時,指令寄存器由FSM輸出的控制標志符get_ir完成指令的拆分,其中高3 bit為操作碼送往ALU中進行操作,低8 bit送往RAM中完成數(shù)據(jù)的尋址操作。在QuartusⅡ中編寫Verilog HDL語言完成了指令寄存器的RTL模型的搭建,其在QuartusⅡ中的封裝模塊如圖2所示。
指令寄存器設計的難點是控制標志符get_ir如何與ROM的讀指令標志rd_rom配合完成指令的拆分。好的時序設計能避免產(chǎn)生雜亂無章的信號,使匯編程序能正確的被所設計的指令寄存器識別并被后面的模塊使用。
圖2 指令寄存器模塊
算術(shù)邏輯單元主要完成8種指令的運算和邏輯操作,本設計的指令系統(tǒng)由 HLT、SKZ、ADD、AND、XORR、LDA、STO和JMP這8條指令組成。其中,SKZ是一種判斷指令,若累加器的結(jié)果為0,則跳過下一條語句繼續(xù)執(zhí)行;如果為1,就執(zhí)行下一條指令。這條指令的設計使得設計的程序變得多樣化,因此在ALU的設計中需要輸出1個零標志信號zero來與狀態(tài)機輸出的9位標志信號共同配合才能使RISC工作。邏輯單元在QuartusⅡ中封裝的模塊如圖3所示。
圖3 算術(shù)邏輯單元模塊
程序計數(shù)器(PC)的出現(xiàn)是程序設計的必然,因為在設計程序時不可能都是順序執(zhí)行的,如果只有順序執(zhí)行的情況那么實現(xiàn)一些稍微復雜一點的功能就很困難。計算器不同于計算機就是因為計算機可以按照程序的要求改變程序的執(zhí)行順序,例如在執(zhí)行 JMP(跳轉(zhuǎn)指令)的時候,需要形成新的指令地址。程序計數(shù)器在 QuartusⅡ中封裝的模塊如圖4所示。
圖4 程序計數(shù)器模塊
狀態(tài)機是RISC設計的核心,每個指令要成功運行都必須依靠狀態(tài)機產(chǎn)生的標志信號,因此狀態(tài)機設計的核心又是標志信號的設計。一個指令周期占8個時鐘,即在一個狀態(tài)機內(nèi)部有8個狀態(tài),這8個狀態(tài)依次為:0:裝載 ROM 中的 11 bit指令;1:程序計數(shù)器加 1;2:空操作;3: 程序計數(shù)器加1,同時判斷指令是否為HLT指令;4:判斷指令并讀取 RAM中的數(shù)據(jù);5:執(zhí)行相應的指令;6:空操作 ;7: 判 斷 指 令 是 否 為SKZ指令,若是則程序計數(shù)器加1,若不是則不作任何處理。在QuartusⅡ中封裝的狀態(tài)機模塊如圖5所示。
圖5 狀態(tài)機模塊
在RISC中,ROM用來存儲程序代碼,在每個指令周期結(jié)束后,ROM的地址增1,同時加載一條指令,因此,ROM的地址時鐘應該是狀態(tài)機的輸出狀態(tài)標志rd_rom,在每個rd_rom的上升沿ROM的讀地址加1。在調(diào)試RISC的時候事先將指令代碼用mif文件的格式存儲在ROM中,mif文件中存放的指令代碼如圖6所示。
圖6 mif文件中存放的程序
在QuartusII的MegaWizardsTI中定制了一個32×10 bit的ROM,然后加載 mif文件,但是這樣仍不夠,還需要編寫一個模塊完成ROM的地址生成,編寫的Verilog HDL代碼如下:
將這個rom_data_gen封裝為一個模塊放在主block diagram中,如圖7所示。
RAM的設計相對于ROM而言要復雜很多,因為RAM既要讀又要寫,同時還要在一些時刻形成新的地址。例如要求出一個這樣的序列,已經(jīng)給出了1和2兩個數(shù),后面求出的每個數(shù)都是前面兩個數(shù)的和(這樣的序列稱為費波納序列),這樣求出的序列為:3,5,8,13,21,34,55,89,144…。 用本文設計的指令集來編寫匯編程序如下:
LOOP:LDA 1
STO 2
ADD 0
STO 1
LDA 2
STO 0
圖7 ROM和rom_data_gen模塊
詳細的分析結(jié)果如圖8所示。
RAM設計的難點就是在每個指令周期要完成數(shù)據(jù)的讀操作,在下一個周期要完成數(shù)據(jù)的寫操作,RAM中初始化的數(shù)據(jù)在一個指令周期之后會發(fā)生變化,因此,如何初始化RAM中的數(shù)據(jù)是一個關(guān)鍵問題。
圖8 求解序列的匯編程序分析
在求解一個問題時一定是對內(nèi)存中的數(shù)據(jù)進行操作(即RISC中RAM的數(shù)據(jù)),因此,在每個程序的開始階段一定要讀取RAM中初始化的數(shù)據(jù),讀取完之后釋放RAM中的數(shù)據(jù)的讀控制權(quán),開始由ALU單元進行RAM的數(shù)據(jù)讀寫操作。只有這樣才能不與RAM中初始化的數(shù)據(jù)發(fā)生沖突,保證程序運行的正確。
因此可以再定制一個ROM來完成RAM中數(shù)據(jù)的初始化,在任何一個要往RAM中寫數(shù)據(jù)的時刻釋放該ROM的讀控制權(quán),這個動作由data_choose模塊來完成。data_ram_wr_rd即本文所設計的RAM,圖9即為這3個模塊與ALU的關(guān)系示意圖。
圖9 數(shù)據(jù)讀寫操作示意圖
data_ram_wr_rd模塊的Verilog HDL代碼如下:
在 QuartusⅡ中封裝的 data_ram_wr_rd模塊和RAM_wr_rd模塊如圖10所示。
編寫完RISC的每個模塊后,在Block Diagram中連接各個模塊。
要求出144以內(nèi)的費波納序列,這樣的程序運行之后的正確結(jié)果為:1,2,3,5,8,13,21,34,55,89,144。
本文所設計的RISC如果能成功運行這個程序,則證明本設計是正確的,至于一些細節(jié)的東西(如中斷控制、流水線操作、超標量和cache操作等)再做考慮。
圖10 data_ram_wr_rd模塊和RAM_wr_rd模塊
圖11 求解序列程序的時序仿真結(jié)果
在ROM中裝載好已經(jīng)編寫好的匯編語言(為11 bit二進制數(shù)),同時在RAM中裝載初始化數(shù)據(jù) 1、2(1和2分別對應RAM中的地址0和1)。然后在QuartusⅡ中進行時序仿真,得到的結(jié)果如圖11所示。
從圖11可以看出,程序運行的結(jié)果完全正確,求出了要找的費波納序列。
本文介紹了基于FPGA的RISC的設計和仿真的方法,通過編寫Verilog HDL語言來完成整個RISC模塊的搭建。通過分析匯編程序在FPGA中的運行原理,并在QuartusⅡ中進行時序仿真,驗證了用FPGA設計RISC的可行性。
[1]夏宇聞.數(shù)字系統(tǒng)設計——Verilog實現(xiàn)[M].北京:高等教育出版社,2007.
[2]湯志忠,楊春武.開放式實驗 CPU設計[M]北京:清華大學出版社,2007.
[3]姜詠江.基于 QuartusⅡ的計算機核心設計[M]北京:清華大學出版社,2007.
[4]楊天怡.計算機硬件技術(shù)基礎[M]重慶:重慶大學出版社,2002.
[5]伯杰.計算機硬件及組成原理[M]北京:機械工業(yè)出版社,2006.