【外评】如何改进 RISC-V 规范

我的主要项目是创建英特尔架构的可执行规范,但时不时地,我也会对 ISA 规范进行更广泛的审视,并思考其他 ISA 规范的优缺点:是什么让它们运行良好;它们可以从其他规范中借鉴哪些技术。本月早些时候,有人问我对 RISC-V 规范的看法,我认为分享我的发现会很有帮助。

这篇文章是关于 RISC-V 规范的。该规范实际上由几个不同的部分组成,每个部分都是定义 RISC-V 架构的重要部分。规范中最明显的部分是《RISC-V 指令集手册》第 1 卷《RISC-V 指令集手册》第 2 卷:这两份 PDF 文档描述了架构的非特权和特权部分。如果您正在开发 RISC-V 处理器,您可能会大量使用 RISC-V 测试套件来检查您的处理器是否正确实现了该架构。您可能会使用 Spike RISC-V ISA 模拟器作为 “黄金参考模型”,将处理器的行为与之进行比较。最后,你可能会使用 SAIL RISC-V 模型作为架构的正式规范。(不过,我认为这主要用于软件推理,而非硬件)。

[本帖已于 4 月 28 日修改,以澄清我关于 SAIL 规格的说法。]

这蓝图有什么问题?

总体而言,该规范并不健康。

这两份 PDF 文件在很大程度上依赖于规范中的自然语言文本,其结果是描述并不总是非常精确,而且无法测试这些描述以确定它们是否与其他人工制品相匹配。

关于测试套件的一个常见抱怨是,RISC-V 架构具有很高的可配置性,允许许多子集和实施选择,但测试套件却不容易配置,无法检查所有允许的行为。其中一些问题源于创建一个机器可读的说明来描述您打算构建的特定配置所面临的挑战。(这也限制了将 Spike 用作黄金参考模型的能力。)如果您打算构建 Spike 和测试套件所支持的配置范围之外的配置,您将最终获得大量的 “弃权”,这些 “弃权 “记录了您的处理器可能无法通过测试的地方。

最后,还有用 SAIL ISA 规范语言编写的 SAIL 模型。这是一个精确的、可执行的、正式的架构规范,但它并没有得到应有的使用。理想情况下,SAIL 规范的部分内容会包含在官方 PDF 文档中,这样 SAIL 代码就能增加自然语言规范所缺乏的精确性,而自然语言规范也能弥补 SAIL 规范中几乎完全没有注释的缺陷。

连接各个部分:机器可读格式

最重要的问题是,这四种工件似乎完全互不关联。它们作为四个独立的代码库分别保存在四个独立的资源库中,而且一个工件的任何部分都不是由其他工件的任何部分生成的。如果你要编写一个架构扩展,你必须用四种不同的格式把同样的东西编写四次,然后你必须使用测试和审查来检查所有四个副本是否相同。

但比这更糟糕的是,围绕 RISC-V 有一个完整的生态系统,他们也将根据你的架构扩展编写代码。硬件设计人员、硬件验证团队、软件工具(如汇编器、编译器和 JIT)开发人员、操作系统黑客和调试器开发人员等都必须编写一些代码,以支持或受益于任何架构扩展。他们还必须手工编写所有这些代码,然后审查和测试代码,使其与官方规范保持一致。

值得注意的是,大多数架构扩展都是在首次设计和最终批准的设计之间演变的:评估设计需要工具支持;设计的社会化和审查需要文档。因此,每个扩展通常都要实施很多次,每次修订都需要在很多地方进行更新。

