前言:本文主要简单介绍RISC-V指令集,其中参考了浙江大学mooc《计算机组成与设计:RISC-V》和《手把手教你设计CPU——RISC-V处理器》,如果文章中有描述不恰当的地方,欢迎指正。
1、RISC-V指令集简介
RISC-V(英文发音为"risk-five")架构主要由美国加州伯克利分校(简称伯克利)的Krste Asanovic教授和Yunsup Lee等开发人员于2010年发明。经过几年的发展,伯克利为RISC-V架构开发了完整的软件工具链以及若干开源的处理器实例(例如Pocket Core和BOOM Core),并且得到了计算机体系结构领域的泰斗David Patterson的大力支持。
与大多数指令集架构相反,RISC-V指令集架构最大的特点就是开放,无论学术机构还是商业组织都可以免费地用于所有需要的设备中,允许任何人设计、制造和销售RISC-V芯片和软件。
2、指令格式介绍
指令(又称机器指令):是指示计算机执行某种操作的命令,是计算机运行的最小功能单位。一台计算机的所有指令的集合构成该机的指令系统,也称为指令集。
一条指令通常要包括操作码字段和地址码字段两部分:
3、RISC-V 32个通用寄存器介绍
RISC-V32I基础指令集共定义了32个32位的通用寄存器,分别标记为x0~x31。寄存器x0固定连接到常数0,还有一个额外的用户可见程序计数器pc寄存器,它保存当前指令的地址。32个寄存器的详细功能如下图所示:
4、RISC-V 指令集
4.1、RISC-V 指令分类
根据RISC-V指令的共性,主要将其分为以下6种指令格式:
根据RISC-V指令集之间的共性,其主要可分为以下6种指令格式(R、I、S、B、U、J)。
- R型指令——用于寄存器与寄存器之间算术运算操作;
- I 型指令——用于寄存器与立即数之间算术运算和读存储器操作;
- S型指令——用于写存储器;
- B型指令——用于分支转移操作(属于S型指令的变体,之前也叫SB型指令);
- U型指令——用于高20比特位立即数操作;
- J型指令——用于直接跳转(属于U型指令的变体,之前也叫UJ型指令)。
6种基本指令的格式如下图所示为:
——opcode表示7位指令操作码,用于区分不同的指令;
——funct3表示3位的功能码,funct7表示7位的功能码,用于辅助区分不同种类的指令;
——rs1和rs2表示两个5位的源寄存器;
——rd表示5位的目的寄存器,用于存储指令的运算结果;
——imm表示不同长度的立即数,一般会扩展为32位再进行运算操作;
4.2、6种基本指令格式具体介绍
4.2.1、R型指令
R型指令是最为常用的运算指令,主要用于寄存器与寄存器之间算术运算操作。如下图所示,具有两个5位的源寄存器地址、一个5位目的寄存器地址、一个7位的funct7功能码、一个3位的funct3功能码和7位的opcode操作码。
如上图R型指令格式所示,通过低7位的opcode(0110011)可以得出指令为R型指令,然后将32位的指令按照R型指令的格式划分相应的区域。由funct3(000)和funct7(0000000)可以得出指令执行add操作。rs1对应x19(10011),rs1对应x10(01010),rd1对应x18(10010),即将寄存器19的值加上寄存器10的值并将其运算结果存放到寄存器18这个地址上。注:RISC-V并无减法指令,可以通过加负数来实现减法,减少了指令集数量,这也符合RISC-V精简的原则。注:x10、x18和x19对应上面的32个通用寄存器。
其他R型指令操作如下图所示:
4.2.2、I 型指令
I 型指令主要用于寄存器与立即数之间算术运算和读存储器操作。如下图所示,具有一个5位的源寄存器地址、一个5位目的寄存器地址、一个12位的imm立即数、一个3位的funct3功能码和7位的opcode操作码。
如上图 I 型指令格式所示,通过低7位的opcode(0010011)可以得出指令为 I 型指令,然后将32位的指令按照I型指令的格式划分相应的区域。由funct3(000)可以得出指令执行addi操作。rs1对应x1(00001),立即数imm(1111_1100_1110 = -50)通过符号位扩展成32位,rd1对应x15(01111),即将寄存器1的值加上立即数(-50)并将其运算结果存放到寄存器15这个地址上。
其他I型指令操作如下图所示:
4.2.3、S型指令
S型指令主要用于写存储器的S型指令。
如下图所示,具有两个5位的源寄存器地址、一个12位的imm立即数、一个3位的funct3功能码和7位的opcode操作码。
如上图S型指令格式所示,通过低7位的opcode(0100011)可以得出指令为S型指令,然后将32位的指令按照S型指令的格式划分相应的区域。由funct3(010)可以得出指令执行sw操作。rs1对应x2(00001)作为基地址,立即数imm(0000_0000_1000 = 8)通过符号位扩展成32位作为地址偏移量,rs1对应x14(01110)作为,即将寄存器2的值加上立即数(8)的值作为地址,并将此地址的值存入到寄存器14中。
其他S型指令操作如下图所示:
4.2.4、B型指令
B型指令主要用于分支转移操作的B型指令(属于S型指令的变体,之前也叫SB型指令)。如下图所示,具有两个5位的源寄存器地址、一个12位的imm立即数、一个3位的funct3功能码和7位的opcode操作码。
如上图B型指令格式所示,通过低7位的opcode(1100011)可以得出指令为B型指令,然后将32位的指令按照B型指令的格式划分相应的区域。由funct3(000)可以得出指令执行beq操作。rs1对应x19(10011),rs2对应x10(01010),立即数imm(0000_0000_1000 = 8),即若寄存器x19中的值与寄存器x10的值相等,则跳转到立即数所示的地址中;若不相等则不实行跳转。
其他B型指令操作如下图所示:
4.2.5、U型指令
U型指令主要用于高20比特位立即数操作的U型指令。如下图所示,具有一个5位的目的寄存器地址、一个20位的imm立即数和7位的opcode操作码。
如上图U型指令格式所示,也是通过低7位的opcode可以得出其指令类型,然后将32位的指令按照相应的型指令的格式划分相应的区域。例如执行lui x10,0x87654指令,即将0x87654存入到x10寄存器中的高20位中,剩余的12位低位补零。
4.2.6、J型指令
J型指令主要用于直接跳转的J型指令(属于U型指令的变体,之前也叫UJ型指令)。如下图所示,具有一个5位的目的寄存器地址、一个20位的imm立即数和7位的opcode操作码。
如上图U型指令格式所示,也是通过低7位的opcode可以得出其指令类型,然后将32位的指令按照相应的型指令的格式划分相应的区域。jal常用于子函数的调用,例如执行jal ra,FuncName指令,即跳转到要执行的子函数FuncName中,并将当前PC+4的值存入到寄存器rd中,方便执行完子函数后跳回。
总结
若需要更为全面的学习RISC-V的基础知识,推荐浙江大学mooc《计算机组成与设计:RISC-V》,《手把手教你设计CPU——RISC-V处理器》。此外,B站和中国大学MOOC(慕课)等网站也有相应的视频可供学习。
版权声明:本文为CSDN博主「weixin_45585462」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45585462/article/details/126401223