馮建文
(杭州電子科技大學(xué)計算機(jī)學(xué)院,杭州 310018)
RISC-V架構(gòu)以其開源特性和優(yōu)越的性能,在全球范圍內(nèi)得到迅猛發(fā)展,也為國產(chǎn)處理器自主可控帶來發(fā)展機(jī)遇[1-4]。相應(yīng)地,國內(nèi)外越來越多的高校基于RISC-V架構(gòu)開展教學(xué)[5-6]。
中斷和異常處理是現(xiàn)代CPU的必備功能,在實(shí)現(xiàn)I/O交互、軟硬件故障處理、操作系統(tǒng)功能調(diào)用及并發(fā)機(jī)制等方面,有著不可替代的作用[7-8]。中斷原理抽象,涉及指令集體系架構(gòu)的底層,是計算機(jī)組成原理課程的難點(diǎn)之一。在課程前期實(shí)驗中,學(xué)生已經(jīng)完成了25 ~37 條RV32I 指令子集的多周期CPU 設(shè)計,但中斷實(shí)驗比較繁瑣、復(fù)雜,尤其對于地方高校學(xué)生,實(shí)驗難度較大。本文秉承“精簡開放,重在方法”的設(shè)計理念,基于32 位多周期RISC-V架構(gòu),提出了一種精簡的中斷實(shí)驗方案,引導(dǎo)學(xué)生使用FPGA工具,設(shè)計實(shí)現(xiàn)一個能處理單重可屏蔽外部中斷的模型機(jī),使學(xué)生理解中斷原理、學(xué)會設(shè)計中斷CPU。
RISC-V具有用戶、監(jiān)控和機(jī)器3 種工作模式,規(guī)范中要求必須實(shí)現(xiàn)擁有最高特權(quán)級的機(jī)器模式(M-mode)。RISC-V 設(shè)有4 096 個控制與狀態(tài)寄存器CSR,其中6 個與機(jī)器模式下外部中斷相關(guān),圖1 給出了它們的結(jié)構(gòu)、部分字段含義,忽略了用戶模式、監(jiān)控模式以及其他中斷類型[9]。

圖1 RISC-V機(jī)器模式下外部中斷相關(guān)的CSR寄存器
本實(shí)驗處理的是機(jī)器模式外部中斷,故Interrupt=1,編號為11;采用直接尋址方式轉(zhuǎn)入中斷服務(wù)程序ISR,故mtvec.MODE =0。
RISC-V標(biāo)準(zhǔn)通過平臺級中斷控制器PLIC完成對外部中斷的判優(yōu)及處理[10]。本實(shí)驗只處理1 個外部中斷源,設(shè)計的簡單PLIC如圖2 所示。

圖2 CSR及中斷控制器模塊
(1)CSR 寄存器及讀寫控制。用于實(shí)現(xiàn)CSR 讀寫指令。實(shí)現(xiàn)了圖1 的6 個CSR寄存器,csr_out始終讀出地址為csr_A的CSR寄存器內(nèi)容,記為CSR[csr_A];顯然需要進(jìn)行非完全地址譯碼。當(dāng)csr_Write =1時,在csr_clk上跳沿執(zhí)行對CSR[csr_A]的寫操作,寫入的數(shù)據(jù)是CSR[csr_A]和rs1_data 的運(yùn)算結(jié)果csr_in。運(yùn)算由獨(dú)立的運(yùn)算器完成,功能由csr_op 指定:=01,輸出rs1_data;=10,進(jìn)行或運(yùn)算;=11,進(jìn)行rs1_data & CSR[csr_A]運(yùn)算。csr_op取自CSR指令funct3[1:0]。
(2)中斷控制邏輯。用于中斷請求、響應(yīng)與返回。INTR是CPU外部中斷請求輸入引腳,上跳沿來臨時,置位mip.MEIP。如圖3 所示,此時如果開中斷且未屏蔽,則輸出int =1,送至控制單元CU處理。

