摩尔芯闻 > 行业新闻 > 半导体 > RISC-V 全新指令构架介绍,它能否甩脱 Arm 和 X86 的束缚?

RISC-V 全新指令构架介绍,它能否甩脱 Arm 和 X86 的束缚?

硬件十万个为什么 ·2019-07-25 19:56·与非网
阅读:5591

RISC -V指令集架构介绍

RISC-V (英文发音为"risk-five")是一个全新的指令集架构,该架构最初由美国加州大学伯克利分校的EECS部门的计算机科学部门的Krste Asanovic教授、Andrew Waterman和Yunsup Lee等开发人员于2010年发明。其中"RISC"表示精简指令集,而其中"V"表示伯克利分校从RISC I开始设计的第五代指令集。

2010年,加州大学伯克利分校的研究团队分析了 ARM 、MIPS、SPARC、 X86 等多种指令集,发现这些指令集不仅复杂度不断提升,且还存在知识产权风险,而处理器架构种类和处理能力并无直接关联。针对以上问题,该小组设计并推出了一套基于BSD协议许可的免费开放的指令集架构RISC-V,其原型芯片也于2013年1月成功流片。RISC-V指令集具有性能优越,彻底免费开放两大特征。RSIC-V的设计目标是能够满足从微控制器到超级计算机等各种复杂程度的处理器需求,支持从FPGA、ASIC乃至未来器件等多种实现方式,同时能够高效地实现各种微结构,支持大量定制与加速功能,并与现有软件及编程语言可良好适配。RISC-V产业生态正进入快速发展期。加州大学伯克利分校在2015年成立非盈利组织RISC-V基金会,该基金会旨在聚合全球创新力量共同构建开放、合作的软硬件社区,打造RISC-V生态系统。三年多来,谷歌、高通、IBM、英伟达、NXP、、西部数据、Microsemi、中科院计算所、麻省理工学院、华盛顿大学、英国宇航系统公司等100多个企业和研究机构先后加入了RISC-V基金会。

RISC-V基金会负责维护RSIC-V指令集标准手册与架构文档,每年RISC-V基金会都会举办各种专题讨论会和全球活动,将广阔的生态系统聚集在一起,讨论当前和未来RISC-V项目和实施,以促进RISC-V阵营的交流和发展。一款指令集架构能否取得成功,很大程度依赖于软件生态环境。当前可用的RISC-V软件工具包括GNU编译器集合(GCC工具链、GDB调试器),LLVM工具链,OVPsim仿真器(以及RISC-V快速处理器模型库),Spike仿真器和QEMU模拟器。当前支持该指令集架构的操作系统包括FreeRTOS、SylixOS、RT-Thread、Linux等。RTRISC-V架构在短时间内还无法撼动x86和ARM架构,但是随着越来越多的公司和项目采用RSIC-V架构的处理器,相信RSIC-V的软件生态会逐渐壮大起来。

通用寄存器模型

RISC-V具有32个整数寄存器x0~x31,其中31个通用寄存器x1~x31,它们保存了整数数值,寄存器x0是硬件连线的常数0。当实现浮点扩展时具体32个浮点寄存器f0~f31。对于RV32,其x寄存器是32位宽度的,对于RV64,它们是64位宽度的。

其中RISC-V寄存器调用约定如下图:

RISC-V调用约定尽可能在寄存器中传递参数,其多达8个整数寄存器a0-a7,和多达8个个浮点寄存器fa0-fa7用于这个目    的。函数的返回值存放在整数寄存器a0和a1、浮点寄存器fa0和fa1中。返回值包含1个或者2个浮点值的结构体时候通过浮点寄存器返回,其他返回值能放入a0和a1。更大的返回值都全部通过存储器返回,调用者分配这些存储器区域,并将它作为第一个隐藏参数传递给被调用者。在标准RISC-V调用约定中,栈是向下增长并且栈指针总是对齐到16字节。

