RISC-V处理器的设计与实现(一)—— 基本指令集_risc-v基本指令级-程序员宅基地

技术标签: 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

下面我们开始指令的介绍。

RV32I 基本指令集

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寄存器。

RV32M 扩展指令集

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 交流~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_51103378/article/details/131201501

智能推荐

Java 诊断工具 Arthas 常见命令(超详细实战教程)-程序员宅基地

文章浏览阅读3.1k次。点击关注公众号,利用碎片时间学习基本概念云原生这么多微服务,当然需要一个诊断利器来排查问题。Arthas 是阿里开源的 Java 诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪 Java 代码;实时监控 JVM 状态。Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便..._java -jar arthas-boot.jar

系统编程概念(文件系统mount等函数的使用)-程序员宅基地

文章浏览阅读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

zkcli远程连接_如何启动hbase 自带了一个 zkcli?-程序员宅基地

文章浏览阅读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

第七十四题 UVA10474 大理石在哪儿 Where is the Marble?_如果marble的编码207114,labour-程序员宅基地

文章浏览阅读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

我的世界Java版中怎么改名_我的世界怎么改名字 付/免费改名字教程-程序员宅基地

文章浏览阅读5.1k次。我的世界怎么改名字 付/免费改名字教程。那在我的世界中改名字还是非常费事儿的,那今天就教大家怎么改名字吧!想知道怎么改名字的玩家不妨进来看看哦!希望对大家有所帮助。游戏园我的世界官方群:325049520欢迎各路喜爱我的世界的小伙伴们加入讨论!打开一个文件夹,地址改成C:Users你的用户名AppDataLocalPackagesMicrosoft.MinecraftUWP_8wekyb3d8bb..._微软pcl怎么改名字

box-shadow 与 filter:drop-shadow 详解及技巧-程序员宅基地

文章浏览阅读88次。box-shadow 在前端的 CSS 编写工作想必十分常见。但是 box-shadow 除去它的常规用法,其实还存在许多不为人知的奇技淫巧。喜欢 markdown 版本的可以戳这里。box-shadow 常规用法说到 box-shadow ,首先想到的必然是它能够生成阴影,所以称之为 shaodow ,简单看看它的语法:基础属性语法box-sha..._filter: drop-shadow(100px 0 0 $bg-info);

随便推点

outlook2013升级_如何在Outlook 2013中创建和管理联系人-程序员宅基地

文章浏览阅读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邮箱能使用本地通讯录地址

Pycharm下载与安装教程_pycharm 下载-程序员宅基地

文章浏览阅读5.6w次,点赞84次,收藏551次。PyCharm是一种Python IDE(Integrated Development Environment,集成开发环境)​ PyCharm拥有一般IDE具备的功能,比如, 调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试、版本控制_pycharm 下载

web开发中,后台数据获取到了,前端显示不出来_java-web能拿到数据库内的数据但是不能显示在前端-程序员宅基地

文章浏览阅读2.3w次,点赞12次,收藏13次。一开始我以为是后台没有获取到数据,写了几个输出语句测试发现数据是能获取到的,那就是显示的问题,检查了各个属性发现都是对的,后来突然发现我的遍历显示的地方出现了警告,这才注意到,忘记加<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>加了之后立马就显示正常了。..._java-web能拿到数据库内的数据但是不能显示在前端

【渝粤教育】广东开放大学 中国文化文学通论 形成性考核 (25)_《采薇》曾被古人视为《诗经》中最好的篇章。-程序员宅基地

文章浏览阅读341次。选择题题目:《楚辞》是《诗经》以外先秦诗歌的另一部总集。题目:知我者,回答题目:《采薇》曾被古人视为《诗经》中最好的篇章。题目:“楚辞”是战国时期产生于蜀地的一种诗歌样式。题目:《颂》诗包括《周颂》、《鲁颂》和《齐颂》。题目:若有人兮山之阿,回答题目:身既死兮神以灵,回答题目:回答题目:回答题目:《楚辞》是我国古代第一部诗歌总集。题目:“楚辞”最为明显的特征是带有“兮”字的三字句或四字句。题目:宋玉是除屈原以外创作成就最高的“楚辞”作家。题目:回答题目:《诗经》分为《风》、《雅》_《采薇》曾被古人视为《诗经》中最好的篇章。

Solaris 初步设置(转)-程序员宅基地

文章浏览阅读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等,进一步提升了目标检测的精度和效率,使得目标检测在越来越多的应用场景中得到应用。多年来,研究者们提出了许多经典的目标检测算法,下面我们就来介绍几种常见的经典目标检测算法。

推荐文章

热门文章

相关标签