圖3 RISC-V中斷過程的具體操作
本條指令執(zhí)行完后,如果CU檢測到int =1,則發(fā)送中斷響應(yīng)信號int_ack,執(zhí)行圖3 中的中斷隱指令操作。針對本實(shí)驗的外部中斷:保存的斷點(diǎn)mepc_in 是PC;且Interrupt =1,E_Code =11;轉(zhuǎn)入ISR的方法是直接將mtvec內(nèi)容置入PC。
CPU通過執(zhí)行中斷服務(wù)程序ISR來處理中斷,ISR的最后一條指令一定是中斷返回指令,RISC-V機(jī)器模式下就是mret指令。執(zhí)行mret指令時,需要發(fā)送中斷返回信號int_ret以返回斷點(diǎn),具體操作見圖3。
外部中斷處理后,通常是由軟件(譬如讀中斷狀態(tài)寄存器)來復(fù)位外部中斷請求。圖2 中,硬件上使用clr_M(jìn)EIP信號清除mip.MEIP。那么由誰、何時發(fā)送clr_M(jìn)EIP 信號呢?實(shí)驗用存儲器地址2000 0000H映射了一個自定義寄存器mipc[11],當(dāng)軟件寫該地址時,clr_M(jìn)EIP置1,從而復(fù)位MEIP。
6 個CSR寄存器要對其敏感的控制信號做出響應(yīng),下面給出mip寄存器的Verilog代碼示例。
assign clr_M(jìn)EIP =(F ==32’h2000_0000)&& Mem_Write;
always @(negedge rst_n or posedge csr_clk or posedge INTR or
posedge clr_M(jìn)EIP) / /mip寄存器
begin
if(!rst_n) mip <=32'h0;
else if(INTR) mip[11]<=1′b1;/ /MEIP =1
else if(clr_M(jìn)EIP) mip[11]<=1′b0;/ /MEIP =0
else if(csr_Write &&(csr_A ==12′h344)) / /寫mip
mip <=csr_in; / /csr_in =CSR[csr_A]csr_op rs1_data
end
目標(biāo)指令集包含RV32I 基礎(chǔ)指令和中斷相關(guān)指令。前期的CPU 實(shí)驗,學(xué)生已經(jīng)實(shí)現(xiàn)了至少25 條RV32I指令子集,允許學(xué)生在此基礎(chǔ)上修改添加,也可以選取表1 所示的8 條典型RV32I指令[12],或者以目標(biāo)導(dǎo)向的方式來選擇最小化指令集——以能執(zhí)行“中斷功能測試程序”為設(shè)計目標(biāo)。

表1 RV32I目標(biāo)指令子集
表2 給出了新增的2 條中斷指令和3 條CSR 指令[9],均為I型格式。CSR 指令同時完成一對原子操作:rs1 與CSR運(yùn)算后寫入CSR、CSR內(nèi)容寫入rd。

表2 中斷指令與CSR寄存器訪問指令
基于目標(biāo)指令集,設(shè)計出多周期RISC-V 中斷模型機(jī)的系統(tǒng)結(jié)構(gòu),如圖4 所示。
存儲器采用哈佛結(jié)構(gòu),指令執(zhí)行包含經(jīng)典的五階段[13-14]:取指令I(lǐng)F、譯碼-讀寄存器ID、執(zhí)行EX、訪存MEM和寫回WB。每個階段都包含了相應(yīng)的功能部件以及保存操作結(jié)果的暫存器/寄存器,例如IR、A/B/F暫存器、MDR寄存器。
初級譯碼器ID1 解析指令字段、產(chǎn)生32 位立即數(shù)imm32。譯碼及控制單元CU則進(jìn)行二次譯碼,產(chǎn)生全機(jī)的控制信號,包括中斷控制信號。
分析指令在圖4 上的數(shù)據(jù)通路,可以畫出指令執(zhí)行流程圖,如圖5 所示,虛線框表示與中斷相關(guān)。每條指令的指令周期結(jié)束后,都會轉(zhuǎn)移到公共的中斷查詢周期,詢問“int =1?”,如果為1,則轉(zhuǎn)入中斷響應(yīng)周期,執(zhí)行中斷隱指令。

圖4 多周期RISC-V中斷模型機(jī)系統(tǒng)結(jié)構(gòu)

圖5 指令執(zhí)行流程
控制單元CU是CPU控制中心,有序發(fā)送當(dāng)前指令所需的控制信號,它的設(shè)計是CPU 設(shè)計的關(guān)鍵步驟。CU可采用硬布線或有限狀態(tài)機(jī)FSM 來實(shí)現(xiàn),由學(xué)生自主選擇。FSM實(shí)現(xiàn)CU的設(shè)計步驟如下[15]:
(1)將圖5 中相同的方框合并,構(gòu)造出狀態(tài)轉(zhuǎn)移圖,如圖6 所示,依據(jù)指令操作碼執(zhí)行狀態(tài)轉(zhuǎn)移。

圖6 指令執(zhí)行的狀態(tài)轉(zhuǎn)移圖
(2)寫出每個狀態(tài)下發(fā)送的控制信號,如表3 所示。中斷相關(guān)的狀態(tài)是S14~S18;表格中未出現(xiàn)的狀態(tài)不發(fā)送有效控制信號,僅由clk 控制操作。例如S16和S17狀態(tài),僅根據(jù)int信號確定下一狀態(tài)。