除了参数寄存器和返回值寄存器之外,7个整数寄存器t0-t6和12个浮点寄存器ft0-ft11是临时寄存器,它们在调用过程中被破坏,如果后面还有使用的话,在调用者中必须先保存。12个整数寄存器s0-s11和12个浮点寄存器fs0-fs11在调用过程后被保持不变,如果需要使用的 话,在被调用者中必须保存。

RISC-V特权级

RISC-V定义了四种特权级模式。不同的特权级包含多个 CSR(control and status register,控制和状态寄存器)寄存器。四种特权级信息如下表1.1:

特权级被用于在不同的软件栈部件之间提供保护,试图执行当前特权模式不允许的操作,将导致一个异常的产生。机器级是最高级特权,也是RISC-V硬件平台唯一必须的特权级。运行于机器模式(M-mode)下的代码是固有可信的,因为它可以在低层次访问机器的实现。用户模式(U-mode)和管理员模式(S-mode)被分别用于传统应用程序和操作系统,而 Hypervisor 模式(H-mode)则是为了支持虚拟机监视器。

所有硬件实现必须提供 M-mode,因为这是唯一的模式可以不受限制地访问整个机器。最简单的 RISC-V 实现可以仅提供M-mode,虽然这样做不能为防止不正确的、恶意应用代码提供保护。许多RISC-V实现还支持至少一个用户模(U-mode)以对系统的其他部分进行 保护,防止被应用程序代码破坏。

标准 RISC-V ISA 设置了一个 12 位的编码空间(csr[11:0])可用于 4096 个 CSR。根据约定,CSR 地址的高 4 位(csr[11:8])用于编码CSR根据特权级读写的可访问性。最高2位(csr[11:10])指示这个寄存器是否是可以读/写(00、01或者10),还是只读 的(11)。后面 2 位(csr[9:8])指示了能够访问这个 CSR 所需要的最低特权级(用户级是 00, 管理员级是 01)。

试图访问一个不存在的CSR将产生一个非法指令异常。试图访问一个没有相应特权的CSR或者写一个只读寄存器,也将产生一个非法指令异常。一次读/写寄存器可能包含了某 些位是只读的,此种情况下,写入只读位被忽略。

CSR相关寄存器相关描述可参考特权级指令手册,其中机器模式寄存器如下图:

用于读取CSR的汇编语言伪指令CSRR rd, csr被编码为CSRRS rd, csr, x0。用于写CSR的汇编语言伪指令CSRW csr, rs1 被编码为 CSRRW x0, csr, rs1,而伪指令 CSRWI csr, zimm 被编码 为 CSRRWI x0, csr, zimm。

RISC-V指令集描述

RISC-V 被设计成可以支持丰富的定制化和特殊化。基本整数 ISA 可被一个或者多个可选指令集扩展进行增强,但是基本整数指令集不能被重新定义。我们将RISC-V指令集扩展分为标准扩展和非标准扩展。标准扩展一般都是有用的,并且与其它的标准扩展并不冲突。非标准扩展是高度特殊化的,并可能与其它的标准扩展或者非标准扩展冲突。指令集扩展根据基本整数指令集宽度不同,可能有轻微的功能差异。RISC-V为基本指令和指令集扩展开发了一个命名规则,其命令规则如下图。

为了支持更一般的软件开发,定义了一组标准扩展,提供乘法/除法、原子操作以及单精度、双精度浮点算术。基本整数 ISA 被命名为“I”(依据整数寄存器宽度不同,前缀 RV32 或者 RV64),其中包含了整数计算指令、整数 load、整数 store 和控制流指令,并且在所有RISC-V实现中,都是必须的。标准整数乘法和除法扩展被命名为“M”,其中增加了对保存在整数寄存器中的值进行乘法和除法的指令。标准原子指令扩展被命名为“A”,其中增加了对存储器进行原子的读、修改和写操作的指令,以支持处理器间的同步。标准单精度浮点 扩展,被命名为“F”,增加了浮点寄存器、单精度计算指令、单精度 load 和 store 指令。标准双精度浮点扩展,被命名为“D”,扩展了浮点寄存器,并增加了双精度计算指令、load 和 store 指令。一个基本整数内核加上这四个标准扩展(“IMAFD”),被缩写为“G”,它提供 了一个通用的标量指令集。RV32G 和 RV64G 现在是我们编译器工具链的缺省目标机器。下图描述了这些扩展以及其他计划中的标准 RISC-V 扩展。

