如何使用RISC-V创建自定义处理器

描述

RISC-V(风险五)基金会将开源自由与标准化的好处融合在一起,引起了业界的广泛关注。它的内核规格稳定且一经批准就可以使用,软,硬CPU内核以及芯片,开发板和工具已在市场上出售,并且主要公司已开始采用RISC-V来替代其自定义体系结构。该体系结构吸引人的一个关键特征是,CPU开发人员可以在不牺牲为基本标准创建的工具和库的适用性的情况下,使RISC-V功能适应其需求。适应的关键在于了解RISC-V的模块化指令集体系结构。

RISC-V最初是UC Berkeley的简化指令集计算(RISC)设计工作的第五次迭代,但随后迅速地从学术研究演变成旨在重新定义电子行业处理硬件设计方法的运动。当前,系统开发人员必须选择通常针对特定应用程序空间进行了优化的专有CPU架构,或者设计自己的CPU架构。但是,通过追求自己的设计,开发人员放弃了已建立的CPU开发的广泛支持生态系统。有一个折衷方案:采用专有的CPU架构来获得自定义功能,同时保留许多支持生态系统。不幸的是,由于专有架构的高昂架构许可费用,这种折衷对于许多设计团队而言是不切实际的。

RISC-V计划试图为设计人员提供一种替代方案,该方案允许定制和创新,同时保留许多标准化的好处。为此,RISC-V Foundation维护并推动了模块化,开源RISC-V处理器指令集体系结构(ISA)的社区发展,该体系结构旨在满足从嵌入式系统到服务器场以及其他应用的需求。该体系结构的规范可以免费下载,开发人员可以自由地基于ISA实施设计,而无需支付许可费用。他们也没有义务像其他开源计划一样将其设计提供给其他人。ISA是开源的。如果开发人员愿意,则各个设计,硬件体系结构和自定义项可以保持专有。

该倡议取得了可观的势头。现在有商业和开放源代码的RISC-V芯片和内核可用。公司如SiFive,GreenWaves技术,以及Microsemi的对他们的RISC-V实现开发板。开发工具,软件库和操作系统端口(包括Linux)都是当前RISC-V支持生态系统的一部分。不过,要充分利用对定制设计的所有支持,首先要仔细研究RISC-V ISA的结构。

基本规格

定义RISC-V ISA的两个关键文档是:用户级ISA规范和特权ISA规范。在这些定义中,既定义了基本需求,又定义了许多标准化的模块化扩展。标准扩展是模块化的,因为在CPU设计中实现任何给定的标准扩展都不会干扰任何其他标准扩展的实现。一些扩展可以在其他扩展的基础上构建,但是,要求将基本扩展实现为所需扩展的一部分。

总体设计基于寄存器,需要进行所有操作的31个通用寄存器,并具有对通用存储空间的加载和存储访问。已经为32位,64位和128位地址空间定义了指令集,并定义了额外的减少寄存器计数的32位指令集,专门针对嵌入式系统设计的较小门数实现。除了存在用于操纵更长的字长以及与地址空间匹配的寄存器大小的附加指令外,这些变体的指令编码都是相同的。

图1以示意图形式显示了核心规范和标准扩展如何相互作用。RISC-V基金会现在冻结了许多规范,以确保基于这些规范的实施将随着ISA的发展而保持有效。这确保了今天编写的软件将永远在类似的RISC-V内核上运行。某些扩展名仍处于草稿模式,因此可能会发生变化。保留了一些,即等待未来发展的占位符。例如,冻结了32位和64位基本整数ISA,而128位和嵌入式变体仍处于草稿形式。

基本整数ISA(I)是构建所有其他整数的基础,并且在任何实现中都必须存在。除基本整数ISA之外,所有标准RISC-V实现都必须至少包括Privileged ISA的计算机级别部分;否则,不执行任何操作。主管级别(S)和管理程序部分是标准扩展。但是,特权ISA的定义方式是,开发人员可以根据需要实现特权代码执行的自定义形式,而又不影响基本整数ISA。

RISC-V

 

图1 RISC-V ISA构成了指令的模块化集合,这些指令可以在CPU设计中实现而不会互相干扰。

通过标准扩展增强基本功能

