老黄Charlin 发表于 2023-6-3 12:28:22

一文了解RISC-V



1.RISC-V概述及历史
RISC-V 起源于加州大学伯克利分校。在 2010 年夏季,Krste Asanovic 教授带领他的两个学生 Andrew Waterman 和 Yunsup Lee 启动了一个3个月的项目,目标是针对 x86 和ARM 指令集架构复杂和需要IP 授权的问题,开发一个简化和开放的指令集架构。RISC-V基金会创建于2015 年,是一家非营利组织。基金会董事会最早由 Bluespec、Google、Microsemi、NVIDIA、NXP、UC Berkeley、Western Digital 七家单位组成,目前的主席是 Krste Asanovi 教授。成员单位现在已经比较多了:

基金会为核心芯片架构制定标准和建立生态,标准公开免费下载。基金会旗下有超过 1 000 家成员,包括高通、NXP、阿里巴巴和华为等。RISC-V 基金会成员可以使用 RISC-V 商标。RISC-V 指令集架构采用开源BSD 授权,任何企业、高校和个人都可以遵循RISC-V 架构指南设计自己的 CPU.秉承开放、中立的宗旨,RISC-V 基金会总部从美国迁往瑞士,并于 2020年3月完成在瑞士的注册,更名为 RISC-V 国际基金会(RISC-V International Association)。近日,基金会 CEO Calista Redmond 撰文 RISC-V Catalyst for ChangRISC-V,文章指出,RISC-V 标准是免费和开放的,没有任何一个实体可以控制RISC-V 技术。企业、学术界和机构都可以自由地在 RISC-V 指令集架构上进行创新,共同推动计算前沿技术的迅速发展。
自RISC-V 架构诞生以来,市场上已有数十个版本的 RISC-V 内核和SoC芯片它们中的一部分是开源免费的,而商业公司开发的 RISC-V 处理器内核和平台是需要商业授权的。某些商业公司开发用于内部使用的 RISC-V 内核,但也可以开源运作。西部数据的 SweRV架构(RV32IMC)是 RISC-V内核处理器的典型代表,它是一个32 bit 顺序执行指令架构,具有双向超标量设计和9 级流水线,采用 28 nm 工艺技术实现,运行频率高达 1.8 GHz,可提供 4.9 CoreMark/MHz 的性能,略高于ARM的 Cortex A15,已经在西部数据的 SSD和 HDD 控制器上使用,SweRV项目是一个开源项目(Chip Alliance)典型的开源 RISC-V 内核有 Rocket Core,它是加州大学伯克利分校开发的一个经典的 RV64 设计。伯克利分校还开发了一个 BOOM Core,它与 Rocket Core不同的是面向更高的性能。苏黎世理工大学(ETH Zurich)开发的 Zero-riscy,是经典的RV32 设计。苏黎世理工大学还开发了另外一款 RISC-V R15CY Core,可配置成RV32E,面向的是超低功耗、超小芯片面积的应用场景。由 Clifford Wolf 开发的RISC-V Core-Pico RV32,其内核重点在于追求面积和 CPU频率的优化。
开源的 RISC-V 内核非常适用于研究和教学,但用于商业芯片设计还有许多工作要做。SiFive(美国赛防科技)由 Yunsup Lee 创立,他也是 RISC-V 的创始人之一。2017 年 SiFive公司发布首个 RISC-V 内核SOC平台家族,以及相关支持软件和开发板。在这些芯片中,包括采用 28 nm 制造技术,支持 Linux 操作系统的64位多核CPUU500,以及采用 180 nm 制造技术的多外设低成本IOT 处理器内核 E300。
国产处理器芯片起步较晚,从2013年至今,集成电路每年的进口额均超过了 2000 亿美元。RISC-V和AI(人工智能)芯片是我国最有希望突破的领域之一。RISC-V使用的领域还是对于生态依赖比较小的嵌入式系统或者新兴的IoT(物联网)、边缘计算、人工智能领域,但RISC-V得到了产业界和社区的广泛支持,同时,现在很多企业开始对 RISC-V 重视,所以说RISC-V 应用前景会非常乐观。