基本RISC-V ISA具有32位固定长度指令,并且必须在32位边界对齐。然而,标准RISC-V编码模式被设计成支持变长指令的扩展,在这个扩展中,每条指令长度可以是16位指令包裹长度的整数倍,并且这些指令包裹必须在16位边界对齐。标准压缩ISA扩展,通过提供压缩的16位指令,减少了代码大小,并放松了对齐要求,允许所有指令(16 位和 32 位)对齐到任意 16 位边界,以提高代码密度。

标准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,保留给未来更长的 指令编码。

在基本ISA中,有四种核心指令格式(R/I/S/U),如图 2.2所示。所有的指令都是固定 32位长度的,并且在存储器中必须在4字节边界对齐。当发生一个条件分支或者无条件转移 而且目标地址不是对齐到4字节时,将会产生一个指令地址不对齐的异常。如果条件分支没 有发生(not taken),那么将不会产生一个取指不对齐异常。

在所有格式中,RISC-V将源寄存器(rs1和rs2)和目标寄存器(rd)固定在同样的位置,以简化指令译码。在指令中,立即数被打包,朝着最左边可用位的方向,并且是分配好的,以减少硬件复杂度。特别地,所有立即数的符号位总是在指令的第31位,以加速符号扩 展电路。

一般操作系统底层开发人员才涉及编写汇编代码,且一般使用编译器提供伪指令进行编程,RISC-V支持的伪指令如下图。掌握下面的伪指令已经足够满足汇编程序员进行汇编代码编写。

表21.2 RSIC-V CSR伪指令

RISC-V特点

1 模块化的指令子集

RISC-V的指令集使用模块化的方式进行组织,每一个模块使用一个英文字母来表示。RISC-V最基本也是唯一强制要求实现的指令集部分是由I字母表示的基本整数指令子集,使用该整数指令子集,便能够实现完整的软件编译器。其他的指令子集部分均为可选的模块,具有代表性的模块包括M/A/F/D/C,如表1所示。

表1 RISC-V的模块化指令集

为了提高代码密度,RISC-V架构也提供可选的“压缩”指令子集,由英文字母C表示。压缩指令的指令编码长度为16比特,而普通的非压缩指令的长度为32比特。以上这些模块的一个特定组合“IMAFD”,也被称为“通用”组合,由英文字母G表示。因此RV32G表示RV32IMAFD,同理RV64G表示RV64IMAFD。

为了进一步减少面积,RISC-V架构还提供一种“嵌入式”架构,由英文字母E表示。该架构主要用于追求极低面积与功耗的深嵌入式场景。该架构仅需要支持16个通用整数寄存器,而非嵌入式的普通架构则需要支持32个通用整数寄存器。

通过以上的模块化指令集,能够选择不同的组合来满足不同的应用。譬如,追求小面积低功耗的嵌入式场景可以选择使用RV32EC架构;而大型的64位架构则可以选择RV64G。

除了上述的模块,还有若干的模块包括L、B、P、V和T等。这些扩展目前大多数还在不断完善和定义中,尚未最终确定,因此本文在此不做详细论述。

2  可配置的通用寄存器组

RISC-V架构支持32位或者64位的架构,32位架构由RV32表示,其每个通用寄存器的宽度为32比特;64位架构由RV64表示,其每个通用寄存器的宽度为64比特。

RISC-V架构的整数通用寄存器组,包含32个(I架构)或者16个(E架构)通用整数寄存器,其中整数寄存器0被预留为常数0,其他的31个(I架构)或者15个(E架构)为普通的通用整数寄存器。

如果使用了浮点模块(F或者D),则需要另外一个独立的浮点寄存器组,包含32个通用浮点寄存器。如果仅使用F模块的浮点指令子集,则每个通用浮点寄存器的宽度为32比特;如果使用了D模块的浮点指令子集,则每个通用浮点寄存器的宽度为64比特。

