开发者学堂课程【高校精品课-清华大学 - 计算机原理与设计:RISC-V处理器介绍】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/78/detail/15733
RISC-V处理器介绍
内容介绍
一、ISA新兴宠儿RISC-V
二、RISC-V指令集架构
三、RV321基础指令集介绍及其与MIPS指令集对比
四、总结
一、ISA新兴宠儿RISC-V
指令集顾名思义就是一个给定的计算机体系结构所包含的指令集合。CPU完全依靠这些指令来计算和控制系统,可以说指令集就是CPU的灵魂。
从这个表中可以看到CPU的技术是历久弥新推陈出新的。表格列出多种CPU架构和其对应诞生的时间。
RISC-V是这些指令集中新兴的一个宠儿,它诞生在2014年。RISC-V是基于精简指令集RISC原理建立起来的一个开放的指令集架构。它是一个历久弥新的,他其中的Five表示第五代RISC指令集架构,可以看得出来这个指令集架构的新宠儿RISC-V是历久弥新推陈出新的一个CPU的技术。
全世界超过95%的智能手机和平板电脑都采用的是ARM的架构。在普通人眼中ARM的知名度远远没有Intel公司的辨识度高,甚至不如华为,高通苹果联发科三星等这些厂商,但是ARM处理器架构却以润物细无声的方式渗透在了生活的每个角落,从日常使用的电视、手机、平板、电脑、手环、手表等电子产品到不是很起眼的一些遥控器、智能灯和充电器等我们想不到的方方面面,都有ARM架构处理器的的身影。
白色家电工业控制与汽车电子领域ARM架构处理器更是无处不在。一些桌面PC服务器或者超级计算机领域,ARM架构也在朝这方面去逐渐的去渗透,可以说ARM架构的处理器统治了这些领域,支撑着这个世界的运行。
ARM架构或者是母公司的一个盈利模式其实是在传统的PC领域,半导体厂商一般是有两种路子可选,首先就是像英特尔那样从头到尾自己大包大揽架构那些店设计生产一律不依靠任何人。英特尔早期也提供过也对外提供过X86指令集的授权,但很快就收回了。这样做需要极其雄厚,全方位的实力做保障。今天能有这样这么一个保障的其实是屈指可数,世界上也就这么一家公司,并且其实英特尔最近也在一个。这样做好处其实是非常明显。这样做不但可以完全把握自己的命脉,而且利润是极其可观的,英特尔几乎任何产品都享有非常高的利润,甚至基本上就是他想卖多少钱就可以卖多少钱。
在PC领域这种模式就行不通了,因为在处理器在PC系统中的成本占比非常高,但是在智能手机平板平板平板电脑里面往往不到10%甚至不足5%。。
历久弥新、推陈出新的 CPU 技术
盈利模式,以 ARM 架构为例
授权“ ARM 处理器 IP ”一由 ARM 公司开发,给其他芯片生成公
司(合作伙伴)
收取前期的授权费
量产后的版费(每卖1块芯片,付1%2%版税)
ARM 公司主要盈利模式
转让“ ARM 架构授权” ARM 指令集架构,给其他芯片生成公
司(合作伙伴),由其根据需求自行研发(自研 ARM )
收取前期的架构授权费
其他授权 ISA 架构
其他像x86, MIPS 等,同样存在高昂授权问题
x86的源码根本获得不到; ARM 的代码修改也不被允许
其他开源 ISA 架构
其他像 SPARC ,0penRISC等多少存在一些问题
0penRISC只是一种开源 CPU 核,任何改动也必须开源
SPARC 面向服务器领域,功耗面积大,不适合嵌入式,用户无法裁剪和定制
费劲却挣不到更多的利润,也是英特尔在移动领域推广比较困难的关键原因之一。ARM完全不一样,他不制造芯片也不销售任何芯片,它只设计自己的一个IP核。IP主要包括指令集架构,微处理器途径核心互联架构,做好之后谁喜欢就把授权卖给谁,客户拿着ARM的IP就可以自己想怎么去设计就怎么去设计。
ARM的经营之道比较简单,以三种不同的模式对外提供授权。
第一个是处理器授权,ARM设计好一颗CPU或者GPU,授权卖给伙伴,买下他们后只要照着图纸实现,能发挥的地方不多,但是如何实现就随便,比如可以配置哪些模块、多少核心、多少缓存、多高频率、什么工艺,甚至找谁代工都是自己做决定。ARM也会提供一些指导性的辅助,但如何把方案变成芯片设定在一个什么样的规格,还是自己去做决定。
第二个授权就是处理器优化包或者物理IP包的授权。如果很想做ARM处理器,但实力有限,ARM准备了一系列优化处理器设计的方案,可以根据自己的需要挑选合适的直接拿过去用。
第三点就是指令和架构,还有指令集的授权。仅购买ARM的架构或者指令集然后自己去研究设计芯片,比如高通或者苹果都是典型的代表,在作为ARM的授权人有两部分钱,就是是前期的授权费还有版税。
还有其他的一些收费项目,比如一些软件工具技术支持等等,但主要就是这两个。业绩报告分别占ARM的总收入大概33%-50%左右。而前期授权费一般少则100多万美元,多则1000多万美元,也可能更高或者更少了。
这些前期授权费都是一次性付清的。具体多少取决于所购授权技术的复杂程度,ARM11就最新的cortex A57便宜很多。版税是说每卖出一颗芯片就交一点,这一点通常是售价的1%-2%,如果芯片是卖给其他企业或者消费者很好计算,如果是内部消化就按照应有的价格来定。
ARM有一套以处理器架构为技术的一个盈利模式。一直以来都没有一个开源的指令集架构,相比其他领域如通信操作系统、编译器数据集、计算机、图形库等等,其实都是有开源工作的。
CPU领域的指令集架构不能有开源的工作,是因为他有一些特性,如公认性、稳定、简单、高效、易实现的这种特性。
基于此uc berkeley从2010年起有待Python等教授领先开发推出,
主要做的是两点。
2014年开发出了一套完整的编辑器软件工具链和若干开源的处理器流变实力。并且采用了BSD的一个许可证发布的RISC-V既可以用于开项目,同时也可以用于商业项可以开源或者不开源所做的改进。
BSD开源协议是一个基于使用者很大自由的一个协议,基本上使用者可以为所欲为,可以很自由的使用、修改源代码,也可以将修改后的代码作为开源或者专有的软件再发布。
二、RISC-V指令集架构
RISC-V有以下两个含义,一是代表这是uc berkeley从RISC精简指令集架构,一开始设计的第五代指令集架构。二则表示Variation和Victor,暗示了符合Berkeley追求开放的精神。
RISC-V架构的目标主要有两点,一个是实现完全开放免费的使用价格,并且给任何学术机构或者商业组织都可以完全自由的使用。第二是适合硬件实现的一个简单简洁高效且稳定的标准指令集。经过几年发展现代的这个X86和ARM架构的文章长达几百数千页打印起来基本上是有半个桌子高可可以说是著作等身。
这个表格可以看到就是RISC-V的架构文档分为了这个指令集文档和特权架构文档。指令集文档的篇幅是145页,特权架构的篇幅仅仅有91页。熟悉的结构的工程师仅需要一至两天便可将其通读。
虽然RISC-V的架构文档还在不断的丰富,但相比X86的架构文档和ARM架构文档RISC-V的篇幅可以说是极其短小。
2016年非营利组织基金会成立负责RISC-V指令集标准和价格文档的一个维护。
任何组织和个人无需注册,随时可在RISC-V基金会官网下载包括工具链、ISA文档,通过GitHub链接的开源项目等等。
RISC-V自从诞生之后就受到了学术界和工业界的一个巨大的欢喜。并且被誉为2016年的一个最佳技术。
在教育界呢出现了基于RISC-V改进了计算机体系结构量化研方法的这本书,作者Dacid Patterson,它是图灵奖的得主。并且它是RISC-V架构的主要发起者之一,这意味着美国以后都将会RISC-V作为最新的教学范例,若干年后的高校毕业生都将对RISC-V很熟悉。
在工业界,2016年2017年起RISC-V指令集就成为印度的事实国产指令级架构,从2015年开始每半年一次Workshop推动RISC-V经济发展,并且近几年RISC-V基金会积极布局中国市场。
RISC-V的指令集以模块化组织方式进行组织,每种指令集以一个英文字母来表示。
使用整数指令子集就可以实现和利用完整的软件编译器。他自己都是一个可选的模块。具有代表性的比如字母M、A、F、D、C分别来表示,这个基础指令集则可以分为三个,第一个是最基础的32位整数指令集,也就是RV32I,相对应的还有RV64I和RV128I。
为了进一步减少面积RISC-V架构还提供一种嵌入式的架构,由英文字母E来表示,该架构主要是为了追求基地面积与功耗的深嵌入式场景,该架构仅需要支持16个通用整数寄存器。非嵌入式的普通的架构需要支持32个通用整数寄存器。
RV32I和RV32E主要区别是RV32E相比RV32I来讲只需要支持16个32位宽的通讯器。这两种指令集对于通用计算器数目的不同,对于ASIC和FPGA设计实现的意义在于在ASIC设计中的寄存器通常通过触发器来实现,所以对于面积划的RV32I设计来讲一处16个通用寄存器,可以减少25%的芯片面积,而在FPGA实现中,移除这16个计算器并不能带来资源上的节省,因为在FPGA中通用计算器可以通过片上的BRAM来实现。
RISC-V的指令集都是用模块化的方式进行组织的,每个模块都用一个英文字母来表示,除了RISC-V最基本也是唯一强制要求实现的由字母I来表示的基本整数指令子集之外,还存在一些拓展之列,第一个就是由字母M表示的整数乘法和除法的扩展指令。它包括对两个整数寄存器中的值做乘法除法指令。将乘除法单独列出来成为一个扩展指令集是为了简化低端硬件的实现。有些场景极少用到整数乘除法,所以就不用单独实现。
第二个是压缩指令,这个指令特点就是它的长度仅为16位。为了提高大密度的RISC-V架构,它提供了可选压缩指令集,用字母C来表示,指令变化长度就是16比特,普通的非压缩的长度为32比特,值得注意的是RV32C压缩只是一个拓展,可以理解是一种简写方式,而不是一个独立的指令集。在RV32C中每条指令都可以转化成为一条完整的32位指令。RV32C只是对部分32位指令的一种简写方式,从而将纯32位代码转成16位或者32位的混合方式,如果处理器支持这种压缩指令只需要修改指令取值器和指令解码器即可,这样大大地简化初期设计。
对于两个数求和相同操作上面需要32位的指令,而压缩后只需要16位ID,其实就是对上面原32位指令简写成了16位。通过这16位的压缩指令集的拓展和32位指令集相比,这种压缩指令的引入可以大大的减少代码的一个密度基本上就可以将代码密度减少近40%左右。
第三个要介绍的是单精度32比特浮点运算(F)当使用浮点模块,比如F和双精度浮点运算D都需要增加一个独立的浮点,浮点寄存器F0到F3231。在仅使用F模块下每个通用浮点寄存器的宽度是32比特。
除单精度浮点之外,还有一个设计就是双精度浮点。运算扩展指令格式用字母D来表示,用D模块时每个通用浮点寄存器的宽度就变成了64比特。
除上面四种之外还有还有其他拓展指令,如原子指令的标准扩展(I)、四精度浮点的标准扩展(Q)、十进制浮点的标准扩展(L)、位操作的标准扩展(B)
可配置的通用寄存器组。RISC-V架构支持32位或者64位的可配置的通用寄存器组,与MIPS一致,RISC-V通用寄存器用于保存变量均为32,整数寄存器0预留为:常数零。
与MIPS不同的是整数型通用寄存器组的数量是可配置的,如RV32I使用的通用寄存器是32个,RV32E使用的通用寄存器是16个。第二个不同点是寄存器可以看配置,RV32为32比特,RV64则为64比特。
第三个不同点在于RISC-V中设置有扩展指令来使通用浮点寄存器组可配置他们独立于整数型通用寄存器组的单精度二维32F配置为32比特,双精度LV32D的配置为64比特,通过FLEN来区分二者宽度。
RISC-V指令集架构三个特点.第一个是其短小精悍基础的RV32I类型只有40多条,通过这40多条即可以构成一个完整的处理器流程,所有类型加起来不到300条。
第二个特点是它是用模块化的方式去组织的。不同类型的指令采用不同的模块化设计,比如说RV32I或者RV32M。
第三个特点是非常的灵活扩展,它可以按照不同的应用场景,按需求组合剪裁进行灵活拓展。可以用LV32IMFD达到更多的功能的效果,不同应用场景,对于深嵌入式场景中可以使用一些压缩的扩展指令。
RISC-V用不同的场景的非常的方便的原因其实也是采用这种比较模块化的方式去设计的。
三、RV321基础指令集介绍及其与MIPS指令集对比
MIPS的核心子集其实可以概括为三个指令类,第一个是算术逻辑指令类,第二个是存储器访问指令类,第三个是转移指令类。
Mips指令的设计原则有三点,一是剂量小尽量简洁,二是不含乘、除、移位指令,三是不含浮点指令。
Mips和RISC-V算术逻辑指令均属于立即数指令、寄存器指令,这两种简称。
比如I-type和R-type他们有一个共同点,就是Mips和RISC-V的指定编码方式都很规整,但是其实编码格式不同。
RISC-V和Mips指令在R-type里面都是一致通过均提供三个寄存器操作,寄存器字段对应的5位由32个寄存器进行寻址范围所确定,rs1作为第一个源操作数、rs2作为第二个操作数、rd作为目的操作数用于存放结果。
在 RISC - V 的 R - type 中的源寄存器rs2变为相对应的偏移量立即数 shamt ,并将其划分至1-type中。
SC - V 的 R - type 中funct7与funct3的编码方式与1-type对应逻辑运算的编码方式一致,相比于 MIPS 中1-type编码方式,保证了编码方式的规整性(在 MIPS 的 I - typei 过唯一指定 opcode 的编码方式来决定具体操作)。
不能直接解决是因为Mips指令它有32位。所以mips提供了一个lui指令来存取常数的高16倍,然后允许后续指令设定常数的第16位。其实就是用零来填充第16位。可以实现对于32位立即数的存储。
对比使用和不使用auipc指令的两个例子
使用auipc将相对当前的地址的,比如说00X1234这个字节的内容载入X4寄存器的话,只需要两步,如果不使用auipc指令,就需要通过如下的方法进行实现,首先就是用一个跳转指令连接的指令,把PC加四付给X4寄存器,然后用这个lUI的指令,如X50S1指定,它会有一个第12位置零所以就是0X100,零付给了X5,然后把X4和x5相加付给S4。可以算一下就是X的值就变成了PC加0241004最后再用一个load指令把0X相对于这个X4的这么一个地址的一个值去存进去,可以看到就是相比于不使用这个auipc指令使用之后有非常大的一个简化性。
RISC-V中使用auipc指令的优势
分析:使用变通方法的缺点
代码晦涩冗长,而且需要借助额外的寄存器x5
跳转指令( Jump and Link , JAL )可能会误导流水线的运行,使得流水线执行清空动作。在某些采用了 BTB ( Branch Target Buffer ,分支目标缓冲区)来做跳转预测的处理器上,上面的跳转指令会在 BTB 中留下记录条目,但对跳转预测却并无帮助,因为目标地址等同于下一条顺序执行的指令地址。而 BTB 用来记录之前发生过跳转的指令的 PC 值和目标地址。
auipc 的引入极大减轻了编译器的负担。
回顾: MIPS 中溢出的处理
◆ MIPS 中地址操作数被看作是无符号的数,对地址的操作溢出时, MIPS
忽略溢出。
◆而对非地址操作数的处理, MIPS 需要检测溢出情形◆ MIPS 提供了2类指
add , addi , sub 遇到溢出,产生异常中断
addu , addiu , subu 遇到溢出,不产生异常中断
通过 MIPS 专用寄存器 CAUSE 寄存器,该寄存器用于标识异常的原因。
bit2至bit6这5个 bit 所表示的 Exception Code 位,其值为12时,表示异常的类型为0verflow(表示算术溢出),只有带符号的运算会引起这个异常。
没有定义空操作指令( NOP )
相比于定义 MIPS 定义了空操作,对于 RISC - V 指令集,编译器一般会把ADD1中的立即数、源寄存器、目标寄存器都设置为零,当作空操作指令使用。
> addi x0,x0,0
◆ RISC - V 未定义 nop 的原因
MIPS 需要经常使用 nop 指令来填充无法有效利用起的分支延迟槽。在 RISC - V 中,由于比较和分支用一条指令完成,而且分支指令没有延迟槽,需要用到 nop 的机会小很多。
RISC - V 指令中无分支延迟槽
◆分支延迟槽:指在每一条分支指令后面紧跟的一条或者若干条指令不受分支跳转的影响,不管分支是否跳转,这后面几条指令都一定会被执行。分支指令后面的几条指令所在的位置便是分支延迟槽。
◆ MIPS 使用分支延迟槽的原因:
主要因为早期的 RISC 处理器流水线比较简单,没有高级的硬件动态分支预测器,使用分支延迟槽能够取得可观的效果。
◆分支延迟槽的缺点:对于取指部分的硬件设计十分繁琐
◆ RISC - V 放弃分支延迟槽的原因:
因为现代的高性能处理器的分支预测算法精度已经非常高,可以有强大的分支预测电路保证处理器能够准确地预测跳转执行达到高性能,而对于低功耗小面积的处理器可以选择非常简单的电路实现,由于无须支持分支延迟槽所带来的硬件极大简化也能进一步减少功耗和提高时序。
MIPS 与 RISC - V 存储器访问类指令的比较
RISC - V 与 MIPS 均规定所有的运算必须在寄存器中进行,因此均提供了两条存储器操作指令,用来对存储器进行读写操作
》 Iw 指令,从存储器取操作数到寄存器
》 sw 指令,把寄存器的数存到存储器
◆为了更好适应五级流水线, MIPS 定义了 Ioad 指令的语义, load 上来的数据在 Ioad 指令两个指令后才可用。但对于后来出现更长的流水线,延迟加载带来的收益逐渐消失,因此 RISC - V 不支持延迟加载
◆ MIPS 存储访问类指令均为1-type; RISC - V 中 Iw 指令为1-type; sw 指令为 S - type
RISC - V 中数据在内存中的存
◆数据在内存中的两种存放方式
大端模式:对于每个字长的数据,将高位字节存放在内存地址的低位部分,低位字节则存放在内存地址的高位部分。
小端模式:对于每个字长的数据,将低位字节存放在内存地址的低位部分,高位字节则存放在内存地址的高位部分。
◆ MIPS 中数据在内存中的存放方式一大部分为大端模式,但也设置小端模式
◆ RISC - V 中数据在内存中的存放方式﹣小端模式
RISC - V 设计者主要考虑到目前大部分商用系统均采用小端模式,故
将小端模式定为 RISC - V 的标准模式
MIPS 与 RISC - V 控制转移类指令的比较
与 MIPS 指令集相比, RISC - V 的跳转指令的设计特色
RISC - V 本身并不专设状态寄存器来做溢出位、加法进位、零值标识等。 RISC - V 将比较和跳转相结合,而且利用条件跳转来对“溢
出”、“零值”等做出判断,从而简化了处理器结构。
RISC - V 中的条件跳转指令与不同之处
在有条件跳转指令中, RISC - V 舍弃了条件编码传统的 RISC (包括 MIPS )中存在条件编码
标志位会被编码即为条件编码,并成为指令编码的一部分。
step 1.在状态寄存器中设置标志位(例如溢出标志位( Overflow )、零标志( Zero Flag )、进位标志( Carry )
step 2.后续指令根据标志位决定是否需要执行比如对“ if ( a =10){…·}”这样的高级代码,
编译器的常用处理方式是在一个计算指令后跟随一个条件执行指令,如下面的伪代码所示:
subtract ion ( reg ister -10) #减法,结果可以被丢弃
branch if zero flag is not set #如果不相等则跳转
使用条件编码的优缺点
在有条件跳转指令中, RISC - V 舍弃了条件编码
√条件编码的优点:
让条件跳转指令变得相对比较简单。(不涉及对通用寄存器的读取,只涉及标志位,这样跳转条件就可以在流水线比较靠前的阶段被判断出来)
√条件编码的缺点
①条件编码需要在指令编码中占用一定的位置。
②需要在条件跳转指令之前安排另一条指令来设置标志位,降低了代码密度。
③硬件也需要有专门的状态寄存器,记录各种标志位。
RISC - V 舍弃条件编码后的优缺点
在有条件跳转指令中, RISC - V 舍弃了条件编码
RISC - V 的设计者将上面标志位设置指令合并到条件跳转指令中,并在条件跳转指令中直接读取通用寄存器做判断。
√优点
①没有条件编码,节省下的位可以被指令编码派作其他用途从而减小指令集规模。
②只要一条指令就可以实现上面需要两条指令来实现的功能
提高了代码密度。
③不需要专门的状态寄存器来记录各种标志位,降低了硬件的开销。
√缺点
跳转条件的判定在流水线中后移 影响不大
权衡:由于需要在条件跳转指令中直接读取通用寄存器,跳转条件要在流水线中比较靠后的阶段才能判断。但 RISC - V 的设计者认为,目前跳转预测的准确度和精确度都已经大幅度提高,将跳转条件的判定在流水线中后移并不会给性能带来太大的负面影响。
MIPS 与 RISC - V 控制转移类指令的比较
与 MIPS 指令集相比, RISC - V 的跳转指令的设计特色
RISC - V 为无条件跳转指令专门定义了 J - type (衍生于 U - type )和 B - type (衍生于 S - type )。对立即数的某些位置做了位置调整,在一定程度上降低硬件设计的开销。
四、总结
MIPS 指令集概括为3个指令类>算术逻辑指令类
Add , sub , and , or , sIt 等>存储器访问指令类
Lw , Sw 等>转移指令类
Beq , J 等
1.舍弃溢出标志
2.舍弃空操作指令
3.“20+12=32”的32bit立即数构建方式
4.舍弃条件编码
5.六种指令格式编码
6.采用小端模式存放数据
1、尽量小,尽量简洁
2、不含乘、除、移位指令
3、不含浮点指令
1.含必选的基础指令集RV32I及其扩展指令集
2.通用寄存器组可配置