表3 各狀態(tài)下指令發(fā)送的控制信號
(3)采用FPGA兩段式或三段式有限狀態(tài)機(jī)描述狀態(tài)轉(zhuǎn)移圖,并發(fā)送控制信號。
設(shè)計完成CU 后,將它和其他部件連接起來就構(gòu)成了RISC-V的模型計算機(jī)。
為測試外部中斷,將CPU 的INTR 接到一個按鍵上,每按下一次,就產(chǎn)生一次中斷。假設(shè)CPU 對外部中斷的處理是將x6 寄存器內(nèi)容減1,為0 時結(jié)束主程序,測試程序如下:
main: #主程序,地址00H
addi x5,x0,0x20 #取ISR_DEC入口地址0x20→x5
csrrw x0,mtvec,x5 #裝中斷向量(x5)到mtvec
addi x6,x0,3 #中斷次數(shù)3→x6,3次結(jié)束主程序
L: wfi #等待外部中斷
beq x6,x0,exit # x6 =0結(jié)束主程序,否則順序執(zhí)行
j L #x6≠0,則跳轉(zhuǎn)L,繼續(xù)等待中斷
exit:wfi #相當(dāng)于空指令/占位符
wfi #相當(dāng)于空指令/占位符
ISR_DEC: #中斷服務(wù)子程序,地址20H
lui x7,0x20000 #x7 =0x2000_0000
sw x0,0(x7) #寫0x2000_0000產(chǎn)生clr_M(jìn)EIP
addi x6,x6,-1 #中斷處理操作,x6-1
mret #中斷返回
將測試程序翻譯成機(jī)器語言程序,裝入指令存儲器IM,即可設(shè)計驗證方案,重點(diǎn)驗證wfi 指令、mret 指令和中斷隱指令,能否正確轉(zhuǎn)移。圖7(a)給出了wfi指令(編碼10500073H)發(fā)生外部中斷時的仿真波形圖,狀態(tài)機(jī)當(dāng)前狀態(tài)ST 從S16(0x10)轉(zhuǎn)移到S17(0x11),再轉(zhuǎn)入S18(0x12)進(jìn)行中斷響應(yīng),圖7(a)黃線顯示PC 被修改為ISR_DEC 的入口地址20H。圖7(b)是相應(yīng)的板級驗證,左邊5 位LED燈是ST狀態(tài)。當(dāng)ST =10000b(S16)時,按clk 鍵狀態(tài)保持不變,但是按一次INTR鍵后再按clk鍵,狀態(tài)會變成10001b(S17),進(jìn)而變成10010b(S18),正確響應(yīng)了中斷。3 次中斷后,主程序停在exit 處。驗證結(jié)果表明中斷實(shí)驗的CPU運(yùn)行正確。

圖7 實(shí)驗驗證
基本要求之外,實(shí)驗設(shè)置了豐富的思考與探索題,要求學(xué)生至少回答或?qū)嵺`兩個。例如:能否在執(zhí)行mret指令時清除mip.MEIP?能否合并狀態(tài)S16和S17?能否取消S17狀態(tài),以使所有指令周期縮短1 個clk?CSR指令的運(yùn)算操作能否用主ALU 實(shí)現(xiàn)?如何修改設(shè)計,以支持中斷嵌套?如果要實(shí)現(xiàn)支持8 個硬件中斷源的PLIC呢?如果外部中斷請求的操作是從開關(guān)讀入一個數(shù)據(jù)存入主存,如何修改設(shè)計方案?
思考與探索環(huán)節(jié)促進(jìn)學(xué)生養(yǎng)成勤于分析思考、善于推導(dǎo)求證、敢于探索實(shí)踐的習(xí)慣,學(xué)生逐漸由被動到主動,很大程度上激發(fā)了學(xué)生硬件學(xué)習(xí)實(shí)踐的興趣。
中斷是CPU處理突發(fā)事件、實(shí)現(xiàn)操作系統(tǒng)核心功能的重要手段。基于FPGA 實(shí)驗平臺,本文設(shè)計了一個功能精簡、原理深入的中斷實(shí)驗,通過實(shí)現(xiàn)32 位RISC-V多周期中斷CPU,達(dá)成了“理解中斷原理、學(xué)會簡單的中斷CPU設(shè)計實(shí)現(xiàn)”的教學(xué)目標(biāo)。在指令集選擇、指令流程設(shè)計、CU 實(shí)現(xiàn)、測試程序及實(shí)驗驗證等各環(huán)節(jié),均設(shè)置多元開放的實(shí)驗要求,讓學(xué)生自主選擇、組織與架構(gòu),實(shí)現(xiàn)自己的中斷CPU。實(shí)驗設(shè)計注重學(xué)思結(jié)合、知行統(tǒng)一,鍛煉了學(xué)生的分析研究與系統(tǒng)設(shè)計的能力,在教學(xué)實(shí)踐中,取得了良好的教學(xué)效果。