2.RISC-V指令集特点
CPU 支持的所有指令和指令的字节级编码就是这个 CPU 的指令集架构(Instruction Set Architecture,ISA),指令集在计算机软件和硬件之间搭起了一座桥梁。不同的 CPU 家族,例如 86、PowerPC 和 ARM,都有不同的 ISA。RISC-VISA 开源,更确切地讲是它的指令集规范和标准开源。
RISC-V指令集是基于精简指令集计算原理建立的开放指令集架构(ISA),RISC-V是在指令集不断发展和成熟的基础上建立的全新指令。RISC-V ISA可以免费使用,允许任何人设计、制造和销售 RISC-V 芯片和软件。

RISC-V(读音“risk-five”)是一个新的指令集体系结构(ISA),它最初用于支持计算机 体系结构研究和教学,但现在我们希望它也成为一个对于工业实现来说标准、免费、开放的 体系结构。RISC-V官方定义 RISC-V 的目的包括:
[*]一个完全开放的 ISA,能够自由地提供给学术界和工业界使用。
[*]一个真正的 ISA,能够适合直接在硬件上实现,而不仅仅是适用于模拟或者二进制 翻译。
[*]一个避免对某一种微体系结构风格(例如微编码、按序、去耦合、乱序等)或者实 现技术(例如全定制、ASIC、FPGA)“过度体系结构化(over-architecting)”的 ISA, 但是也能够非常高效地利用任何一种技术实现。

[*]包含一个小的基本整数 ISA(可以作为一个定制的加速器的基础或者作为教学用途) 和多个可选的标准扩展的 ISA,可以支持通用的软件开发。

支持修订的 2008 IEEE-754浮点标准。
[*]ISA 支持丰富的用户级 ISA 扩展和各种特殊的变种。
[*] 对应用程序、操作系统内核、硬件实现的32 位、64 位地址空间变种。
[*]ISA 支持高度并行的多核、众核实现,包括异构多处理器等。
[*]可选的变长指令,以支持扩展可用的指令编码空间、支持一个可选的密集指令编码, 以提高性能、静态代码大小和能耗效率。
[*]一个可完全虚拟化的 ISA,以简化虚拟机监督管理器(Hypervisor)的开发。
[*]ISA 支持新的管理员级(supervisor-level)和虚拟机监督管理级(hypervisor-level) ISA 设计。

3.关于RISC-V的V
RISC-V 这个名字,代表了 UC Berkeley 大学设计的第五代主要的 RISC ISA(前 四个是 RISC-I、RISC-II、SOAR和 SPUR)。罗马数字“V”也暗示 了“变种(Variations)”和“向量(Vectors)”,以支持各种体系结构研究,包括各种数据并行加速器,也是这个 ISA 设计的明确目标。

4、发明者为什么要开发一个新的ISA
关于为什么要有RISC-V,发明者这么说:
硬件上实现一些研究思想特别感兴趣(自从这个规范的第一个版本发布之后, 我们已经完成了 11 块不同的 RISC-V 硅片的制造),在课堂上提供给学生真实 的实现(在 Berkeley,RISC-V 处理器的 RTL 设计代码已经用于多个本科生、研 究生的课程)。在我们当前的研究中,由于传统晶体管不断变小带来的能耗约 束,我们对特殊、异构的加速器特别感兴趣。我们需要一个高度灵活、高度可 扩展的基本 ISA,在此基础上可以构建我们自己的研究。
我们总被问及这样一个问题“为什么要开发一个新的 ISA?”。使用一个已 有的商业化的 ISA,其显而易见最大的优势在于其已经具备了丰富和广泛支持。
的软件生态系统,包括开发工具和可移植的应用程序,而在研究和教学中,这 些都是可以利用的。其他的好处包括拥有大量的文档和教程示例。然而,我们 的经验证明,在科研和教学中使用商业的指令集,在实际中获得的好处很小, 而且掩盖不了它的缺点:
商业 ISA 都是私有的。
除了 SPARC V8(它是一个开放的IEEE 标准), 绝大多数 ISA 的拥有者非常小心地保护他们的知识产权,并且并不欢 迎自由实现的竞争实现。对于仅仅使用软件模拟器来进行学术研究和 教学来说,这并不是一个问题,但是对于那些希望分享真实硬件实现 的科研小组来说,这就是一个大问题。对于那些被强迫信任仅有的几 个商业 ISA 实现,而不允许创建自己的全新实现(clean room implementation)的企业来说,这也是一个大问题。我们并不能确保 所有的 RISC-V 实现没有侵犯第三方专利,但是我们确保我们绝不会 起诉一个 RISC-V 的实现者。
(1)商业 ISA 仅仅在某个市场领域比较流行。当书写此文档时,最显而易 见的例子就是 ARM 体系结构在服务器领域并没有得到很好的支持, 而 Intel x86 体系结构(或者几乎任何一种其他的体系结构)在移动领 域并没有得到很好的支持,虽然 Intel 和 ARM 正在试图进入对方的市 场领域。另外一个例子是 ARC 和 Tensilica,它们提供了可扩展的内核, 但是只关注嵌入式市场。这种市场的划分,使得支持某种特定商业 ISA 获得的好处大大削弱,因为事实上软件生态系统只存在于某个领 域,到了别的领域,必须重新构建。

