摘 要: 設(shè)計(jì)了一款具有4級(jí)流水線結(jié)構(gòu)的16位RISC嵌入式微處理器。針對(duì)轉(zhuǎn)移指令,未采用慣用的延遲轉(zhuǎn)移技術(shù),而是通過(guò)在取指階段增加相應(yīng)的硬件結(jié)構(gòu)實(shí)現(xiàn)了無(wú)延遲轉(zhuǎn)移。采用內(nèi)部前推技術(shù)解決了指令執(zhí)行過(guò)程中的數(shù)據(jù)相關(guān)。同時(shí)通過(guò)設(shè)置相應(yīng)的硬件堆棧實(shí)現(xiàn)了對(duì)中斷嵌套和調(diào)用嵌套的支持。整體系統(tǒng)結(jié)構(gòu)采用Verilog HDL語(yǔ)言設(shè)計(jì),指令系統(tǒng)較完善。在軟件平臺(tái)上的仿真驗(yàn)證初步表明了本設(shè)計(jì)的正確性。
關(guān)鍵詞: 微處理器;流水線;精簡(jiǎn)指令集;現(xiàn)場(chǎng)可編程門陣列;嵌入式系統(tǒng)
隨著微電子及EDA技術(shù)的高速發(fā)展,可編程邏輯器件的研發(fā)與應(yīng)用也取得了長(zhǎng)足的進(jìn)步。其中,基于現(xiàn)場(chǎng)可編程門陣列(FPGA)的片上系統(tǒng)(System on Chip)在嵌入式系統(tǒng)中得到了廣泛的應(yīng)用。與傳統(tǒng)的專用集成電路(ASIC)相比,其具有開(kāi)發(fā)周期短、設(shè)計(jì)簡(jiǎn)單靈活等特點(diǎn)。
本文描述了基于FPGA的16 bit嵌入式微處理器的結(jié)構(gòu)設(shè)計(jì)。該處理器采用程序存儲(chǔ)器與數(shù)據(jù)存儲(chǔ)器分離的哈佛型結(jié)構(gòu),采用精簡(jiǎn)指令集(RISC),指令面向寄存器操作,加快了運(yùn)行速度,簡(jiǎn)化了控制邏輯。
1 系統(tǒng)結(jié)構(gòu)設(shè)計(jì)
該處理器執(zhí)行指令時(shí)按照取指(IF)、譯碼(ID)、執(zhí)行(EX)和結(jié)果保存(WR)4個(gè)階段依次進(jìn)行。由于采用4級(jí)流水線結(jié)構(gòu),每個(gè)時(shí)鐘周期能完成一條指令的執(zhí)行。
1.1 指令系統(tǒng)
該處理器采用RISC型指令,設(shè)置了數(shù)據(jù)傳送、算術(shù)邏輯運(yùn)算和程序控制3大類共21條指令,指令格式固定,每條指令長(zhǎng)度為32 bit。
1.2 硬件結(jié)構(gòu)
該處理器共有4級(jí)流水線,因此可將硬件基本劃分為取指、譯碼、執(zhí)行和結(jié)果保存4部分。
1.2.1 取指
取指部分結(jié)構(gòu)如圖1所示。與參考文獻(xiàn)[1]中提及的處理器取指部分相比,其增加了PC選擇生成器G_PC,通過(guò)它實(shí)現(xiàn)了無(wú)延遲的程序轉(zhuǎn)移指令。
G_PC是本部分的核心,其部分Verilog HDL實(shí)現(xiàn)代碼如下:
……
input inta,z;//inta為中斷請(qǐng)求信號(hào)
//z為譯碼部分回送的信號(hào),用于jz、jnz指令
input[4:0]p_op_code;//指令操作碼,即inst[28:24]
output status_up,status_down,epc_up,epc_down;
//對(duì)status和EPC進(jìn)行出入棧控制
output s2;//對(duì)將要壓入EPC中的返回地址進(jìn)行選擇
output cover;//控制EPC頂部單元數(shù)據(jù)是否被mux2送來(lái)的數(shù)據(jù)覆蓋
output[1:0]s1;//s1對(duì)下條指令的取指地址進(jìn)行選擇
reg status_up,status_down,epc_up,epc_down,s2;
reg[1:0] s1;
always begin
case(p_op_code)
//根據(jù)指令的操作碼來(lái)產(chǎn)生信號(hào)的輸出
5′b00000:begin//此操作碼對(duì)應(yīng)add ra,rb,rc指令
if(inta)begin
//如果有符合優(yōu)先級(jí)條件的中斷請(qǐng)求則inta為1
status_down=1;
//控制status在下個(gè)時(shí)鐘沿將s0壓棧
status_up=0;
epc_down=1;
//控制EPC下個(gè)時(shí)鐘沿將相應(yīng)的返回地址壓棧
epc_up=0;
s1=3;
//選擇中斷入口地址add_int作下條指令地址
s2=0;
//選擇當(dāng)前指令地址加4作為返回地址壓入EPC
cover=0;//EPC頂部數(shù)據(jù)不被覆蓋
end
else begin//無(wú)符合優(yōu)先級(jí)條件的中斷請(qǐng)求
status_down=0;
status_up=0;
epc_down=0;
epc_up=0;
s1=0;//下條指令地址為當(dāng)前指令地址加4
s2=1′bx;//s2為無(wú)關(guān)信號(hào),0或1均可
cover=0;
end
end
……
//其他指令類似,根據(jù)操作碼及是否有中斷請(qǐng)求來(lái)生成相應(yīng)的輸出信號(hào)
endcase
end
優(yōu)先編碼器coder則從硬件電路上實(shí)現(xiàn)了中斷源的優(yōu)先級(jí),即3號(hào)中斷優(yōu)先級(jí)最高,然后依次遞減(3號(hào)中斷的優(yōu)先級(jí)值為4,2號(hào)中斷的優(yōu)先級(jí)值為3,1號(hào)中斷為2,0號(hào)中斷為1)。coder的輸出信號(hào)s0既代表了中斷的優(yōu)先級(jí),又起到了選擇中斷入口地址的作用。
取指部分的具體工作流程如下。
?。?)假設(shè)此時(shí)指令地址add_pc在ROM中對(duì)應(yīng)的指令inst為sub r0,r1,r2,此類語(yǔ)句不會(huì)使下一條指令地址發(fā)生轉(zhuǎn)移。同時(shí)假設(shè)沒(méi)有中斷信號(hào)產(chǎn)生,于是當(dāng)下一個(gè)時(shí)鐘上升沿到達(dá)時(shí),由G_PC生成的控制信號(hào)s1將add_pc+4選通送入PC寄存器中,即取出物理地址相鄰的下一條指令(加4是因?yàn)橐粭l指令有32 bit,共4 B)。
假設(shè)add_pc在ROM中對(duì)應(yīng)的指令inst為sub r0,r1,r2,且中斷狀態(tài)棧status頂部單元數(shù)據(jù)為0。此時(shí)有中斷信號(hào)0和中斷信號(hào)2產(chǎn)生,優(yōu)先編碼器coder生成的s0為2號(hào)中斷的優(yōu)先級(jí)3(大于status頂部數(shù)據(jù)0),于是中斷請(qǐng)求信號(hào)inta有效。當(dāng)下一個(gè)時(shí)鐘上升沿到達(dá)時(shí),G_PC生成的s2信號(hào)和epc_down信號(hào)將add_pc+4壓入返回地址棧EPC中,s0和由G_PC產(chǎn)生的信號(hào)s1將2號(hào)中斷的入口地址v2送入PC寄存器中(0號(hào)中斷被忽略掉),同時(shí)將s0的值3(即2號(hào)中斷的優(yōu)先級(jí))壓入中斷狀態(tài)棧status頂部。
?。?)假設(shè)此時(shí)add_pc在ROM中對(duì)應(yīng)的指令inst為絕對(duì)跳轉(zhuǎn)jump 100,即程序轉(zhuǎn)移到地址100處開(kāi)始執(zhí)行,且沒(méi)有中斷信號(hào)產(chǎn)生。則當(dāng)下一個(gè)時(shí)鐘上升沿來(lái)臨時(shí),由G_PC產(chǎn)生的s1等控制信號(hào)將inst[23:16](此時(shí)為100)送入PC寄存器中開(kāi)始執(zhí)行。
假設(shè)此時(shí)add_pc在ROM中對(duì)應(yīng)的指令inst為絕對(duì)跳轉(zhuǎn)jump 100,但此時(shí)有中斷信號(hào)1產(chǎn)生(且假設(shè)此時(shí)status頂部值小于2),則inta為1。于是G_PC產(chǎn)生的控制信號(hào)將inst[23:16](即100)壓入EPC頂,將中斷1的優(yōu)先級(jí)(即s0的值2)壓入status頂部,將中斷1的入口地址送入PC寄存器中,開(kāi)始響應(yīng)中斷。如果之后又產(chǎn)生優(yōu)先級(jí)大于2的中斷,則將相關(guān)數(shù)據(jù)壓棧后響應(yīng)中斷,若產(chǎn)生中斷的優(yōu)先級(jí)小于或等于2,則被忽略不執(zhí)行。
條件轉(zhuǎn)移jz、jnz與jump指令類似,只是當(dāng)譯碼階段產(chǎn)生的Z信號(hào)為1時(shí),jz跳轉(zhuǎn),Z為0時(shí)jnz跳轉(zhuǎn)。通常比較指令comp后面緊跟條件轉(zhuǎn)移指令來(lái)實(shí)現(xiàn)程序轉(zhuǎn)移控制。
(3)假設(shè)此時(shí)add_pc在ROM中對(duì)應(yīng)的指令inst為調(diào)用指令call 100,執(zhí)行此條指令時(shí)忽略所有中斷請(qǐng)求信號(hào),將add_pc+4壓入EPC中后,將inst[23:16](即100)送入PC寄存器中開(kāi)始執(zhí)行調(diào)用程序。
(4)假設(shè)此時(shí)add_pc在ROM中對(duì)應(yīng)的指令inst為中斷返回指令int_ret,且沒(méi)有高優(yōu)先級(jí)的中斷產(chǎn)生,則EPC頂部的數(shù)據(jù)add_ret送入PC寄存器中,同時(shí),EPC和status中的頂部數(shù)據(jù)彈出,其余數(shù)據(jù)依次上移一位。
假設(shè)此時(shí)add_pc在ROM中對(duì)應(yīng)的指令inst為中斷返回指令int_ret,但有優(yōu)先級(jí)比status頂部單元數(shù)據(jù)高的中斷信號(hào)產(chǎn)生,則G_PC產(chǎn)生的cover信號(hào)有效,status頂部數(shù)據(jù)被新的中斷優(yōu)先級(jí)值所覆蓋,EPC維持不變,同時(shí)響應(yīng)新中斷。
(5)調(diào)用返回指令call_ret與中斷返回指令int_ret類似,不過(guò)執(zhí)行時(shí)status中的數(shù)據(jù)不彈出。
1.2.2 譯碼
譯碼部分結(jié)構(gòu)如圖2所示。
譯碼部分核心是控制單元ctrl。為了解決流水線的數(shù)據(jù)相關(guān),采用了內(nèi)部前推的方法,將執(zhí)行部分產(chǎn)生的數(shù)據(jù)result回送至本部分。將比較單元comp產(chǎn)生的信號(hào)Z送至譯碼部分,使得條件跳轉(zhuǎn)指令(jz、jnz)在取指階段就能實(shí)現(xiàn),從而實(shí)現(xiàn)無(wú)延遲跳轉(zhuǎn)。
本部分中的寄存器堆reg_file在時(shí)鐘下降沿且寫信號(hào)l_e_w_reg有效時(shí)執(zhí)行寫數(shù)據(jù)操作(實(shí)現(xiàn)結(jié)果保存WR這一部分的功能)。ctrl產(chǎn)生的一部分控制信號(hào)通過(guò)執(zhí)行控制寄存器EXR送至下一級(jí)使用。
1.2.3 執(zhí)行
執(zhí)行部分的結(jié)構(gòu)如圖3所示。此部分核心是算術(shù)邏輯運(yùn)算單元ALU,前面譯碼部分的ctrl產(chǎn)生的運(yùn)算控制碼alu_code指定運(yùn)算操作,運(yùn)算結(jié)果c_out送入5/1選擇器mux6。關(guān)于mux6的其余4路數(shù)據(jù)對(duì)應(yīng)的指令為:dout對(duì)應(yīng)load ra,imme即將數(shù)據(jù)存儲(chǔ)器中指定地址單元M[imme]的數(shù)據(jù)送入ra號(hào)寄存器中;ds對(duì)應(yīng)pop ra,即將數(shù)據(jù)堆棧stake棧頂?shù)臄?shù)據(jù)彈入ra號(hào)寄存器中;e_imme對(duì)應(yīng)指令val ra,imme送立即數(shù)imme入ra號(hào)寄存器;e_db對(duì)應(yīng)mov ra,rb即將rb號(hào)寄存器中的數(shù)據(jù)送入ra號(hào)寄存器中。
1.2.4 結(jié)果保存
這里的結(jié)果保存是針對(duì)目的地址為寄存器的指令,如算術(shù)邏輯運(yùn)算指令、寄存器之間的數(shù)據(jù)傳輸指令等。工作流程即將圖3中RSR的l_e_ra、l_e_w_reg、l_result信號(hào)送入圖2中的reg_file。當(dāng)時(shí)鐘下降沿到達(dá)且l_e_w_reg有效時(shí),數(shù)據(jù)l_result被寫入l_e_ra號(hào)寄存器中。
2 仿真驗(yàn)證
為了驗(yàn)證該設(shè)計(jì),利用Altera公司的Quartus II軟件進(jìn)行仿真驗(yàn)證。仿真時(shí)設(shè)計(jì)在取地址為32的指令時(shí)出現(xiàn)0號(hào)中斷,在取地址為52的指令時(shí)出現(xiàn)1號(hào)中斷。實(shí)際執(zhí)行時(shí),1號(hào)中斷嵌套在0號(hào)中斷之中。對(duì)應(yīng)中斷的入口地址分別為48、68。仿真結(jié)果如圖4所示。
圖4中a0~a6分別顯示的是r0~r6號(hào)寄存器中的數(shù)據(jù);v0、v1分別是0號(hào)中斷、1號(hào)中斷的入口地址;pc_num是處在取指階段的指令的地址;ints是中斷輸入信號(hào),ints=1、ints=2分別表示外設(shè)請(qǐng)求1號(hào)中斷、外設(shè)請(qǐng)求2號(hào)中斷。從圖4中可以看出:
?。?)幾乎每條處在取指階段的指令都要經(jīng)過(guò)3個(gè)時(shí)鐘上升沿和一個(gè)時(shí)鐘下降沿后才執(zhí)行完畢。這是因?yàn)橹噶钊≈竿瓿珊?,還要經(jīng)過(guò)譯碼、執(zhí)行和結(jié)果保存3個(gè)階段,并且結(jié)果保存是在時(shí)鐘下降沿完成的。但由于是流水線結(jié)構(gòu),故等效于每一個(gè)時(shí)鐘執(zhí)行一條指令。
?。?)當(dāng)取到地址為pc_num=32的指令時(shí),中斷信號(hào)1產(chǎn)生,于是下條指令的取指地址為1號(hào)中斷入口地址48。執(zhí)行1號(hào)中斷的子程序到52時(shí),中斷信號(hào)2產(chǎn)生,于是響應(yīng)2號(hào)中斷,下條指令地址為2號(hào)中斷入口地址68(2號(hào)中斷子程序就一條返回指令)。
?。?)當(dāng)執(zhí)行地址為24的jump 0指令時(shí),下條指令地址為0,實(shí)現(xiàn)了無(wú)延遲轉(zhuǎn)移。
綜上所述,經(jīng)初步驗(yàn)證,該設(shè)計(jì)能實(shí)現(xiàn)4級(jí)流水線結(jié)構(gòu),并具備中斷及其嵌套、無(wú)延遲轉(zhuǎn)移等功能。
本文設(shè)計(jì)了一種基于FPGA的16 bit嵌入式RISC微處理器。該處理器主要特點(diǎn)是通過(guò)增加硬件結(jié)構(gòu)實(shí)現(xiàn)了對(duì)轉(zhuǎn)移指令的無(wú)延遲實(shí)現(xiàn)以及對(duì)中斷及調(diào)用指令的支持。在下一步工作中將優(yōu)化結(jié)構(gòu)設(shè)計(jì),增加外圍設(shè)備,逐步構(gòu)成一個(gè)高性能的單片系統(tǒng)。
參考文獻(xiàn)
[1] 李亞民.計(jì)算機(jī)原理與設(shè)計(jì)[M].北京:清華大學(xué)出版社,2011.
[2] 鄭緯民,湯志忠.計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)[M].北京:清華大學(xué)出版社,1998.
[3] 夏宇聞.Verilog數(shù)字系統(tǒng)設(shè)計(jì)教程[M].北京:北京航空航天大學(xué)出版社,2008.
[4] 于洋,肖鐵軍,丁偉.面向教學(xué)的16位CISC微處理器的設(shè)計(jì)[J].計(jì)算機(jī)工程與設(shè)計(jì),2010,31(16):3584-3587.
[5] 張英武,袁國(guó)順.32位嵌入式RISC處理器的設(shè)計(jì)與實(shí)現(xiàn)[J].微電子學(xué)與計(jì)算機(jī),2008,25(6):14-17.
[6] 曾舒婷,楊志家.高性能PLC專用指令集處理器設(shè)計(jì)與仿真[J].微電子學(xué)與計(jì)算機(jī),2011,28(7):76-81.