技术标签: fpga开发 学习 risc-v RISC-V处理器设计
RISC-V处理器的设计与实现(一)—— 基本指令集_Patarw_Li的博客-程序员宅基地
RISC-V处理器的设计与实现(二)—— CPU框架设计_Patarw_Li的博客-程序员宅基地
RISC-V处理器的设计与实现(三)—— 上板验证_Patarw_Li的博客-程序员宅基地
RISC-V处理器设计(四)—— Verilog 代码设计-程序员宅基地
RISC-V处理器设计(五)—— 在 RISC-V 处理器上运行 C 程序-程序员宅基地
本人小白一枚,在学习FPGA的过程中偶然刷到了tinyriscv这个开源项目,并且自己对计算机体系结构的知识也很感兴趣,所以想参考这个开源项目做一个基于RISC-V指令集的CPU,本项目很多思路和设计都参考了tinyriscv开源项目。
本人自己做的 riscv-cpu 项目仓库(如果觉得对你有帮助请一定一定点个 star!):
riscv-cpu: 一个基于RISC-V指令集的CPU实现(成功移植到野火征途PRO开发板)
在设计RISC-V处理器之前,我们首先要做的事就是指令集的选取,指令集是一个CPU的基石,要实现CPU 计算和控制功能,就必须定义好一系列与硬件电路相匹配的指令系统。下面是RISC-V官方给出的指令集架构:
因为是第一次做,所以我们选择简单一点的32位基本指令集,也就是RV32I 基本指令集(目前增加了RV32M扩展)。
RV32I 基本指令集有6种格式,分别是:
目的 | 类型 |
---|---|
用于寄存器-寄存器操作 | R 类型指令 |
用于短立即数和访存 load 操作 | I 型指令 |
用于访存 store 操作 | S 型指令 |
用于条件跳转操作 | SB 类型指令 |
用于长立即数 | U 型指令 |
用于无条件跳转 | UJ 型指令 |
RV32I 基本指令集有47条指令,如下图:
本项目目前除了 FENCE 指令其他的都已经实现,下面介绍了一下这些指令的用法,这里给大家先推荐一个好用的工具叫Ripes,可以到上面运行riscv汇编指令,并且可以把对应的指令转成二进制机器码,方便我们后面的仿真:
Releases · mortbopet/Ripes · GitHub
下面我们开始指令的介绍。
1. LUI
语法:lui rd, imm,作用是将立即数imm逻辑左移12位,结果写入rd寄存器(立即数是无符号数)。
我们在ripes运行如下例子来看看结果:
lui x1,1
lui x2,255
如下是运行结果,可以看到寄存器内的数值都是立即数左移12位的结果(16进制):
2. AUIPC
语法:auipc rd, imm,作用是将立即数imm逻辑左移12位,然后加上当前指令PC的值,结果写入rd寄存器(立即数是无符号数)。
我们可以通过将立即数的值设置为0来计算PC的值:
auipc x1,0
auipc x2,0
auipc x3,0
auipc x4,4
运行结果如下:
3. JAL(无条件跳转指令)
语法:jal rd, imm,作用是将PC的值加上4,结果写入rd寄存器,rd默认为x1,同时将PC的值设置为当前jal指令地址PC加上符号位拓展的imm。
我们可以通过这个指令来跳到指定的指令执行:
auipc x2,0
auipc x3,0
auipc x4,4
jal x1,-12
可以看到上述指令会一直循环执行。
4. JALR(无条件跳转指令,寄存器相对寻址)
语法:jalr rd, rs1,imm,作用是将PC的值加上4,结果写入rd寄存器,rd默认为x1,同时将当前PC值设置为寄存器rs1的值加上符号位拓展的imm。
功能和JAL指令一样,不过计算跳转地址的方式不一样,JAL指令跳转地址为PC+imm,而JALR指令跳转地址为寄存器rs1内容+imm:
addi x1,x0,8
auipc x2,0
auipc x3,0
auipc x4,4
jalr x5,x1,4
因为第4条指令的地址为12,寄存器x1的内容8+立即数4等于12,所以可以看到程序跳转到第四条指令执行:
5. BEQ(分支跳转指令,相等时跳转)
语法:beq rs1, rs2, imm,作用是如果rs1的值等于rs2的值,则将PC设置为符号当前指令beq地址+符号位拓展的立即数imm。
addi x1,x0,1
addi x2,x0,2
add x1,x1,x1
beq x1,x2,-4
执行结果如下,可以看到第三条add指令执行了两次:
6. BNE(分支跳转指令,不等时跳转)
语法:bne rs1, rs2, imm,作用是如果rs1的值不等于rs2的值,则将PC设置为符号当前指令bne地址+符号位拓展的立即数imm。
addi x1,x0,1
addi x2,x0,8
add x1,x1,x1
bne x1,x2,-4
执行结果如下,可以看到第三条add指令执行了三次:
7. BLT(分支跳转指令,小于时跳转)
语法:blt rs1, rs2, imm,作用是如果rs1的值小于rs2的值,则将PC设置为符号当前指令blt地址+符号位拓展的立即数imm。
addi x1,x0,1
addi x2,x0,8
add x1,x1,x1
blt x1,x2,-4
执行结果如下,可以看到第三条add指令执行了三次:
8. BGE(分支跳转指令,大于等于时跳转)
语法:bge rs1, rs2, imm,作用是如果rs1的值大于或等于rs2的值,则将PC设置为符号当前指令bge地址+符号位拓展的立即数imm。
addi x1,x0,10
addi x2,x0,8
addi x1,x1,-1
bge x1,x2,-4
执行结果如下,可以看到第三条addi指令执行了三次:
9. BLTU(分支跳转指令,无符号数比较,小于时跳转)
语法:bltu rs1, rs2, imm,作用是如果rs1的值小于rs2的值(rs1和rs2为无符号数),则将PC设置为符号当前指令bltu地址+符号位拓展的imm。
10. BGEU(分支跳转指令,无符号数比较,大于或等于时跳转)
语法:bgeu rs1, rs2, imm,作用是如果rs1的值大于或等于rs2的值(rs1和rs2为无符号数),则将PC设置为符号当前指令bgeu地址+符号位拓展的imm。
BLTU、BGEU和BLT、BGE的区别在于一个是无符号数比较,一个是有符号数比较。
如下两个示例,执行结果是不一样的:
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(访存指令,一字节)
语法:lb rd, imm, rs1,作用是从处读rs1加上imm的地址取一个字节的内容,并将该内容经符号位扩展后写入rd寄存器。
addi x1,x0,-1
lb x3,1,x1
执行结果如下,可以看到memory内第一个字节的数据被符号位扩展后送入寄存器x3:
12. LH(访存指令,两字节)
语法:lh rd, imm, rs1,作用是从处读rs1加上imm的地址取两个字节的内容,并将该内容经符号位扩展后写入rd寄存器。
addi x1,x0,0
lh x3,4,x1
执行结果如下,可以看到memory内地址4的两个字节数据被符号位拓展后送入x3:
13. LW(访存指令,四字节)
语法:lw rd, imm, rs1,作用是从处读rs1加上imm的地址取四个字节的内容,并将该内容写入rd寄存器(因为四字节位数和寄存器位数相同,所以无需符号位拓展)。
addi x1,x0,0
lw x3,4,x1
执行结果如下,可以看到memory内地址4的四个字节数据被送入x3:
14. LBU(访存指令,一字节,无需符号位拓展)
语法:lbu rd, imm, rs1,作用是从处读rs1加上imm的地址取一个字节的内容,并将该内容经高位补0后写入rd寄存器。
15. LHU(访存指令,两字节,无需符号位拓展)
语法:lhu rd, imm, rs1,作用是从处读rs1加上imm的地址取两个字节的内容,并将该内容经高位补0后写入rd寄存器。
16. SB(访存指令,一字节)
语法:sb rs2, imm, rs1,作用是将rs2的低八位写入rs1加上imm的地址处。
addi x1,x0,-1
sb x1,0,x0
执行结果如下:
17. SH(访存指令,两字节)
语法:sh rs2, imm, rs1,作用是将rs2的低16位写入rs1加上imm的地址处。
addi x1,x0,-1
sh x1,0,x0
执行结果如下:
18. SW(访存指令,四字节)
语法:sw rs2, imm, rs1,作用是将rs2写入rs1加上imm的地址处。
addi x1,x0,-1
sw x1,0,x0
19. ADDI
语法:addi rd, rs1, imm,作用是将符号扩展的立即数imm的值加上rs1的值,结果写入rd寄存器,忽略算术溢出。
addi x1,x0,-1
addi x2,x1,2
执行结果如下:
20. SLTI(小于置1)
语法:slti rd, rs1, imm,作用是将符号扩展的立即数imm的值与rs1的值比较(有符号数比较),如果rs1 < imm,则向rd寄存器写1,否则写0。
addi x1,x0,-1
slti x2,x1,2
执行结果如下:
21. SLTIU(小于置1,无符号比较)
语法:sltiu rd, rs1, imm,作用是将符号位拓展的立即数imm作为作为无符号数与rs1的值比较(无符号数比较),如果rs1 < imm,则向rd寄存器写1,否则写0。(一定要将上面的话理解清楚,不然设计的时候会出问题)
addi x1,x0,-1
sltiu x2,x1,2
执行结果如下,可以看到x2结果变为了0:
22. XORI(异或)
语法:xori rd, rs1, imm,作用是将rs1与符号位扩展的imm按位异或,结果写入rd寄存器。
23. ORI
语法:ori rd, rs1, imm,作用是将rs1与符号位扩展的imm按位或,结果写入rd寄存器。
24. ANDI
语法:andi rd, rs1, imm,作用是将rs1与符号位扩展的imm按位与,结果写入rd寄存器。
25. SLLI(逻辑左移)
语法:slli rd, rs1, shamt,作用是将rs1左移shamt位,空出的位补0,结果写入rd寄存器。
26. SRLI(逻辑右移)
语法:srli rd, rs1, shamt,作用是将rs1右移shamt位,空出的位补0,结果写入rd寄存器。
27. SRAI(算术右移)
语法:srai rd, rs1, shamt,作用是将rs1右移shamt位,空出的位用rs1的最高位补充,结果写入rd寄存器。
28. ADD
语法:add rd, rs1, rs2,作用是将rs1寄存器的值加上rs2寄存器的值,然后将结果写入rd寄存器里,忽略算术溢出。
29. SUB
语法:sub rd, rs1, rs2,作用是将rs1寄存器的值减去rs2寄存器的值,然后将结果写入rd寄存器里,忽略算术溢出。
30. SLL
语法:sll rd, rs1, rs2,作用是将rs1左移rs2位(低5位有效),空出的位补0,结果写入rd寄存器。
31. SLT
语法:slt rd, rs1, rs2,作用是将rs1的值与rs2的值比较(有符号数比较),如果rs1的值更小,则向rd寄存器写1,否则写0。
32. SLTU
语法:sltu rd, rs1, rs2,作用是将rs1的值与rs2的值比较(无符号数比较),如果rs1的值更小,则向rd寄存器写1,否则写0。
33. XOR
语法:xor rd, rs1, rs2,作用是将rs1与rs2按位异或,结果写入rd寄存器。
34. SRL
语法:srl rd, rs1, rs2,作用是将rs1右移rs2位(低5位有效),空出的位补0,结果写入rd寄存器。
35. SRA
语法:sra rd, rs1, rs2,作用是将rs1右移rs2位(低5位有效),空出的位用rs1的最高位补充,结果写入rd寄存器。
36. OR
语法:or rd, rs1, rs2,作用是将rs1与rs2按位或,结果写入rd寄存器。
37. AND
语法:and rd, rs1, rs2,作用是将rs1与rs2按位与,结果写入rd寄存器。
1. MUL
语法:mul rd, rs1, rs2,作用是将rs1与rs2相乘,结果的低32位写入rd寄存器。
2. MULH
语法:mulh rd, rs1, rs2,作用是将rs1与rs2相乘,结果的高32位写入rd寄存器。
3. MULHSU
语法:mulhsu rd, rs1, rs2,作用是将rs1与rs2相乘,其中rs1为有符号数,rs2为无符号数,结果的高32位写入rd寄存器。
4. MULHU
语法:mulhu rd, rs1, rs2,作用是将rs1与rs2相乘,其中rs1、rs2均为无符号数,结果的高32位写入rd寄存器。
5. DIV
语法:div rd, rs1, rs2,作用是将rs1与rs2相除,结果的商写入rd寄存器。
6. DIVU
语法:divu rd, rs1, rs2,作用是将rs1与rs2相除,其中rs1、rs2均为无符号数,结果的商写入rd寄存器。
7. REM
语法:rem rd, rs1, rs2,作用是将rs1与rs2相除,结果的余数写入rd寄存器。
8. REMU
语法:remu rd, rs1, rs2,作用是将rs1与rs2相除,其中rs1、rs2均为无符号数,结果的余数写入rd寄存器。
以上就是目前所用到的指令了,之后如果添加新的指令会在这里更新。
之后我会还会出新文章更新具体设计部分的内容,大家看了如果觉得有帮助请点个小小的赞吧~
如果遇到问题也欢迎加群 892873718 交流~
文章浏览阅读3.1k次。点击关注公众号,利用碎片时间学习基本概念云原生这么多微服务,当然需要一个诊断利器来排查问题。Arthas 是阿里开源的 Java 诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪 Java 代码;实时监控 JVM 状态。Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便..._java -jar arthas-boot.jar
文章浏览阅读152次。挂载文件系统#include<sys/mount.h>int mount(const char *source,const char *target,const char *fstype,unsigned long mountflags,const void *data)其中mountflags的值可为: MS_BIND 建立绑定挂载,会忽略fstype,..._ms_nodev
文章浏览阅读176次。红颜莎娜常用到的HBase启动脚本有:1.$HBASE_HOME/bin/start-hbase.sh启动整个集群2.$HBASE_HOME/bin/stop-hbase.sh停止整个集群3.$HBASE_HOME/bin/hbase-daemons.sh启动或停止,所有的regionserver或zookeeper或backup-master4.$HBASE_HOME/bin/hbase-dae..._cli 链接 hbase
文章浏览阅读237次。Raju and Meena love to play with Marbles. They have got a lot ofmarbles with numbers written on them. At the beginning, Raju wouldplace the marbles one after another in ascending order of the number..._如果marble的编码207114,labour
文章浏览阅读5.1k次。我的世界怎么改名字 付/免费改名字教程。那在我的世界中改名字还是非常费事儿的,那今天就教大家怎么改名字吧!想知道怎么改名字的玩家不妨进来看看哦!希望对大家有所帮助。游戏园我的世界官方群:325049520欢迎各路喜爱我的世界的小伙伴们加入讨论!打开一个文件夹,地址改成C:Users你的用户名AppDataLocalPackagesMicrosoft.MinecraftUWP_8wekyb3d8bb..._微软pcl怎么改名字
文章浏览阅读88次。box-shadow 在前端的 CSS 编写工作想必十分常见。但是 box-shadow 除去它的常规用法,其实还存在许多不为人知的奇技淫巧。喜欢 markdown 版本的可以戳这里。box-shadow 常规用法说到 box-shadow ,首先想到的必然是它能够生成阴影,所以称之为 shaodow ,简单看看它的语法:基础属性语法box-sha..._filter: drop-shadow(100px 0 0 $bg-info);
文章浏览阅读1.2k次。outlook2013升级Outlook isn’t much use if you don’t have contacts. Sure, you can enter email addresses as you go, but that’s time-consuming and error-prone. It’s better to have your contacts already in O..._outlook2013邮箱能使用本地通讯录地址
文章浏览阅读5.6w次,点赞84次,收藏551次。PyCharm是一种Python IDE(Integrated Development Environment,集成开发环境) PyCharm拥有一般IDE具备的功能,比如, 调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试、版本控制_pycharm 下载
文章浏览阅读2.3w次,点赞12次,收藏13次。一开始我以为是后台没有获取到数据,写了几个输出语句测试发现数据是能获取到的,那就是显示的问题,检查了各个属性发现都是对的,后来突然发现我的遍历显示的地方出现了警告,这才注意到,忘记加<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>加了之后立马就显示正常了。..._java-web能拿到数据库内的数据但是不能显示在前端
文章浏览阅读341次。选择题题目:《楚辞》是《诗经》以外先秦诗歌的另一部总集。题目:知我者,回答题目:《采薇》曾被古人视为《诗经》中最好的篇章。题目:“楚辞”是战国时期产生于蜀地的一种诗歌样式。题目:《颂》诗包括《周颂》、《鲁颂》和《齐颂》。题目:若有人兮山之阿,回答题目:身既死兮神以灵,回答题目:回答题目:回答题目:《楚辞》是我国古代第一部诗歌总集。题目:“楚辞”最为明显的特征是带有“兮”字的三字句或四字句。题目:宋玉是除屈原以外创作成就最高的“楚辞”作家。题目:回答题目:《诗经》分为《风》、《雅》_《采薇》曾被古人视为《诗经》中最好的篇章。
文章浏览阅读1.3k次。Solaris 初步设置(转) 简介 这篇文档包含了你用solaris和Sun平台工作时所需要的最重要的20%的技术。它能处理你所遇到的80%的问题。 这篇文档并不打算覆盖Solaris处理环境的细节,也不会包..._solaris11 dev/dsk
文章浏览阅读1.1k次,点赞41次,收藏9次。R-CNN大大提升了目标检测的精度,但速度很慢。此后,Fast R-CNN和Faster R-CNN对原始R-CNN进行了改进,Faster R-CNN通过RPN网络学习提取候选区域,实现了端到端的目标检测。近年来,目标检测技术不断进步,涌现出了许多新的算法和模型,如RetinaNet、RefineDet、CenterNet等,进一步提升了目标检测的精度和效率,使得目标检测在越来越多的应用场景中得到应用。多年来,研究者们提出了许多经典的目标检测算法,下面我们就来介绍几种常见的经典目标检测算法。