基于risc-v架构cpu


一、定义:

   CPU ,全称为中央处理器单元,简称为处理器,是一个不算年轻的概念 早在 20 世纪60 年代便己诞生了第一款 CPU请注意区分“处理器”和“处理器核”“ PU ”和“Core ”的概念。严格来说 “处理器核”和“ Core ”是指处理器内部最核心的部分,是真正的处理器内核;而“处理器”和“CPU"往往是一个完整的 Soc ,包含了处理器内核和其他的设备或者存储器 但是在现实中大多数往往不会严格地遵循两者的差别,时常混用,因此读者需要根据上下文自行颤别体会具体的含义经过几十年的发展,到 天已 相继诞生或消亡过了几十种不同的 CPU 架构 1-1为近几十年来知名 CPU 架构的诞生时间表 什么是 CPU 架构?下面让我们来探讨区分 CPU的主要标准 CPU 灵魂一一指令集架构 Clnstructio Set Architecture, ISA )。
   RISC-V(读音“risk-five”)是一个新的指令集体系结构(ISA),它最初用于支持计算机体系结构研究和教学,但现在我们希望它也成为一个对于工业实现来说标准、免费、开放的体系结构。RISC-V ISA 被定义为一个基本的整数 ISA,必须在任何实现中存在,另外可以包含基于基本 ISA 的其他扩展。这个基本的整数 ISA 与早期的 RISC 处理器非常相似,除了没有分支延迟槽(delay slot),另外支持可选的变长指令编码。这个基本核心被小心地限制具有最少的指令,足够支持一个合理的目标机,以便编译器、汇编器、链接器、操作系统(包含额外的管理员级操作)可以在之上运行,这样就可以提供一个方便的 ISA 和软件工具链“骨架”,围绕它可以构建更为定制化的处理器 ISA。每一个基本整数指令集,被整数寄存器宽度和相应的用户地址空间大小进行分类。有两种主要的基本整数变种,RV32I 和 RV64I,分别提供了 32 位和 64 位用户级地址空间。硬件实现和操作系统可以提供给用户程序使用 RV32I 或者 RV64I中的一种或者两种。还描述了未来支持 128 位用户地址空间的 RV128I 变种基本整数指令集。
二、指令集
  基本 RISC-V ISA 具有 32 位固定长度指令,并且必须在 32 位边界对齐。然而,标准 RISC-V编码模式被设计成支持变长指令的扩展,在这个扩展中,每条指令长度可以是 16 位指令包裹(parcel)长度的整数倍,并且这些指令包裹必须在 16 位边界对齐。第 14 章中描述的标准压缩 ISA 扩展,通过提供压缩的 16 位指令,减少了代码大小,并放松了对齐要求,允许所有指令(16 位和 32 位)对齐到任意 16 位边界,以提高代码密度。图 1.1 展示了标准 RISC-V 指令长度编码约定。所有基本 ISA 中的 32 位指令的最低 2 位被设置为 11。可选的压缩 16 位指令集扩展中的指令,最低 2 位被设置为 00、01 或者 10。超过 32 位的标准指令集扩展,在低位有额外的位被设置为 1,48 位、64 位长度约定如图 1.1所示。指令长度在 80 位到 176 位之间的长度信息,被编码到一个 3 位的字段[14:12]中,给出了 16 位字的数量,加上最开始的 5×16 位字。位[14:12]编码为 111,保留给未来更长的指令编码。

 

 三、32 位指令集

  本文只是简单的介绍32位指令集的一些原理及使用:

1、立即数编码变种

1)ADDI将符号扩展的12位立即数加到寄存器rs1上。算术溢出被忽略,而结果就是运算结果的低XLEN位。ADDI rd,rs1,0用于实现MV rd,rs1汇编语言伪指令。SLTI(set less than immediate)将数值1放到寄存器rd中,如果寄存器rs1小于符号扩展的立即数(比较时,两者都作为有符号数),否则将0写入rd。SLTIU与之相似,但是将两者作为无符号数进行比较(也就是说,立即数被首先符号扩展为XLEN位,然后被作为一个无符号数)。注意,SLTIU rd,rs1,1将设置rd为1,如果rs1等于0,否则将rd设置为0(汇编语言伪指令SEQZ rd,rs)。ANDI、ORI、XORI是逻辑操作,在寄存器rs1和符号扩展的12位立即数上执行按位AND、OR、XOR操作,并把结果写入rd。注意,XORI rd,rs1,-1在rs1上执行一个按位取反操作(汇编语言伪指令NOT rd,rs)。

 

