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

news/2024/10/17 21:21:52/

本人小白一枚,在学习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.ppmy.cn/news/581122.html

相关文章

钉钉企业邮箱smtp服务器

EMAIL_HOST试了’smtp.aliyun.com’不行 换成’smtp.mxhichina.com’就行了

搭建 Extmail企业邮件服务

文章目录 搭建 Extmail企业邮件服务简介邮件协议组成客户端 1、配置 DNS 模块2、使用 extmail 自带模板在 MySQL 中创建数据库安装数据库、修改密码安装Apache、部署网站向数据库中导入extmail的初始化数据&#xff0c;导入前修改部分密码、方便登录 还原数据库&#xff0c;创建…

几何平均值最大子数组

题目描述 从一个长度为N的正数数组numbers中找出长度至少为L且 几何平均值 最大的子数组&#xff0c;并输出其位置和大小。 &#xff08;K个数的 几何平均值 为K个数的乘积的K次方根&#xff09; 若有多个子数组的几何平均值均为最大值&#xff0c;则输出长度最小的子数组。 若…

网易免费企业邮箱服务器地址

pop:pop.ym.163.com smtp:smtp.ym.163.com 更多信息请查看 个人博客 或者关注公众号&#xff1a;Z技术

腾讯企业邮箱SMTP服务器连接失败 PHPMailer

今天测试PHPMailer 发送邮箱&#xff0c;按照常规配置&#xff0c;端口正常填写&#xff0c;但是腾讯企业邮箱就是提示错误。 解决方法&#xff1a; 深坑&#xff0c;不要加端口&#xff0c;把端口注释掉&#xff01; $mail->SMTPDebug SMTP::DEBUG_SERVER; …

公司企业邮箱登陆客户端,邮件服务器如何设置?

企业邮箱有很好的邮件管理功能&#xff0c;例如登录tom企业邮箱后台&#xff0c;可部门分级管理、邮件群组、邮箱搬迁、移动办公、邮件备份等功能&#xff0c;细分起来还有不少。企业邮箱的服务器有很强大的兼容功能&#xff0c;使用其他客户端&#xff0c;邮件也能同步&#x…

企业邮箱容量,注册无限容量邮箱,企业邮箱服务器怎么设置?

公司邮箱容量是在选择企业邮箱时重点考虑的&#xff0c;TOM企业邮箱&#xff0c;无限容量&#xff0c;3折优惠&#xff0c;高性价比&#xff0c;邮件加密传输&#xff0c;是国内唯一具备24年运营经验的直销服务商。 企业邮箱怎么申请 首先开启电脑的一个浏览器&#xff0c;在…

网易免费的企业邮箱smtp的地址

网易域名邮箱支持POP3/SMTP服务 POP3&#xff1a;pop.ym.163.com   默认端口为&#xff1a;110 SMTP&#xff1a;smtp.ym.163.com  默认端口为&#xff1a;25 验证方式选择无 单个帐号每天发信上限为1000封 单个帐号发送频率每15分钟不得超过500封 单次群发不宜超过200…