RISC-V处理器的设计与实现——基本指令集

news2024/11/26 4:34:00

本人小白一枚,在学习FPGA的过程中偶然刷到了tinyriscv这个开源项目,并且自己对计算机体系结构的知识也很感兴趣,所以想参考这个开源项目做一个基于RISC-V指令集的CPU,下面是tinyriscv这个开源项目的地址,本项目很多思路和设计都参考了tinyriscv开源项目:

从零开始写RISC-V处理器 | liangkangnan的博客

tinyriscv: 一个从零开始写的极简、非常易懂的RISC-V处理器核。

在设计RISC-V处理器之前,我们首先要做的事就是指令集的选取,指令集是一个CPU的基石,要实现CPU 计算和控制功能,就必须定义好一系列与硬件电路相匹配的指令系统。下面是RISC-V官方给出的指令集架构:

因为是第一次做,所以我们选择简单一点的32位基本指令集,也就是RV32I 基本指令集,扩展指令我们到后面再去实现。

RV32I 基本指令集有6种格式,分别是:

目的类型
用于寄存器-寄存器操作R 类型指令
用于短立即数和访存 load 操作I 型指令
用于访存 store 操作S 型指令
用于条件跳转操作SB 类型指令
用于长立即数U 型指令
用于无条件跳转UJ 型指令

RV32I 基本指令集有47条指令,如下图:

本项目打算先实现前37条(黄色高亮部分)基础指令,下面介绍了一下这些指令的用法,这里给大家先推荐一个好用的工具叫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指令地址加上符号位拓展的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,作用是将高位补0的立即数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寄存器。

 

以上就是目前所用到的指令了,之后如果添加新的指令会在这里更新。

之后我会还会出新文章更新具体设计部分的内容,大家看了如果觉得有帮助请点个小小的赞吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

优思学院|六西格玛倡导者与项目赞助人是什么角色?有何区别?

倡导者&#xff08;Champion&#xff09;和项目赞助人&#xff08;Sponsor&#xff09;在正式的六西格玛的组织架构中是两个不同的角色&#xff0c;所以希望在这篇文章中解释一下两个角色的区别。 倡导者&#xff08;Champion&#xff09;是负责组织竞争力和增长的董事和高管&…

quartus 无法识别usb blaster

一、Windows无法正常驱动USB-Blaster 问题:驱动问题 解决方法: 右键我的电脑->管理->设备管理器找到设备USB-Blaster,此时是带有黄色感叹号的 3.右键->更新驱动程序软件 4. 选择“浏览计算机以查找驱动程序软件(R)”,如选择自动搜索是不能安装成功的,…

jQuery 基础语法使用指南

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 引入 jQuery 2. jQuery 语法 3. 选择器 …

FusionComputeV100R006C10SPC101平台安装win10踩坑记

生产环境中有一套华为FusionCompute&#xff0c;版本比较老&#xff0c;V100R006C10SPC101&#xff0c;该产品已EOS了&#xff0c;无法升级。因业务需要&#xff0c;需安装Windows10系统&#xff0c;遇到了不少坑&#xff0c;在此记录一下。 一、坑1&#xff1a;Windows10版本…

CAN总线终端电阻

CAN总线终端电阻&#xff0c;一般来说都是120欧姆&#xff0c;实际上在设计的时候&#xff0c;也是两个60欧姆的电阻串起来&#xff0c;而总线上一般有两个120Ω的节点&#xff0c;基本上稍微知道点CAN总线的人都知道这个道理。 但是这两个终端电阻的具体作用是什么呢&#xf…

迅为视频教程 | RKNPU2 从入门到实践一套搞定!

迅为基于瑞芯微RK3568和RK3588处理器设计开发的两款开发板都自带NPU&#xff0c;RK3568自带1T算力的NPU、RK3588自带&#xff16;T算力的NPU&#xff0c;且这两款开发板使用的都是RKNPU2。 &#xff08;RKNPU发展历程&#xff09; RKNPU2较RKNPU1有较大的提升&#xff0c;但市面…

Unity核心9——3D动画

一、3D 动画的使用 ​ 使用导入的 3D 动画&#xff1a; 将模型拖入场景中为模型对象添加 Animator 脚本为其创建 Animator Controller 动画控制器&#xff08;状态机&#xff09;将想要使用的相关动作&#xff0c;拖入 Animator Controller 动画控制器&#xff08;状态机&…

Java:时间日期类

文章目录 DateCalendarDate/Time APILocalDateLocalTimeLocalDateTimeZonedDateTime 功能获取标准时间 参考文献 Date 同样位于java.util包下。 在java中&#xff0c;获取时间最简单的方式就是直接实例化Date类。 以自定义格式&#xff0c;取当前的时间日期&#xff1a; Da…

渗透测试入门指南之小白该如何学习渗透?

前言&#xff1a; 内容都是精华&#xff0c;如果想要入安全的行&#xff0c;强烈建议仔细阅读。 目录&#xff1a; 渗透测试是什么&#xff1f; 学习渗透测试的战略方针是什么&#xff1f; 学习渗透测试的具体方法是什么&#xff1f; 遇到的各种疑难杂症怎么解决&#xf…

践行公益担当 | 关爱留守儿童,暖到“心理”

农民在中国各个时代都扮演着十分重要的角色&#xff0c;为中国的发展做出了卓越的贡献。随着经济的发展&#xff0c;农民为了改善生活而大规模的进城打工&#xff0c;“留守儿童”成为一个新的社会问题&#xff0c;开始在农村甚至部分城市出现。 全国“留守儿童”达6102.55万&…

从0到1精通自动化测试,pytest自动化测试框架,测试用例setup和teardown(三)

目录 一、前言 二、用例运行级别 三、函数式 1、setup_function / teardown_function 2、setup_module / teardown_module 四、类和方法 五、函数和类混合 一、前言 学过 unittest 的都知道里面用前置和后置 setup 和 teardown 非常好用&#xff0c;在每次用例开始前和…

计算机组成原理-复习大纲(期末版)

目录 第一章 计算机系统概论 1.1 冯诺依曼型计算机 1.2 计算机的硬件组成 第二章 运算方法和运算器 2.1 ieee754标准、32位浮点数 2.2 补码运算 2.3 运算器的基本结构形式 第三章 存储系统 3.1 主存与cache的地址映射 3.1.1 全相联映射方式 3.1.2 直接映射方式 3.1.3 组相…

全网最细,web自动化测试实战场景(滚动元素的滚动操作)直接上干g货......

前言 使用 selenium 进行 web 自动化测试对我们来说是个常规操作。用了很多次后&#xff0c;我们经常会抱怨 selenium 封装的操作实在是太少了。 比如说 selenium 没有对页面的滚动提供丰富 API , 有的只有一个孤零零的 location_once_scrolled_into_view 方法&#xff0c;把…

css 解决多张图片显示时出现的空白间隙问题

1、出现的间隙 在后端设置富文本时&#xff0c;添加了多张图片&#xff0c;但是到前台展示时&#xff0c;每2张图片直接都会多出一个间隙&#xff1b; 2、空白间隙产生的原因 在网上查阅资料时&#xff0c;发现是由于图片设置了display: inline-block;属性&#xff0c;使图…

任意分频器电路设计

目录 任意分频器电路设计 1、任意偶数分频器电路设计 1.2、实验任务 1.3、程序设计 1.3.1、代码如下&#xff1a; 1.3.2、编写仿真 TB 文件 2、任意奇数分频器电路设计 2.1、实验任务 2.2、程序设计 2.2.1、奇数分频电路代码 2.2.2、编写仿真 TB 文件 2.2.3、仿真验…

关于前端项目安全问题的一些思考

1.路由守卫&#xff0c;本地路径与本地存储加密后的该用户所有能访问的的路径列表对比&#xff0c;是否有权限&#xff0c;这个要搞个一级页面-二级页面三级页面这种记录下来&#xff0c;后台管理员开启后赋予用户访问某些页面的权限&#xff0c;即能打开相关菜单的权限&#x…

【吴恩达老师《机器学习》】课后习题2之【逻辑回归(logistic_regression)】

逻辑回归-线性可分 用于解决输出标签y为0或1的二元分类问题 判断邮件是否属于垃圾邮件&#xff1f;银行卡交易是否属于诈骗&#xff1f;肿瘤是否为良性&#xff1f;等等。 案例:根据学生的两门学生成绩&#xff0c;建立一个逻辑回归模型&#xff0c;预测该学生是否会被大学录…

卷积码编码器的结构与表示

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 卷积码基础卷积码的…

Oracle数据库startup mount时的报错处理(ORA-01078LRM-00109)

安装监听 Disconnected [oraclerac1 ~]$ netcaOracle Net Services Configuration:[oraclerac1 ~]$ sqlplus / as sysdbaSQL*Plus: Release 11.2.0.4.0 Production on Tue Jun 20 22:50:36 2023Copyright (c) 1982, 2013, Oracle. All rights reserved.Connected to an idle …

学习adaboost(三,第二次迭代,c#实现)

我们改进了第一次迭代&#xff1a;第二次迭代如下&#xff1a;因为三个弱分类器都是犯了3次错误&#xff0c;我们故意选了y>6.5,标签1&#xff0c;else&#xff0c;标签-1&#xff1b;第一个弱分类器已经选了&#xff0c;再选一次没意义&#xff0c;不会有任何进展&#xff…