2)被移位常数次,被编码为I类格式的特例。被移位的操作数放在rs1中,移位的次数被编码到I立即数字段的低5位。右移类型被编码到I立即数的一位高位。SLLI是逻辑左移(0被移入低位);SRLI是逻辑右移(0被移入高位);SRAI是算术右移(原来的符号位被复制到空出的高位中)。

 

 3)LUI(load upper immediate)用于构建32位常数,并使用U类格式。LUI将U立即数放到目标寄存器rd的高20位,将rd的低12位填0。AUIPC(add upper immediate to pc)用于构建pc相对地址,并使用U类格式。AUIPC从20位U立即数构建一个32位偏移量,将其低12位填0,然后将这个偏移量加到pc上,最后将结果写入寄存器rd。

 

 

2、控制转移指令

1)无条件跳转

 跳转并连接(JAL)指令使用了UJ类格式,此处J立即数编码了一个2的倍数的有符号偏移量。这个偏移量被符号扩展,加到pc上,形成跳转目标地址,跳转范围因此达到±1MB。JAL将跳转指令后面指令的地址(pc+4)保存到寄存器rd中。标准软件调用约定使用x1来作为返回地址寄存器。普通的无条件跳转指令(汇编语言伪指令J)被编码为rd=x0的JAL指令

 

2)间接跳转指令JALR(jump and link register)使用I类编码。通过将12位有符号I类立即数加上rs1,然后将结果的最低位设置为0,作为目标地址。跳转指令后面指令的地址(pc+4)保存到寄存器rd中。如果不需要结果,则可以把x0作为目标寄存器。

 

 3)条件分支

  分支指令比较两个寄存器。BEQ和BNE将跳转,如果rs1和rs2相等或者不相等。BLT和BLTU将跳转,如果rs1小于rs2,分别使用有符号数和无符号数进行比较。BGE和BGEU将跳转,如果rs1大于等于rs2,分别使用有符号数和无符号数进行比较。注意,BGT、BGTU、BLE和BLEU可以通过将BLT、BLTU、BGE、BGEU的操作数对调来实现。

 

 3、Load 和 store 指令

RV32I是一个load-store体系结构,也就是说,只有load和store指令可以访问存储器,而算术指令只在CPU寄存器上进行操作运算。RV32I提供了一个32位用户地址空间,它是字节寻址并且是小端的。执行环境将定义这个地址空间的哪些部分是可以合法访问的(译者注:这涉及到存储保护等)。

Load和store指令在寄存器和存储器之间传输数值。Load指令编码为I类格式,而store指令编码为S类格式。有效字节地址是通过将寄存器rs1与符号扩展的12位偏移量相加而获得的。Load指令将存储器中的一个值复制到寄存器rd中。Store指令将寄存器rs2中的值复制到存储器中。LW指令将一个32位数值从存储器复制到rd中。LH指令从存储器中读取一个16位数值,然后将其进行符号扩展到32位,再保存到rd中。LHU指令存储器中读取一个16位数值,然后将其进行零扩展到32位,再保存到rd中。对于8位数值,LB和LBU指令的定义与前面类似。SW、SH、SB指令分别将从rs2低位开始的32位、16位、8位数值保存到存储器中。

 

 

 4、整数寄存器-寄存器操作

ADD和SUB分别执行加法和减法。溢出被忽略,并且结果的低XLEN位被写入目标寄存器rd。SLT和SLTU分别执行符号数和无符号数的比较,如果rs1<rs2,则将1写入rd,否则写入0。注意,SLTU rd,x0,rs2,如果rs2不等于0(译者注:在RISC-V中,x0寄存器永远是0),则把1写入rd,否则将0写入rd(汇编语言伪指令SNEZ rd,rs)。AND、OR、XOR执行按位逻辑操作。SLL、SRL、SRA分别执行逻辑左移、逻辑右移、算术右移,被移位的操作数是寄存器rs1,移位次数是寄存器rs2的低5位。

 

附录

 

 这些博客的内容来自我工作、学习时的感悟、与行业前辈的交流感悟以及读书时的笔记,一部分内容可能与其他的网络资源类似,如果有相关问题的话(比如内容有错),请私聊博主或者在博文下面留言评论。

  写博客最初目的就是记录自己容易忘记的东西,而不是像写书那样专门写给别人看的。所以,文章可以转载(转载请标明出处 http://www.cnblogs.com/podia/ ,作者:podia),无需版权

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM