簡易RISC-V處理器設(shè)計 (一.RISC-V指令集)

本文為通過Verliog HDL編寫簡易RISC-V CPU的試驗筆記,如有錯誤敬請指正

一.RISC-V
RISC-V為伯克利研究團(tuán)隊基于精簡指令集計算原理建立的一個開放指令集架構(gòu)。由于其開源、模型化及指令長度固定等特點而被應(yīng)用于學(xué)習(xí)及嵌入式領(lǐng)域當(dāng)中。
詳見:什么是RISC-V-知乎(https://zhuanlan.zhihu.com/p/49176102)
二.RISC-V指令
作為大型開源項目,RISC-V的官方技術(shù)文檔可于Github上搜索得到并下載。此外,CSDN及知乎上亦有相關(guān)指令集介紹與表格可供參考,因此本文僅對RISC-V的指令架構(gòu)作簡略描述。
RISC-V指令結(jié)構(gòu)
RISC-V指令包含數(shù)個主要結(jié)構(gòu),分別為訪問寄存器的R-Type,使指指令中立即數(shù)進(jìn)行操作的I-Type,儲存至內(nèi)存中的S-Type,判斷分支執(zhí)行的B-Type,執(zhí)行跳轉(zhuǎn)的J-Type,以及包含20位立即數(shù)的U-Type。
對于下方圖表,opcode為指令操作碼,rs1與rs2均為源寄存器地址,rd為目標(biāo)寄存器地址,funct3及funct7為操作指令,imm為立即數(shù),即計算機(jī)對該數(shù)據(jù)進(jìn)行簡易操作(擴(kuò)展)后直接傳遞至計算單元進(jìn)行運算的數(shù)據(jù),其特點為數(shù)據(jù)被保存至指令中而無需訪問寄存器。下表中imm[ ]表示數(shù)據(jù)的長度為
位二進(jìn)制編碼,其順序按高至低位排列,如11-0,20-0。

RV32指令集的指令位寬及數(shù)據(jù)位寛均為32位,寄存器地址長度為5位,最多可支持個寄存器,此外,由于指令不支持直接寫入結(jié)果至內(nèi)存,該指令集對寄存器的操作頻率將較其他指令集高。
RV32I 基礎(chǔ)整數(shù)指令集
RV32I Base Integer Instructions ( 32位基礎(chǔ)整數(shù)指令集 )
RV32I主要包含37條運行指令與2條系統(tǒng)指令。相應(yīng)的指令表格可通過RSIC-V Reference Card或RISC官方技朮文檔得到。

詳見:
RISC-V Reference Card - Github
(https://github.com/jameslzhu/riscv-card)
RISC-V Instruction Set Manual - RISC-V International
(https://riscv.org/technical/specifications/)
寄存器的數(shù)學(xué)/邏輯運算指令
按R-Type結(jié)構(gòu)進(jìn)行編碼,其指令操作碼均為七位二進(jìn)位數(shù)的(0110011),按funct3判斷數(shù)據(jù)的運算類型。
以算朮加法ADD為例,其funct3為三位二進(jìn)制的000,操作內(nèi)容為從地址rs1及rs2對應(yīng)的32位寄存器中取數(shù)據(jù)后通過算朮單元進(jìn)行算朮加法,隨后輸出計算結(jié)果并儲存至rd地址所對應(yīng)的32位寄存器中。完成此流程則認(rèn)為該指令執(zhí)行完結(jié)。
下式為ADD指令的一個例子,該指令的rd為,rs1為
,rs2為
,funct3為
,funct7為
。
附注:
SUB(算朮減法)指令與ADD共用一個funct3值,需通過funct7進(jìn)行判別。
SRA(循環(huán)右移)指令與SRL共用一個funct3值,需通過funct7進(jìn)行判別。
SRA(循環(huán)右移)指令將數(shù)據(jù)的最右位循環(huán)至數(shù)據(jù)的的最高位。
SLT指令視數(shù)據(jù)為符號數(shù)進(jìn)行比較,SLTU指令則視數(shù)據(jù)為無符號數(shù)進(jìn)行比較。
立即數(shù)的數(shù)學(xué)/邏輯運算指令
按I-Type結(jié)構(gòu)進(jìn)行編碼,其指令操作碼均為七位二進(jìn)位數(shù)的(0010011),按funct3判斷數(shù)據(jù)的運算類型。
以算朮加法ADDI為例,其funct3為三位二進(jìn)制的000,執(zhí)行步驟為從地址rs1對應(yīng)的32位寄存器中取數(shù)據(jù),同時擴(kuò)展立即數(shù)至32位數(shù)值,隨后通過算朮單元進(jìn)行算朮加法,完成后輸出計算結(jié)果儲存至地址rd所對應(yīng)的32位寄存器中。完成此流程則認(rèn)為該指令執(zhí)行完結(jié)。
下式為ADDI指令的一個例子,對應(yīng)的rd為,rs1為
,funct3為
。
附注:
一. 符號擴(kuò)展:
立即數(shù)指令默認(rèn)進(jìn)行符號擴(kuò)展。視所有立即數(shù)通過補碼形式儲存。若立即數(shù)最高位為1,則擴(kuò)展時對其高20位補1。否則對高20位補0。
32位立即數(shù)擴(kuò)展后的結(jié)構(gòu)為imm[31:0] = { imm[31:12], imm[11:0] }
二. 零擴(kuò)展:
無論立即數(shù)的高位為何,其高位皆補零。
內(nèi)存讀取指令
按I-Type結(jié)構(gòu)進(jìn)行編碼,其指令操作碼均為七位二進(jìn)位數(shù)的(0000011),按funct3判斷數(shù)據(jù)的儲存方式。
以字加載LW為例,其funct3為三位二進(jìn)制的010,該指令先從地址rs1中取數(shù)據(jù),與符號擴(kuò)展的12位立即數(shù)進(jìn)行符號算朮加法,并輸出計算結(jié)果至32位地址總線,內(nèi)存則通過地址總線上的值讀出數(shù)據(jù)。并寫入該數(shù)據(jù)至地址rd對應(yīng)的寄存器。
下式為LW指令的一個例子,其以rs1寄存器的值為基點偏移()后的內(nèi)存位置讀出一個字至rd寄存器中。
附注:?
假設(shè)rs1中的值為32,則訪問的內(nèi)存位置為(32+(-24)) = 8,即rd = M[8][31:0]
上述表格未表示M的內(nèi)存地址,完整的描述為M[rs1+imm][31:0]
內(nèi)存儲存指令
按S-Type結(jié)構(gòu)進(jìn)行編碼,其指令操作碼均為七位二進(jìn)位數(shù)的(0100011),按funct3判斷數(shù)據(jù)的儲存方式。
以字加載SW為例,其funct3為三位二進(jìn)制的010,該指令先從rs1中取數(shù)據(jù),與符號擴(kuò)展的12位立即數(shù)進(jìn)行符號算朮加法,并輸出計算結(jié)果至32位地址總線,指令同時取出rs2的值輸出至數(shù)據(jù)總線。內(nèi)存則通過地址總線及數(shù)據(jù)總線上的值。寫入該數(shù)據(jù)至地址對應(yīng)的區(qū)域。
下式為SW指令的一個例子,該指令將rs2的值寫入以rs1為基點偏移()后的內(nèi)存位置。
程序計數(shù)器的分支跳轉(zhuǎn)
按B-Type結(jié)構(gòu)進(jìn)行編碼,其指令操作碼均為七位二進(jìn)位數(shù)的(1100011),按funct3實施不同的跳轉(zhuǎn)策略。
以大于跳轉(zhuǎn)BGE為例,其funct3為三位二進(jìn)制的101,該指令先從rs1與rs2中取數(shù)據(jù),并判斷rs1是否大等于于rs2,若真則修改PC的值為。若否則使PC = PC + 4。
下式為BGE指令的一個例子,若rs1值大于等于rs2,則PC跳轉(zhuǎn)至
附注:
BLTU及BGEU對立即數(shù)進(jìn)行零擴(kuò)展而非符號擴(kuò)展。
程序計數(shù)器( Program Counter ) - 百度百科(https://baike.baidu.com/item/%E7%A8%8B%E5%BA%8F%E8%AE%A1%E6%95%B0%E5%99%A8/3219536)
其他指令
由于所有RV32I指令均已在上表中給出,故其他指令不作描述。
作者個人Blog :?https://starryphantom.github.io/