3 规整的指令编码

在流水线中能够尽早尽快的读取通用寄存器组,往往是处理器流水线设计的期望之一,这样可以提高处理器性能和优化时序。这个看似简单的道理在很多现存的商用RISC架构中都难以实现,因为经过多年反复修改不断添加新指令后,其指令编码中的寄存器索引位置变得非常的凌乱,给译码器造成了负担。

得益于后发优势和总结了多年来处理器发展的教训,RISC-V的指令集编码非常的规整,指令所需的通用寄存器的索引(Index)都被放在固定的位置,如图2所示。因此指令译码器(Instruction Decoder)可以非常便捷的译码出寄存器索引然后读取通用寄存器组(Register File,Regfile)。

图2 RV32I规整的指令编码格式

4 简洁的存储器访问指令

与所有的RISC处理器架构一样,RISC-V架构使用专用的存储器读(Load)指令和存储器写(Store)指令访问存储器(Memory),其他的普通指令无法访问存储器,这种架构是RISC架构的常用的一个基本策略,这种策略使得处理器核的硬件设计变得简单。

存储器访问的基本单位是字节(Byte)。RISC-V的存储器读和存储器写指令支持一个字节(8位),半字(16位),单字(32位)为单位的存储器读写操作,如果是64位架构还可以支持一个双字(64位)为单位的存储器读写操作。

RISC-V架构的存储器访问指令还有如下显著特点:

为了提高存储器读写的性能,RISC-V架构推荐使用地址对齐的存储器读写操作,但是地址非对齐的存储器操作RISC-V架构也支持,处理器可以选择用硬件来支持,也可以选择用软件来支持。

由于现在的主流应用是小端格式(Little-Endian),RISC-V架构仅支持小端格式。有关小端格式和大端格式的定义和区别,本文在此不做过多介绍,若对此不甚了解的初学者可以自行查阅学习。

很多的RISC处理器都支持地址自增或者自减模式,这种自增或者自减的模式虽然能够提高处理器访问连续存储器地址区间的性能,但是也增加了设计处理器的难度。RISC-V架构的存储器读和存储器写指令不支持地址自增自减的模式。

RISC-V架构采用松散存储器模型(Relaxed Memory Model),松散存储器模型对于访问不同地址的存储器读写指令的执行顺序不作要求,除非使用明确的存储器屏障(Fence)指令加以屏蔽。

这些选择都清楚地反映了RISC-V架构力图简化基本指令集,从而简化硬件设计的哲学。RISC-V架构如此定义非常合理,能够达到能屈能伸的效果。譬如:对于低功耗的简单 CPU ,可以使用非常简单的硬件电路即可完成设计;而对于追求高性能的超标量处理器则可以通过复杂设计的动态硬件调度能力来提高性能。

5 高效的分支跳转指令

RISC-V架构有两条无条件跳转指令(Unconditional Jump),jal与jalr指令。跳转链接(Jump and Link)指令jal可用于进行子程序调用,同时将子程序返回地址存在链接寄存器(Link Register:由某一个通用整数寄存器担任)中。跳转链接寄存器(Jump and Link-Register)指令jalr指令能够用于子程序返回指令,通过将jal指令(跳转进入子程序)保存的链接寄存器用于jalr指令的基地址寄存器,则可以从子程序返回。

RISC-V架构有6条带条件跳转指令(Conditional Branch),这种带条件的跳转指令跟普通的运算指令一样直接使用2个整数操作数,然后对其进行比较,如果比较的条件满足时,则进行跳转。因此,此类指令将比较与跳转两个操作放到了一条指令里完成。

作为比较,很多的其他RISC架构的处理器需要使用两条独立的指令。第一条指令先使用比较指令,比较的结果被保存到状态寄存器之中;第二条指令使用跳转指令,判断前一条指令保存在状态寄存器当中的比较结果为真时则进行跳转。相比而言RISC-V的这种带条件跳转指令不仅减少了指令的条数,同时硬件设计上更加简单。