(2)商业 ISA 此起彼伏。以前基于商业 ISA 构建的研究基础设施,并不流 行(SPARC、MIPS),甚至不再生产(Alpha)。这对于一个活跃的软件 生态系统来说是一个大损失,一些围绕 ISA 和支持工具的知识产权问 题,也使得感兴趣的第三方难以继续支持这个 ISA。一个开放的 ISA 也可能失去流行性,但是任何感兴趣的人,都可以继续使用它并研发 相应的生态系统。
(3)流行的商业 ISA 是复杂的。占统治地位的 ISA(x86 和 ARM)若要支 持常用软件栈和操作系统,那么其硬件实现都非常复杂。更糟糕的是, 几乎所有的复杂性都来自于糟糕的、或者至少是过时的ISA设计考虑, 而不是那些真正提高效率的特性。
(4)仅靠商业 ISA 并不足以运行应用程序。即使我们努力实现了一个商业 ISA,对于运行一个现有的应用程序来说,仍然是不够的。绝大多数 应用程序需要一个完整的 ABI(application binary interface)才能运行, 而不仅仅是用户级 ISA。绝大多数 ABI 依赖于库(libraries),而库又 依赖于操作系统支持。为了运行一个已有的操作系统,需要实现管理 员级 ISA、OS 需要的设备接口。这些通常并没有很好的规范,而在实 现上比用户级 ISA 具有更大的复杂性。
(5)流行的商业 ISA 不是为可扩展性设计的。占统治地位的商业 ISA 并没 有为可扩展性而进行特殊的设计,结果就是,随着后续指令集不断地 增长,指令编码的复杂度大幅度增加。而类似 Tensilica(被 Cadence 公司收购)、ARC(被 Synopsys 公司收购)这样的公司,它们围绕 可扩展性构建了 ISA 和工具链(toolchain),但是它们瞄准的是嵌入 式应用而不是通用计算系统。
一个修改过的商业 ISA 实际上是一个新的 ISA。我们的一个主要目标 是支持体系结构研究,包括主要的 ISA 扩展。即使是很小的扩展,也 减弱了使用标准 ISA 而带来的好处,因为必须修改编译器,而应用程 序必须从源代码进行重新编译,以利用这些扩展。引入了新的体系结 构状态的大一些的扩展,也需要对操作系统进行修改。最终使得一个 修改的商业 ISA 变成一个新的 ISA,但是不得不肩负着所有基本 ISA 遗留下来的包袱。我们坚信 ISA 是整个计算系统中最重要的接口,没有理由把这么重要的接 口变成私有的。占统治地位的商业 ISA 都是基于超过 30 年历史的指令集。软 件开发者应当能够定位到一个开放标准的硬件目标机,商业处理器设计者应当 在实现质量上进行竞争。我们并不是第一个为了适合硬件实现而提出开放 ISA 设计的。我们也考虑 了其他现有的开放 ISA 设计,其中 OpenRISC 体系结构与我们的目标最为 接近。
我们由于几个技术原因,并不采用 OpenRISC ISA:
1、OpenRISC 有条件码(condition code)和分支延迟槽(branch delay slot), 这对于更高性能的实现来说,变得更为复杂。
2、OpenRISC 使用了 32 位定长指令编码和 16 位立即数,阻碍了更密集 的指令编码,并对后续 ISA 扩展限制了空间。
3、OpenRISC 并不支持 2008 修订的 IEEE-754 浮点标准。
在我们开始的时候,64 位 OpenRISC 设计并没有完成。从零开始,我们可以设计一个符合我们所有需求的 ISA,当然,这花了比 我们在开始时预期多得多的努力。现在我们在构建 RISC-V ISA 基础设施上投入 了大量的精力,包括文档、编译器工具链、操作系统移植、参考 ISA 模拟器、 FPGA 实现、高效的 ASIC 实现、体系结构测试套件、教学材料等。自本文档的 上一个版本以来,在学术界和工业界对此 RISC-V ISA 都有大量的吸收(uptake), 我们也创建了非盈利的 RISC-V 基金会来保护和推进这个标准。RISC-V 基金会的 网址在 http://riscv.org,包含了基金会成员最新的信息和各种各样使用 RISC-V 的开源项目。