基本整数(I)和计算机级特权ISA提供了基本的通用CPU所需的所有功能。但是,开发人员可以通过向ISA添加扩展来增强此基本功能。自定义扩展总是可能的,但是RISC-V Foundation中的技术任务组管理着标准扩展,确定它们对设计界具有广泛的吸引力,并且其说明与其他标准扩展不冲突。因此,开发人员可以在设计中自由地包含他们所需的任何标准扩展,而无需担心指令编码中的冲突。这些标准扩展包括:

  • M –将两个整数寄存器中保存的值相乘和除的指令(冻结)
  • A –原子读写修改内存以支持同步(冻结)的指令
  • F,D和Q –符合IEEE 754-2008算术标准的(F)单精度,(D)双精度和(Q)四精度浮点计算的说明。每个精度的扩展名取决于存在的较低精度的扩展名。(冻结)
  • G –包含基本整数规范(I)以及M,A,F和D标准扩展名的实现如此流行,以至于基金会将集合定义为G,并将G配置设置为编译器的标准目标。开发中的工具链。(冻结)
  • V –向浮点扩展添加矢量指令的指令(草稿)
  • L –十进制浮点计算说明(保留)
  • B –比特级操作说明(保留)
  • N –处理用户级中断的指令(草稿)
  • P –支持打包的单指令,多数据指令的扩展(保留)
  • T –支持事务性内存操作的指令(保留)
  • J –支持使用动态翻译语言的扩展(保留)
  • C –支持压缩指令执行。基本整数(I)规范要求指令字长32位,并在内存中的32位边界上对齐。实施C标准扩展提供了常见操作的16位编码,并允许CPU设计在自由混合的32位和16位边界上进行对齐,从而将代码大小减少了25%到30%。可以用任何基本整数位宽度以及任何其他标准扩展来实现。(冻结)
  • S –特权ISA的管理员级别扩展(草稿)

像用户级ISA一样,特权ISA使设计人员能够选择要包含的复杂程度。该规范定义了两个ISA集:机器级别和管理员级别,以及保留占位符以获取支持虚拟机管理程序功能的指令。反过来,这些指令集允许开发人员最多支持三个特权级别,代码可以在这些特权级别上运行。单一特权级别(机器级别)意味着所有正在运行的代码都具有对系统资源的完全访问权限,例如在简单的嵌入式系统中运行的单个应用程序。具有两个特权级别,同时需要计算机和主管ISA指令,它们支持将某些系统资源与应用程序代码隔离,以增强软件安全性并允许操作系统访问多个并发应用程序。

RISC-V

图2这两个特权ISA级别可以一起支持许多软件配置,包括一个简单的应用程序执行环境(AEE),一个具有管理者执行环境(SEE)的操作系统上的多个应用程序以及一个具有管理程序的操作系统。(来源:RISC-V基金会)

通过标准扩展和特权级别的所有可能组合,简单的名称“ RISC-V”不足以表示ISA的实际硬件实现。为了阐明程序员在采用给定的硬件实现时可以访问哪些指令,基金会设计了一种核心命名术语。名称包括三个部分:使用的基本规范(RV32I,RV64I等),添加的标准扩展名(M,F,A等)以及每个元素的版本号(1.2版等为1p2)。 ,如图3所示。在许多情况下,为简单起见,可以省略版本号(RV32IC,RV64G等)。

RISC-V

 

图3 RISC-V实现的名称编码了对其支持的指令集的完整描述。

命名约定也允许标识自定义的扩展名。基本整数ISA的扩展使用开发人员选择的名称,并具有X name形式,并带有适当的版本号。如果扩展名涉及特权ISA的管理员级别,则该表单为SX名称。

超越标准扩展

即使具有模块化标准扩展提供的设计灵活性,RISC-V标准也无法提供开发人员可能期望的许多指令增强功能。例如,考虑一个经常需要对两个16位整数进行四舍五入取平均值((r1 + r2)/ 2)的应用,例如两次ADC测量。使用基本整数ISA,所需的平均计算将需要执行两条指令:整数加法和算术右移(有效执行整数除以2,向下舍入)。因此,在一个步骤中执行两项操作的自定义指令可以加快应用程序的软件执行速度。如果您采用ISA的标准指令格式,则RISC-V ISA可以轻松地添加此类指令。

RV32I基本指令集遵循四种基本格式,如图4所示。R型指令从两个源寄存器(rs1和rs2)获取值,并以某种方式(加,异或等)将它们组合以形成一个值,该值将存储在目标寄存器(rd)的第三个寄存器中。I型指令将源值(rs1)和在指令本身中编码的12位值(imm)合并并存储在目标寄存器(rd)。加载指令使用I型格式,结合源值和立即值来确定存储器地址,并将其内容传输到目标寄存器。S型指令从一个源寄存器获取值,以将第二个寄存器的内容和立即值(组合在一起时)所指向的地址存储在内存中。S型指令的B型变体具有相同的格式,但是使用这两个值来计算条件分支指令的地址。U型指令允许使用大于12位的立即数,而J型变量则使用立即数执行无条件跳转。