对于没有配备硬件分支预测器的低端CPU,为了保证其性能,RISC-V的架构明确要求其采用默认的静态分支预测机制,即:如果是向后跳转的条件跳转指令,则预测为“跳”;如果是向前跳转的条件跳转指令,则预测为“不跳”,并且RISC-V架构要求编译器也按照这种默认的静态分支预测机制来编译生成汇编代码,从而让低端的CPU也能得到不错的性能。

为了使硬件设计尽量简单,RISC-V架构特地定义了所有的带条件跳转指令跳转目标的偏移量(相对于当前指令的地址)都是有符号数,并且其符号位被编码在固定的位置。因此,这种静态预测机制在硬件上非常容易实现,硬件译码器可以轻松的找到这个固定的位置,并判断其是0还是1来判断其是正数还是负数,如果是负数则表示跳转的目标地址为当前地址减去偏移量,也就是向后跳转,则预测为“跳”。当然对于配备有硬件分支预测器的高端CPU,则可以采用高级的动态分支预测机制来保证性能。

6 简洁的子程序调用

为了理解此节,需先对一般RISC架构中程序调用子函数的过程予以介绍,其过程如下:

进入子函数之后需要用存储器写(Store)指令来将当前的上下文(通用寄存器等的值)保存到系统存储器的堆栈区内,这个过程通常称为“保存现场”。

在退出子程序之时,需要用存储器读(Load)指令来将之前保存的上下文(通用寄存器等的值)从系统存储器的堆栈区读出来,这个过程通常称为“恢复现场”。

“保存现场”和“恢复现场”的过程通常由编译器编译生成的指令来完成,使用高层语言(譬如C或者C++)开发的开发者对此可以不用太关心。高层语言的程序中直接写上一个子函数调用即可,但是这个底层发生的“保存现场”和“恢复现场”的过程却是实实在在地发生着(可以从编译出的汇编语言里面看到那些“保存现场”和“恢复现场”的汇编指令),并且还需要消耗若干的CPU执行时间。

为了加速这个“保存现场”和“恢复现场”的过程,有的RISC架构发明了一次写多个寄存器到存储器中(Store Multiple),或者一次从存储器中读多个寄存器出来(Load Multiple)的指令,此类指令的好处是一条指令就可以完成很多事情,从而减少汇编指令的代码量,节省代码的空间大小。但是此种“Load Multiple”和“Store Multiple”的弊端是会让CPU的硬件设计变得复杂,增加硬件的开销,也可能损伤时序使得CPU的主频无法提高,笔者在曾经设计此类处理器时便深受其苦。

RISC-V架构则放弃使用这种“Load Multiple”和“Store Multiple”指令。并解释,如果有的场合比较介意这种“保存现场”和“恢复现场”的指令条数,那么可以使用公用的程序库(专门用于保存和恢复现场)来进行,这样就可以省掉在每个子函数调用的过程中都放置数目不等的“保存现场”和“恢复现场”的指令。

此选择再次印证了RISC-V追求硬件简单的哲学,因为放弃“Load Multiple”和“Store Multiple”指令可以大幅简化CPU的硬件设计,对于低功耗小面积的CPU可以选择非常简单的电路进行实现,而高性能超标量处理器由于硬件动态调度能力很强,可以有强大的分支预测电路保证CPU能够快速的跳转执行,从而可以选择使用公用的程序库(专门用于保存和恢复现场)的方式减少代码量,但是同时达到高性能。

7 无条件码执行

很多早期的RISC架构发明了带条件码的指令,譬如在指令编码的头几位表示的是条件码(Conditional Code),只有该条件码对应的条件为真时,该指令才被真正执行。

这种将条件码编码到指令中的形式可以使得编译器将短小的循环编译成带条件码的指令,而不用编译成分支跳转指令。这样便减少了分支跳转的出现,一方面减少了指令的数目;另一方面也避免了分支跳转带来的性能损失。然而,这种“条件码”指令的弊端同样会使得CPU的硬件设计变得复杂,增加硬件的开销,也可能损伤时序使得CPU的主频无法提高,笔者在曾经设计此类处理器时便深受其苦。