5.RISC-V指令集的优势
(1)完全开源。
对于 RISC-V 指令集的使用,RISC-V基金会不收取高额的授权费。开源采用宽松的BSD 协议,企业可以完全自由免费使用,同时也允许企业添加自有指令集,而不必开放共享,实现差异化发展。
(2)架构简单。
RISC-V设。处理器领域,流的架构为x8与ARM架构。x86与ARM架构的发展过程也伴随了现代处理器架构技术的不断发展成熟,但作为商用的架构,为了能够保持架构的向后兼容性,不得不保留许多过时的定义,导致其指令数目多,指令冗余严重,文档数量庞大,所以要在这些架构上开发新的操作系统或者直接开发应用门槛很高。而RISC-V 架构则完全抛弃包袱,借助计算机体系结构经过多年的发展已经成为比较成熟的技术的优势,从轻上路。RISC-V基础指令集只有40多条,加上其他的模块化扩展指令总共也就几十条指令。RISC-V的规范文档仅有145页,而特权架构文档的篇幅也仅为 91页。
(3)易于移植操作系统。
现代操作系统都做了特权级指令和用户级指令的分离,特权指今只能由操作系统调用,而用户级指令才能在用户模式调用,保障操作系统的稳定。RISC-V提供了特权级指令和用户级指令,同时提供了详细的 RISC-V 特权级指令规范和 RISC-V 用户级指令规范的详细信息,使开发者能非常方便地移植 Linux 和 UNIX 系统到RISC-V平台上。
(4)模块化设计。
RISC-V 架构不仅短小精悍,其不同的部分还能以模块化的方式组纱在一起,从而试图通过一套统一的架构满足各种不同的应用场景。用户能够灵活选择不同的模块组合,来实现自己定制化设备的需要,比如针对小面积低功耗嵌入式场景,用户可以选择RV32IC 组合的指令集,仅使用Machine Mode(机器模式);而高性能应用操作系统场景则可以选择RV32IMFDC 指令集,使用 Machine Mode(机器模式)与User Mode()户模式)两种模式。
(5)完整的工具链。
对于设计CPU 来说,工具链是软件开发人员和 CPU 交互的窗口,若没有工具链,则对软件开发人员开发软件要求很高,甚至软件开发者无法让CPU 工作起来在CPU 设计中,工具链的开发是一个巨大的工作。如果用RISC-V来设计芯片,芯片设计公司则不用再担心工具链问题,只需专注于芯片设计,RISC-V社区已经提供了完整的工具链 RISC-V 基金会持续维护该工具链。当前RISC-V的支持已经合并到主要的工具中,比如编评工具链 GCC、仿真工具 QEMU 等。