RISC-V

图4 RISC-V指令的四种基本格式。(来源:RISC-V基金会)

这些指令格式的定义提供了一些有关开发人员如何轻松地将自定义指令添加到组合中的线索。所有指令的低位都包含一个7位操作码,除U型格式外,所有指令的第12位至第14位都具有功能代码(funct3)。R型指令具有第二个功能代码(funct7)。)在第25到31位。当涉及目标寄存器地址时,它总是在第7到11位,第一个源寄存器的地址总是在第15到19位,另一个源寄存器在第20到24位。这种一致性代码和寄存器指针的位置意味着如果您可以将新指令映射到这些基本格式之一,并且您具有符合要求的RISC-V设计,则用于实现该指令的硬件设计几乎已经完成。大部分新操作(例如指令解码和寄存器数据访问)都在现有设计中,您可以使用它。

为了说明平均示例,请考虑图5中的流程图。现有的用于整数的RV32I ADD和SUB指令遵循R型格式,并且具有完全相同的操作码(0110011)和funct3(000)代码值,仅在它们的funct7代码上有所不同(0000000与0100000)。没有其他RV32I指令使用该操作码和funct3组合,从而留下了120多个可能的funct7可用于对新指令进行编码的值,而无需遵循任何标准指令。这些标准指令的可能实现方式是显示来自两个源寄存器的值进入算术单元,该算术单元(取决于位指令30)将这些值相加或相减,然后将结果传递给目标寄存器。

RISC-V

 

图5对标准RISV-V实现的修改,以添加两个新指令

添加新的平均指令只需要对该硬件进行最少的更改。例如,可以通过从指令解码逻辑中提取指令位25并使用它来命令在算术单元之后插入的一组新的多路复用器来完成此操作。该位使多路复用器将原本标准的ADD或SUB结果右移一位,然后再将其传送到目标寄存器。现在,该设计将实现ADD和SUB以及两个新指令:平均值[[ rs1 + rs2 / 2]和平均差[[ rs1 - rs2 / 2] / 2],仅需少量额外的门。这种自定义扩展可围绕现有的指令编码工作,称为“棕场扩展”。

指令扩展的机会比比皆是

RISC-V为棕地扩展提供了许多机会。RV32I基本ISA通过利用3位funct3和7位funct7值定义主要指令类型的次要变化,仅使用可用的128个(7位)主要操作码中的11个来定义其47条不同的指令。大多数标准扩展和更长的基整数变体(RV64I,RV128I)仅需要几个附加的主要操作码。这为编码新的Brownfield扩展指令留出了足够的空间。只有压缩指令(C)标准扩展才添加了大量独特的指令代码,以说明其指令长度的许多变体。但是,这也已经以最小化操作码需求的方式实现。

下图(图6)显示了在具有G标准扩展名的32位,64位和128位宽基本整数实现中可用的未定义主要操作码,它们被认为是开发人员可用来构建的最常见配置。基金会将避免在将来的任何标准扩展中使用其中一些,以帮助确保开发人员其设计将与此类扩展兼容。其他保留给将来的标准扩展使用以及预期的128位基本整数标准使用,但对于不关心避免将来可能出现的不兼容问题的开发人员来说,它们是可用的。

RISC-V

 

图6可用的RISC-V主要操作码图

对于希望在不考虑所有标准扩展的情况下为基本整数(I)规范创建自定义扩展的开发人员来说,机会甚至更多。例如,RISC-V ISA定义了其所有基本整数(I)和大多数标准扩展指令,其编码的两个最低有效位(LSB)设置为x11。仅压缩(C)标准扩展名定义了将这些位设置为x00,x01或x10的指令。然后,不需要C标准扩展的开发人员可以随意使用其所需的LSB位模式来定义指令。这为它们提供了三个30位指令编码空间,可在其中进行播放而不会损害基本整数ISA或任何其他标准扩展。

RISC-V计划的主要目标是允许创新和定制,而不会造成正在成长的生态系统的过度分散。在扩展基本体系结构时遵守ISA准则和要求的开发人员可以帮助确保达到目标。

Rich Quinnell是AspenCore网络的工程师,作家和全球执行编辑。

编辑:hfy

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分