RISC-V架构则放弃使用这种带“条件码”指令的方式,对于任何的条件判断都使用普通的带条件分支跳转指令。此选择再次印证了RISC-V追求硬件简单的哲学,因为放弃带“条件码”指令的方式可以大幅简化CPU的硬件设计,对于低功耗小面积的CPU可以选择非常简单的电路进行实现,而高性能超标量处理器由于硬件动态调度能力很强,可以有强大的分支预测电路保证CPU能够快速的跳转执行达到高性能。

8 无分支延迟槽

很多早期的RISC架构均使用了“分支延迟槽(Delay Slot)”,最具有代表性的便是MIPS架构,在很多经典的计算机体系结构教材中,均使用MIPS对分支延迟槽进行过介绍。分支延迟槽就是指在每一条分支指令后面紧跟的一条或者若干条指令不受分支跳转的影响,不管分支是否跳转,这后面的几条指令都一定会被执行。

早期的RISC架构很多采用了分支延迟槽诞生的原因主要是因为当时的处理器流水线比较简单,没有使用高级的硬件动态分支预测器,所以使用分支延迟槽能够取得可观的性能效果。然而,这种分支延迟槽使得CPU的硬件设计变得极为的别扭,CPU设计人员对此往往苦不堪言。

RISC-V架构则放弃了分支延迟槽,再次印证了RISC-V力图简化硬件的哲学,因为现代的高性能处理器的分支预测算法精度已经非常高,可以有强大的分支预测电路保证CPU能够准确的预测跳转执行达到高性能。而对于低功耗小面积的CPU,由于无需支持分支延迟槽,硬件得到极大简化,也能进一步减少功耗和提高时序。

9 无零开销硬件循环

很多RISC架构还支持零开销硬件循环(Zero Overhead Hardware Loop)指令,其思想是通过硬件的直接参与,通过设置某些循环次数寄存器(Loop Count),然后可以让程序自动地进行循环,每一次循环则Loop Count自动减1,这样持续循环直到Loop Count的值变成0,则退出循环。

之所以提出发明这种硬件协助的零开销循环是因为在软件代码中的for 循环(for i=0; i<N; i++)极为常见,而这种软件代码通过编译器编译之后,往往会编译成若干条加法指令和条件分支跳转指令,从而达到循环的效果。一方面这些加法和条件跳转指令占据了指令的条数;另外一方面条件分支跳转如存在着分支预测的性能问题。而硬件协助的零开销循环,则将这些工作由硬件直接完成,省掉了这些加法和条件跳转指令,减少了指令条数且提高了性能。

然有得必有失,此类零开销硬件循环指令大幅地增加了硬件设计的复杂度。因此,零开销循环指令与RISC-V架构简化硬件的哲学是完全相反的,在RISC-V架构中自然没有使用此类零开销硬件循环指令。

10 简洁的运算指令

在本章第2.1节中曾经提到RISC-V架构使用模块化的方式组织不同的指令子集,最基本的整数指令子集(I字母表示)支持的运算包括加法、减法、移位、按位逻辑操作和比较操作。这些基本的运算操作能够通过组合或者函数库的方式完成更多的复杂操作(譬如乘除法和浮点操作),从而能够完成大多数的软件操作。

整数乘除法指令子集(M字母表示)支持的运算包括,有符号或者无符号的乘法和除法操作。乘法操作能够支持两个32位的整数相乘得到一个64位的结果;除法操作能够支持两个32位的整数相除得到一个32位的商与32位的余数。

单精度浮点指令子集(F字母表示)与双精度浮点指令子集(D字母表示)支持的运算包括浮点加减法,乘除法,乘累加,开平方根和比较等操作,同时提供整数与浮点,单精度与双精度浮点彼此之间的格式转换操作。

很多RISC架构的处理器在运算指令产生错误之时,譬如上溢(Overflow)、下溢(Underflow)、非规格化浮点数(Subnormal)和除零(Divide by Zero),都会产生软件异常。RISC-V架构的一个特殊之处是对任何的运算指令错误(包括整数与浮点指令)均不产生异常,而是产生某个特殊的默认值,同时,设置某些状态寄存器的状态位。RISC-V架构推荐软件通过其他方法来找到这些错误。再次清楚地反映了RISC-V架构力图简化基本的指令集,从而简化硬件设计的哲学。