要改进这一点,最简单的方法就是以易于阅读和操作的格式尽可能多地捕获架构。尤其是指令编码和控制/状态寄存器,很容易用简单的 JSON/YAML/XML/… 格式来描述。只需花很短的时间就能找出需要包含哪些数据,以支持从此类文件中生成多种不同的工件:

  • 名称和简短描述(用于生成文档)。
  • 大小、bitfields、fixed bits等。
  • 于寄存器,将有一个数字 id 用于标识寄存器。
  • 使用指令或寄存器有哪些限制?是否可在管理程序模式、监控程序模式、用户模式下使用?
  • 对于寄存器字段,该字段是否可读、是否可写、重置值是多少、该字段可能具有的不同值的含义是什么?
  • 对于指令,汇编语法是什么?(请参见双向 ARM 汇编语法规范
  • 哪些配置支持每个条目、字段或值?

我可能遗漏了一些重要信息,但你应该明白我的意思。

当然,创建这个易于使用、高度可重用的机器可读规范只是第一步。要想有所作为,就必须修改架构参考手册、Spike 模拟器、测试套件和 SAIL 规范,以便使用这些数据。您必须找到这些工件中目前包含指令或 CSR 信息的每一部分,并围绕 json/yaml/xml 文件自动生成的代码对其进行重构。这对于为任何新的架构扩展自动生成代码至关重要。

而且,在这样做的同时,人们还应该关注构建工具、库、操作系统等扩展生态系统,以便从机器可读数据文件中自动生成尽可能多的内容。

让非语言使用者更容易阅读 SAIL

我经常听到的关于 SAIL 规范的抱怨是,它对普通用户来说有点难以理解。SAIL 语言的设计建立在许多流行的学术语言和编程语言研究思想的基础之上,如 OCaml 函数编程语言、Liquid 类型、Monads 和 Effect Systems。借鉴这些不同来源的挑战在于,该规范的主要受众不是编程语言 (PL) 研究人员,而是从事硬件设计、硬件验证、操作系统开发、编译器开发等工作的人员–他们中的许多人并不熟悉学术编程语言文献,因此对 SAIL 的语法感到困惑和不适应。为了说明这一点,请看下面 SAIL 参考手册早期的 SAIL 示例:

val my_replicate_bits : forall 'n 'm, 'm >= 1 & 'n >= 1.  (int('n), bits('m)) -> bits('n * 'm)

如果您不熟悉 OCaml 和 liquid 类型,可能会问”‘m 和 ‘n 中的引号是什么意思?

从修改语法到应用合理的默认值来减少类型系统中的杂乱无章,我们可以在这方面做出一系列改进。(理想情况下,可以通过采用 ASL-1.0 ISA 规范语言的某些语法来实现这一点。)

与直觉相反的是,SAIL 的成功阻碍了这种情况的改善。如果进行彻底改变,人们可能会担心规范的含义发生了变化,而不仅仅是其外观。

将 SAIL 纳入文档

SAIL 规范的另一个问题更为根本,但也更容易解决:SAIL 规范并未包含在架构手册中。最简单的办法是将整个规范作为一个巨大的附录放在文档的后面。但更好的办法是将 SAIL 规范的每一部分与同一特性的自然语言描述放在同一页上,这样 SAIL 规范就能加深你对自然语言规范的理解,而自然语言规范也能帮助你理解 SAIL 规范。

令人沮丧的是,这实际上是一个已经解决的问题。从 LaTeX 中挑选出片段用于文档的工具早已存在,而且自 2019 年以来,已经有了带有指令语义适当交错的 unpriv 规范版本

在我看来,SAIL 更好的整合方式是将 SAIL 指令规范整合到 CHERI ISAv9 规范中(例如,参见第 176 页)。这减少了许多杂乱,看起来更像正常的 ISA 规范。

[注:随着 RISC-V 从 LaTeX 转为 ASCIIdoc,你可能想使用的工具是 SAIL-to-ASCIIdoc 工具。]

在工具中使用 SAIL

为什么我们的规范有两个可执行部分:SAIL 规范和 Spike 黄金参考模拟器?这其中的历史原因显而易见,但如果 Spike 能够从其 SAIL 规范中生成对未来扩展的支持,那就再好不过了。

这需要做一些工作。这主要包括定义从 SAIL 规范中生成的代码所使用的接口,以便访问 Spike 中表示的部分状态。

结论

RISC-V 架构是以典型的初创公司/学术风格开发的:快速创新,避免在长期工程方面投入过多资金。这就造成了目前的局面:架构规范实际上分散在四个不同的工件中,每个下游工具/库/应用程序都必须从这些来源转录信息,而不是使用架构师提供的机器可读格式来生成代码。

对于只有 47 条指令和 32 个寄存器的原始基本架构来说,这并不是一个大问题,但从那时起,RISC-V ISA 已经增加了许多扩展功能。

本文文字及图片出自 How to improve the RISC-V specification

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注