6、RISC-V的特点
1)没有立即数减法
只有立即数加法指令(addi),没有立即数减法指令(subi),那么减法怎么办?无论是数学上还是程序上,x-y都等价于x+(-y),也就是说可以把减法变成加法,把被减数转化成负数然后再加上减数就实现了和减法一样的功能。正是基于这个原理,RISC-V只提供立即数加法,没有提供立即数减法,如果需要立即数减法,那么就要麻烦编译器把这个立即数转化成负数,然后继续使用加法。这也是 RISC-V将立即数作为有符号数处理的原因。
2)x0 寄存器简化指令集
引入x0 寄存器后,很多特殊指令只需用普通的指令加上 x0 做操作数就能解决,指令的数量大大减少,处理器的解码电路也大大简化。
3)32 位常量
之前使用的ARM 处理器是将立即数表示不下的常量存到常量池,然后用PC相关的LDR指令加载到寄存器。RISC-V 的常量完全是用指令拼接,不需要 Load 指令,使用 Load 指令需要额外的访问周期。RISC-V 单条指令可以表示 12 位的有符号常量,超过 12 位需要两条指令来合成。其中一条指令是 lui,lui 指令加载常量的高 20 位,低 12 位可以用addi指令上去,这个过程需要编译器算出立即数到底是什么,因为 addi 指令执行的是有符号加法,其中的 12 位立即数会先被符号扩展成 32 位的有符号数再参与计算。ARM 的常量加载需要8个字节,一条指令加一个常量;RISC-V的常量加载也是需要8个字节,两条指令,两者占用的程序空间一样。
4)只有小于和大于等于
RISC-V 的比较跳转指令只有 blt 和 bge,即只有小于和大于等于。但大于和小于等于也是需要的,RISC-V用了一个很巧妙的办法用两条指令实现了四条指令的工作,将 blt 的两个参与比较的操作数位置换一下就有了 bgt(大于跳转),将bge 的两个参与比较的操作数位置换一下就有了 ble(小于或等于跳转)。
5)让编译器做更多工作
对 RISC 的理解是处理器尽量少做、编译器尽量多做,这是非常有道理的,毕竟编译的次数远少于执行的次数。上面几点就提到不少要让编译器多做的工作,又例如 B-type 是比较跳转指令的格式,J-type 是长跳转或函数调用指令格式,注意它们的立即数排列次序,把填充这里的立即数交给了链接器的工作。这样排放偏移地址立即数是为了简化处理器的设计,但明显给编译器增加了工作。
6)其他省掉的指令
很多常用的指令都被省掉了,比如nop、move、not、neg 等,但所有这些功能都还有只不过都是用其他的指令来等价实现,比如not 指令是用xorird,rs,-1实现。

7、RISC-V的x0寄存器
Linux 有两个特殊的设备:/dev/zero 和/dev/null。从/dev/zero 可以源源不断地读到0,往dev/null 写的任何内容都被丢弃。如果要创建一个需要填0的文件,就从dev/zero 拷贝,如果要丢弃一些输出,就把输出重定向到/dev/null。RISC-V的x0寄存器就相当于是硬件版的/dev/zero 和/dev/null的组合体。从0读出来的总是0,往x0 写进去的总是被丢弃。所以 x0 提供两种功能:一是提供常量0,在软件编程中0可以说是最常用的常量:二是提供一个可以丢弃结果的场所。有了 x0 寄存器,很多本来需要单独指令的操作只要在普通的指令前加上x0 就可以实现。
(1)nop 空指令,RISC-V没有提供nop 指令,而是用addi x0,x0,0来实现空指令,这条addi 使用x0作为目标存器,会丢弃结果,所以这条指令不会对程序状态产生任何影响,和空指令是完全等价的,这就不需要单独的空指令了。
(2)neg 取负数指令,RISC-V用 sub rd,x0,rs 来实现,x0-rs 等价于0-rs,等价于-rs,有了x0,就可以用更普通的减法指令来实现取负数指令。
(3)j跳转指令,RISC-V 没有单独的跳转指令,只有jal跳转链接指令,跳转之前总是要把下一条指令的地址拷贝到寄存器,但是如果用 x0 作为jal 的操作寄存器,即把下-条指令的地址拷贝到 x0,那么效果就等价于j跳转指令了,因为写入 x0 的任何值都会被丢弃。
(4)beqz等于零跳转指令等一系列和0比较的跳转指令,程序中和0比较是相当常见的操作,RISC-V 中和0比较的指令是普通的比较跳转指令,是用 x0 寄存器做指令的操作数。还有很多其他这样的指令,用普通的指令加上 x0 做操作数,就实现了那些没有x0 寄存器的处理器需要单独指令或者需要组合两条指令才能实现的操作。

参考资料:
1、risc-v.org
2、《基于risc-v的人工智能应用开发》
3、《深入理解RISC-V程序开发》
4、《计算机体系结构与SoC设计》
(内容来源:硬件十万个为什么)

页: [1]
查看完整版本: 一文了解RISC-V