11 优雅的压缩指令子集

基本的RISC-V基本整数指令子集(字母I表示 )规定的指令长度均为等长的32位,这种等长指令定义使得仅支持整数指令子集的基本RISC-V CPU非常容易设计。但是等长的32位编码指令也会造成代码体积(Code Size)相对较大的问题。

为了满足某些对于代码体积要求较高的场景(譬如嵌入式领域),RISC-V定义了一种可选的压缩(Compressed)指令子集,由字母C表示,也可以由RVC表示。RISC-V具有后发优势,从一开始便规划了压缩指令,预留了足够的编码空间,16位长指令与普通的32位长指令可以无缝自由地交织在一起,处理器也没有定义额外的状态。

RISC-V压缩指令的另外一个特别之处是,16位指令的压缩策略是将一部分普通最常用的的32位指令中的信息进行压缩重排得到(譬如假设一条指令使用了两个同样的操作数索引,则可以省去其中一个索引的编码空间),因此每一条16位长的指令都能一一找到其对应的原始32位指令。因此,程序编译成为压缩指令仅在汇编器阶段就可以完成,极大的简化了编译器工具链的负担。

RISC-V架构的研究者进行了详细的代码体积分析,如图3所示,通过分析结果可以看出,RV32C的代码体积相比RV32的代码体积减少了百分之四十,并且与ARM,MIPS和x86等架构相比都有不错的表现。

图3 各指令集架构的代码密度比较(数据越小越好)

12 特权模式

RISC-V架构定义了三种工作模式,又称特权模式(

Privileged Mode):

Machine Mode:机器模式,简称M Mode。

Supervisor Mode:监督模式,简称S Mode。

User Mode:用户模式,简称U Mode。

RISC-V架构定义M Mode为必选模式,另外两种为可选模式。通过不同的模式组合可以实现不同的系统。

RISC-V架构也支持几种不同的存储器地址管理机制,包括对于物理地址和虚拟地址的管理机制,使得RISC-V架构能够支持从简单的嵌入式系统(直接操作物理地址)到复杂的操作系统(直接操作虚拟地址)的各种系统。

2.13 CSR寄存器

RISC-V架构定义了一些控制和状态寄存器(Control and Status Register,CSR),用于配置或记录一些运行的状态。CSR寄存器是处理器核内部的寄存器,使用其自己的地址编码空间和存储器寻址的地址区间完全无关系。

CSR寄存器的访问采用专用的CSR指令,包括CSRRW、CSRRS、CSRRC、CSRRWI、CSRRSI以及CSRRCI指令。

2.14 中断和异常

中断和异常机制往往是处理器指令集架构中最为复杂而关键的部分。RISC-V架构定义了一套相对简单基本的中断和异常机制,但是也允许用户对其进行定制和扩展。

2.15 矢量指令子集

RISC-V架构目前虽然还没有定型矢量(Vector)指令子集,但是从目前的草案中已经可以看出,RISC-V矢量指令子集的设计理念非常的先进,由于后发优势及借助矢量架构多年发展成熟的结论,RISC-V架构将使用可变长度的矢量,而不是矢量定长的SIMD指令集(譬如ARM的NEON和Intel的MMX),从而能够灵活的支持不同的实现。追求低功耗小面积的CPU可以选择使用长度较短的硬件矢量进行实现,而高性能的CPU则可以选择较长的硬件矢量进行实现,并且同样的软件代码能够彼此兼容。

2.16 自定制指令扩展

除了上述阐述的模块化指令子集的可扩展、可选择,RISC-V架构还有一个非常重要的特性,那就是支持第三方的扩展。用户可以扩展自己的指令子集,RISC-V预留了大量的指令编码空间用于用户的自定义扩展,同时,还定义了四条Custom指令可供用户直接使用,每条Custom指令都有几个比特位的子编码空间预留,因此,用户可以直接使用四条Custom指令扩展出几十条自定义的指令。

