文章目錄
RISC-V處理器的設(shè)計與實現(xiàn)(一)—— 基本指令集_Patarw_Li的博客-CSDN博客
RISC-V處理器的設(shè)計與實現(xiàn)(二)—— CPU框架設(shè)計_Patarw_Li的博客-CSDN博客
RISC-V處理器的設(shè)計與實現(xiàn)(三)—— 上板驗證_Patarw_Li的博客-CSDN博客
RISC-V處理器設(shè)計(四)—— Verilog 代碼設(shè)計-CSDN博客?
RISC-V處理器設(shè)計(五)—— 在 RISC-V 處理器上運行 C 程序-CSDN博客?
本人小白一枚,在學(xué)習(xí)FPGA的過程中偶然刷到了tinyriscv這個開源項目,并且自己對計算機體系結(jié)構(gòu)的知識也很感興趣,所以想?yún)⒖歼@個開源項目做一個基于RISC-V指令集的CPU,本項目很多思路和設(shè)計都參考了tinyriscv開源項目。
本人自己做的 riscv-cpu 項目倉庫(如果覺得對你有幫助請一定一定點個 star?。?/strong>:?
riscv-cpu: 一個基于RISC-V指令集的CPU實現(xiàn)(成功移植到野火征途PRO開發(fā)板)
在設(shè)計RISC-V處理器之前,我們首先要做的事就是指令集的選取,指令集是一個CPU的基石,要實現(xiàn)CPU 計算和控制功能,就必須定義好一系列與硬件電路相匹配的指令系統(tǒng)。下面是RISC-V官方給出的指令集架構(gòu):
因為是第一次做,所以我們選擇簡單一點的32位基本指令集,也就是RV32I 基本指令集(目前增加了RV32M擴展)。
RV32I 基本指令集有6種格式,分別是:
目的 | 類型 |
---|---|
用于寄存器-寄存器操作 | R 類型指令 |
用于短立即數(shù)和訪存 load 操作 | I 型指令 |
用于訪存 store 操作 | S 型指令 |
用于條件跳轉(zhuǎn)操作 | SB 類型指令 |
用于長立即數(shù) | U 型指令 |
用于無條件跳轉(zhuǎn) | UJ 型指令 |
RV32I 基本指令集有47條指令,如下圖:
本項目目前除了 FENCE 指令其他的都已經(jīng)實現(xiàn),下面介紹了一下這些指令的用法,這里給大家先推薦一個好用的工具叫Ripes,可以到上面運行riscv匯編指令,并且可以把對應(yīng)的指令轉(zhuǎn)成二進制機器碼,方便我們后面的仿真:
Releases · mortbopet/Ripes · GitHub
下面我們開始指令的介紹。
RV32I 基本指令集
1. LUI?
語法:lui rd, imm,作用是將立即數(shù)imm邏輯左移12位,結(jié)果寫入rd寄存器(立即數(shù)是無符號數(shù))。
我們在ripes運行如下例子來看看結(jié)果:
lui x1,1
lui x2,255
如下是運行結(jié)果,可以看到寄存器內(nèi)的數(shù)值都是立即數(shù)左移12位的結(jié)果(16進制):?
2. AUIPC?
語法:auipc rd, imm,作用是將立即數(shù)imm邏輯左移12位,然后加上當前指令PC的值,結(jié)果寫入rd寄存器(立即數(shù)是無符號數(shù))。
我們可以通過將立即數(shù)的值設(shè)置為0來計算PC的值:
auipc x1,0
auipc x2,0
auipc x3,0
auipc x4,4
運行結(jié)果如下:?
?
3. JAL(無條件跳轉(zhuǎn)指令)
語法:jal rd, imm,作用是將PC的值加上4,結(jié)果寫入rd寄存器,rd默認為x1,同時將PC的值設(shè)置為當前jal指令地址PC加上符號位拓展的imm。?
我們可以通過這個指令來跳到指定的指令執(zhí)行:?
auipc x2,0
auipc x3,0
auipc x4,4
jal x1,-12
?可以看到上述指令會一直循環(huán)執(zhí)行。
4. JALR(無條件跳轉(zhuǎn)指令,寄存器相對尋址)
語法:jalr rd, rs1,imm,作用是將PC的值加上4,結(jié)果寫入rd寄存器,rd默認為x1,同時將當前PC值設(shè)置為寄存器rs1的值加上符號位拓展的imm。
功能和JAL指令一樣,不過計算跳轉(zhuǎn)地址的方式不一樣,JAL指令跳轉(zhuǎn)地址為PC+imm,而JALR指令跳轉(zhuǎn)地址為寄存器rs1內(nèi)容+imm:?
addi x1,x0,8
auipc x2,0
auipc x3,0
auipc x4,4
jalr x5,x1,4
因為第4條指令的地址為12,寄存器x1的內(nèi)容8+立即數(shù)4等于12,所以可以看到程序跳轉(zhuǎn)到第四條指令執(zhí)行:
5. BEQ(分支跳轉(zhuǎn)指令,相等時跳轉(zhuǎn))
語法:beq rs1, rs2, imm,作用是如果rs1的值等于rs2的值,則將PC設(shè)置為符號當前指令beq地址+符號位拓展的立即數(shù)imm。?
addi x1,x0,1
addi x2,x0,2
add x1,x1,x1
beq x1,x2,-4
?執(zhí)行結(jié)果如下,可以看到第三條add指令執(zhí)行了兩次:
?
6. BNE(分支跳轉(zhuǎn)指令,不等時跳轉(zhuǎn))
語法:bne rs1, rs2, imm,作用是如果rs1的值不等于rs2的值,則將PC設(shè)置為符號當前指令bne地址+符號位拓展的立即數(shù)imm。?
addi x1,x0,1
addi x2,x0,8
add x1,x1,x1
bne x1,x2,-4
?執(zhí)行結(jié)果如下,可以看到第三條add指令執(zhí)行了三次:
7. BLT(分支跳轉(zhuǎn)指令,小于時跳轉(zhuǎn))
語法:blt rs1, rs2, imm,作用是如果rs1的值小于rs2的值,則將PC設(shè)置為符號當前指令blt地址+符號位拓展的立即數(shù)imm。
addi x1,x0,1
addi x2,x0,8
add x1,x1,x1
blt x1,x2,-4
?執(zhí)行結(jié)果如下,可以看到第三條add指令執(zhí)行了三次:
8. BGE(分支跳轉(zhuǎn)指令,大于等于時跳轉(zhuǎn))
語法:bge rs1, rs2, imm,作用是如果rs1的值大于或等于rs2的值,則將PC設(shè)置為符號當前指令bge地址+符號位拓展的立即數(shù)imm。
addi x1,x0,10
addi x2,x0,8
addi x1,x1,-1
bge x1,x2,-4
執(zhí)行結(jié)果如下,可以看到第三條addi指令執(zhí)行了三次:
9. BLTU(分支跳轉(zhuǎn)指令,無符號數(shù)比較,小于時跳轉(zhuǎn))
語法:bltu rs1, rs2, imm,作用是如果rs1的值小于rs2的值(rs1和rs2為無符號數(shù)),則將PC設(shè)置為符號當前指令bltu地址+符號位拓展的imm。?
10. BGEU(分支跳轉(zhuǎn)指令,無符號數(shù)比較,大于或等于時跳轉(zhuǎn))
語法:bgeu rs1, rs2, imm,作用是如果rs1的值大于或等于rs2的值(rs1和rs2為無符號數(shù)),則將PC設(shè)置為符號當前指令bgeu地址+符號位拓展的imm。??
BLTU、BGEU和BLT、BGE的區(qū)別在于一個是無符號數(shù)比較,一個是有符號數(shù)比較。
如下兩個示例,執(zhí)行結(jié)果是不一樣的:
addi x1,x0,-1
addi x2,x0,8
addi x1,x1,-1
bge x1,x2,-4
addi x1,x0,-1
addi x2,x0,8
addi x1,x1,-1
bgeu x1,x2,-4
11. LB(訪存指令,一字節(jié))
語法:lb rd, imm, rs1,作用是從處讀rs1加上imm的地址取一個字節(jié)的內(nèi)容,并將該內(nèi)容經(jīng)符號位擴展后寫入rd寄存器。
addi x1,x0,-1
lb x3,1,x1
執(zhí)行結(jié)果如下,可以看到memory內(nèi)第一個字節(jié)的數(shù)據(jù)被符號位擴展后送入寄存器x3:
?
12. LH(訪存指令,兩字節(jié))
語法:lh rd, imm, rs1,作用是從處讀rs1加上imm的地址取兩個字節(jié)的內(nèi)容,并將該內(nèi)容經(jīng)符號位擴展后寫入rd寄存器。
addi x1,x0,0
lh x3,4,x1
執(zhí)行結(jié)果如下,可以看到memory內(nèi)地址4的兩個字節(jié)數(shù)據(jù)被符號位拓展后送入x3:
13. LW(訪存指令,四字節(jié))
語法:lw rd, imm, rs1,作用是從處讀rs1加上imm的地址取四個字節(jié)的內(nèi)容,并將該內(nèi)容寫入rd寄存器(因為四字節(jié)位數(shù)和寄存器位數(shù)相同,所以無需符號位拓展)。
addi x1,x0,0
lw x3,4,x1
?執(zhí)行結(jié)果如下,可以看到memory內(nèi)地址4的四個字節(jié)數(shù)據(jù)被送入x3:
?
14. LBU(訪存指令,一字節(jié),無需符號位拓展)
語法:lbu rd, imm, rs1,作用是從處讀rs1加上imm的地址取一個字節(jié)的內(nèi)容,并將該內(nèi)容經(jīng)高位補0后寫入rd寄存器。
15. LHU(訪存指令,兩字節(jié),無需符號位拓展)
語法:lhu rd, imm, rs1,作用是從處讀rs1加上imm的地址取兩個字節(jié)的內(nèi)容,并將該內(nèi)容經(jīng)高位補0后寫入rd寄存器。
16. SB(訪存指令,一字節(jié))
語法:sb rs2, imm, rs1,作用是將rs2的低八位寫入rs1加上imm的地址處。
addi x1,x0,-1
sb x1,0,x0
執(zhí)行結(jié)果如下:?
17. SH(訪存指令,兩字節(jié))
語法:sh rs2, imm, rs1,作用是將rs2的低16位寫入rs1加上imm的地址處。?
addi x1,x0,-1
sh x1,0,x0
執(zhí)行結(jié)果如下:?
?
18. SW(訪存指令,四字節(jié))?
語法:sw rs2, imm, rs1,作用是將rs2寫入rs1加上imm的地址處。?
addi x1,x0,-1
sw x1,0,x0
19. ADDI
語法:addi rd, rs1, imm,作用是將符號擴展的立即數(shù)imm的值加上rs1的值,結(jié)果寫入rd寄存器,忽略算術(shù)溢出。
addi x1,x0,-1
addi x2,x1,2
執(zhí)行結(jié)果如下:?
20. SLTI(小于置1)
語法:slti rd, rs1, imm,作用是將符號擴展的立即數(shù)imm的值與rs1的值比較(有符號數(shù)比較),如果rs1 < imm,則向rd寄存器寫1,否則寫0。
addi x1,x0,-1
slti x2,x1,2
執(zhí)行結(jié)果如下:??
21. SLTIU(小于置1,無符號比較)
語法:sltiu rd, rs1, imm,作用是將符號位拓展的立即數(shù)imm作為作為無符號數(shù)與rs1的值比較(無符號數(shù)比較),如果rs1 < imm,則向rd寄存器寫1,否則寫0。(一定要將上面的話理解清楚,不然設(shè)計的時候會出問題)
addi x1,x0,-1
sltiu x2,x1,2
執(zhí)行結(jié)果如下,可以看到x2結(jié)果變?yōu)榱?:??
22. XORI(異或)
語法:xori rd, rs1, imm,作用是將rs1與符號位擴展的imm按位異或,結(jié)果寫入rd寄存器。
23. ORI
語法:ori rd, rs1, imm,作用是將rs1與符號位擴展的imm按位或,結(jié)果寫入rd寄存器。
24. ANDI
語法:andi rd, rs1, imm,作用是將rs1與符號位擴展的imm按位與,結(jié)果寫入rd寄存器。
25. SLLI(邏輯左移)
語法:slli rd, rs1, shamt,作用是將rs1左移shamt位,空出的位補0,結(jié)果寫入rd寄存器。
26. SRLI(邏輯右移)
語法:srli rd, rs1, shamt,作用是將rs1右移shamt位,空出的位補0,結(jié)果寫入rd寄存器。
27. SRAI(算術(shù)右移)
語法:srai rd, rs1, shamt,作用是將rs1右移shamt位,空出的位用rs1的最高位補充,結(jié)果寫入rd寄存器。
28. ADD
語法:add rd, rs1, rs2,作用是將rs1寄存器的值加上rs2寄存器的值,然后將結(jié)果寫入rd寄存器里,忽略算術(shù)溢出。
29. SUB
語法:sub rd, rs1, rs2,作用是將rs1寄存器的值減去rs2寄存器的值,然后將結(jié)果寫入rd寄存器里,忽略算術(shù)溢出。
30. SLL
語法:sll rd, rs1, rs2,作用是將rs1左移rs2位(低5位有效),空出的位補0,結(jié)果寫入rd寄存器。
31. SLT
語法:slt rd, rs1, rs2,作用是將rs1的值與rs2的值比較(有符號數(shù)比較),如果rs1的值更小,則向rd寄存器寫1,否則寫0。
32. SLTU
語法:sltu rd, rs1, rs2,作用是將rs1的值與rs2的值比較(無符號數(shù)比較),如果rs1的值更小,則向rd寄存器寫1,否則寫0。
33. XOR
語法:xor rd, rs1, rs2,作用是將rs1與rs2按位異或,結(jié)果寫入rd寄存器。
34. SRL
語法:srl rd, rs1, rs2,作用是將rs1右移rs2位(低5位有效),空出的位補0,結(jié)果寫入rd寄存器。
35. SRA
語法:sra rd, rs1, rs2,作用是將rs1右移rs2位(低5位有效),空出的位用rs1的最高位補充,結(jié)果寫入rd寄存器。
36. OR
語法:or rd, rs1, rs2,作用是將rs1與rs2按位或,結(jié)果寫入rd寄存器。
37. AND
語法:and rd, rs1, rs2,作用是將rs1與rs2按位與,結(jié)果寫入rd寄存器。
RV32M 擴展指令集
1. MUL
語法:mul rd, rs1, rs2,作用是將rs1與rs2相乘,結(jié)果的低32位寫入rd寄存器。
2. MULH
語法:mulh rd, rs1, rs2,作用是將rs1與rs2相乘,結(jié)果的高32位寫入rd寄存器。
3. MULHSU
語法:mulhsu rd, rs1, rs2,作用是將rs1與rs2相乘,其中rs1為有符號數(shù),rs2為無符號數(shù),結(jié)果的高32位寫入rd寄存器。
4. MULHU
語法:mulhu rd, rs1, rs2,作用是將rs1與rs2相乘,其中rs1、rs2均為無符號數(shù),結(jié)果的高32位寫入rd寄存器。
5. DIV
語法:div rd, rs1, rs2,作用是將rs1與rs2相除,結(jié)果的商寫入rd寄存器。
6. DIVU
語法:divu rd, rs1, rs2,作用是將rs1與rs2相除,其中rs1、rs2均為無符號數(shù),結(jié)果的商寫入rd寄存器。
7. REM
語法:rem rd, rs1, rs2,作用是將rs1與rs2相除,結(jié)果的余數(shù)寫入rd寄存器。
8. REMU
語法:remu rd, rs1, rs2,作用是將rs1與rs2相除,其中rs1、rs2均為無符號數(shù),結(jié)果的余數(shù)寫入rd寄存器。
以上就是目前所用到的指令了,之后如果添加新的指令會在這里更新。
之后我會還會出新文章更新具體設(shè)計部分的內(nèi)容,大家看了如果覺得有幫助請點個小小的贊吧~文章來源:http://www.zghlxwxcb.cn/news/detail-752369.html
如果遇到問題也歡迎加群 892873718 交流~文章來源地址http://www.zghlxwxcb.cn/news/detail-752369.html
到了這里,關(guān)于RISC-V處理器的設(shè)計與實現(xiàn)(一)—— 基本指令集的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!