关于RISC-V生态

RISC-V的生态系统,不会由RISC-V基金会定义,决定权在于每位参与者

"RISC-V的增长速度非常快,是所有开源硬件生态里面增长最快的,甚至比很多开源软件的生态增长要快得多。"Calista向小编介绍了RISC-V生态得以繁荣的原因:RISC-V是一个开源的精简指令集架构,在这个精简的指令集之上,可以采用模块化的方式来添加不同的指令集,因此灵活性比较高。这样不同领域的应用可以针对指令集进行不同侧重的优化,从而达到处理器更极致的功耗优化和性能提升。这是RISC-V相较X86等指令集最大的优势所在,很多开发者也都是看中了这一点。但是这样不可避免地会出现标准不统一的问题,碎片化的情况可能会影响其发展速度。为此,其实基金会也有一套策略。

首先,基础的指令集保持统一,这样实现了最基本的软硬件的接口的统一。

然后RISC-V基金会会提供一套标准的拓展指令集,通过这样的统一的拓展指令集,那么就可以确保上层软件和底层硬件的通用性。当然如果开发者想要深度定制,可以在预留位置上去自定义指令集,并不会与标准指令集冲突。

而且基金会鼓励大家可以将自己的拓展指令集分享出来,如果需求的市场成长机会较大的话,开发者可以要求基金会提出讨论,大家一致认可就会加入到作为一个统一标准的拓展指令集。

对此Calista女士还特别解释到,因为生态系统中存在着各种各样不同类型的参与者,所以每个成员的需求都不尽相同。基金会的工作就是要确认参与者提出的这个拓展指令集面对的需求是不是广泛的、具有代表性的。然后再确认如果要满足这些需求,哪些是关键成员,然后召集大家一起进行讨论。RISC-V基金会并不会去定义这个生态系统是什么样子的,一定要有什么,而是由成员来决定,什么是必要的,然后大家一起来贡献力量完成这一需求。

降低生态门槛,看客与球星都在场内

其实对于ISA开源生态而言,门槛之高无需多言。这也是之前很多开源ISA生态发展不起来的主要原因之一。而Calista深知这一点,并表示将降低RISC-V生态的门槛。她表示,现在RISC-V的生态正处于一个阶段化过程。因为RISC-V其实还处于起步阶段,这个过程需要一定的时间。因为对于风险和回报的前景未知,所以大多数都在等别人迈出第一步。对于RISC-V的优势,大家还是有一些犹豫。基金会的价值就体现在此,每个参与者都不会是独自面对和解决问题,借助生态系统内大量参与者的投入,很多单独开发时面临的棘手问题都可以更容易地找到解决办法。

在这个生态系统里面,既有球技高超的“球星”,他们乐于分享自己的拓展指令集等资源;也有水平初级的“看客”,他们并不能做出贡献,但是他们可以持续关注,并得到拓展指令集的支持。他们也不是一无贡献,他们的存在会扩大技术的影响面和社会影响力,并逐渐提高市场和社会的接受程度。所以每一个角色在这一开源生态里面,都很好地表演着自己的角色,发挥着自己的作用,共同促进RISC-V的持续发展。

未来的计算需求,可能需要多种不同形态的处理器来解决,并不仅仅局限于目前的MCU、MPC、CPU、GPU等等,RISC-V的灵活性是一个优势。对于中国参与者而言,他们有的乐于尝试新鲜事物,认可RISC-V的可玩性,拥簇在生态系统周围;有的则将RISC-V看作时绝地反击的机会,要从这里甩脱Arm和X86的束缚。RISC-V基金会并不做任何定义,采用放养的方式,想必RISC-V生态的成长将不可估量。

分享到:
微信 新浪微博 QQ空间 LinkedIn

上一篇:常用单片机电路设计模块解说

下一篇:LED光引擎东风再起 正迎来广阔的发展空间

打开摩尔直播,更多新闻内容
半导体大咖直播分享高清观看
立即下载