【问题标题】:Why are RISC-V S-B and U-J instruction types encoded in this way?为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?
【发布时间】:2020-02-13 07:42:25
【问题描述】:

我正在阅读一本书《计算机组织与设计 RISC-V 版》,我遇到了 S-B 和 U-J 指令类型的编码。

我上面提到的那些类型有奇怪的编码立即字段。

S-B 类型将直接字段分为两部分。这是有道理的,因为所有指令编码都必须相似。但是我不明白为什么下面的立即字段以这种方式编码。

imm[12, 10:5], imm[4:1, 11]

而不是

imm[11:5], imm[4:0]

U-J 类型也有这个奇怪的编码立即字段

imm[20,10:1,11,19:12]

而不是

imm[19:0]

谁能解释一下?

【问题讨论】:

    标签: assembly encoding riscv machine-code instruction-set


    【解决方案1】:

    所选编码与其他编码非常吻合,简化了硬件,但牺牲了必须生成指令的软件、必须解码指令的软件以及学习或使用 RISC V 的程序员;)。

    S 格式将立即数分解为 imm[11:5]imm[4:0]。这个立即数被分解的原因是为了保持其他字段,即寄存器字段rs2rs1,与 R-Type 指令中的两个源寄存器字段的位置相同。 (与 MIPS 相比,MIPS 类似但不完全,这消除了寄存器名称宽度(例如 5 位宽)多路复用器和几个额外的布线,以及控制信号。)

    S 格式允许 12 位立即数。

    虽然 (S)B 类型的分支使用 13 位立即数,但 13 位立即数的最后一个(最低有效位)始终为零因此它不会被存储!因此,它实际上需要像 S-Format 一样对 12 位进行编码,但是因为它们在实际使用中被移位(左移一位,例如 *2),所以与 S-Format 相比,所有位基本上都偏移了 1 位。立即格式化。 (移位并不困难或缓慢,但会占用硅空间。通常,这种恒定量的移位可以通过简单地将输入位连接到偏移输出位位置来完成,而不是使用我们在 ALU 中看到的专用移位器;但是,这仍然是直接和数据路径大小的布线,因此大约需要 12 到 32+ 条额外的布线。)

    为了不必(尽可能多地移动)立即存储的部分,以便与 S 格式的立即数很好地对齐,未存储的LSB 位置(来自 S-Format)用于存储 SB-Format 立即数的第 11 位。这样,位 10:1 与 S-Format 立即数完全对齐。

    但是为什么不直接将分支的第 12 位放在那里,这样可以使另一位与 S 格式保持一致(即 11:1)?因为在指令的立即数中编码的最高位用于将立即数符号扩展为 32 位(对于 RV32,或者对于 RV64 是 64 位,对于 RV128 是 128,很多线!)。因此,通过将符号位保持在与 S 格式 12 位立即数相同的位置,可以共享相同的符号扩展硬件(具有相同的上述优缺点;-)。因此,选择将第 11 位(SB-Type 立即数的下一个最高有效位)存储在 0 位位置(相对于 S-Format)。

    SB(已经给定 S)的成本只有两条左右(1 位)线和一个 1 位多路复用器和一个 1 位控制信号 - 与其他替代方案相比是最低的。

    请参阅以下presentation,幻灯片 46,标题为“RISC-V 立即编码”,副标题为:“为什么这么混乱?!?!”

    UJ-Type 的做法类似,将符号位保持在与其他指令的符号位相同的位位置,同时尽可能多地与其他格式对齐其他位。

    请参阅同一演示文稿的幻灯片 60。

    【讨论】:

      【解决方案2】:

      official RISC-V spec 在解释指令集中每一个的设计选择方面做了出色的工作,解释了为什么以这种特定方式完成某事。如有疑问,您只需要看看它

      因此,指令编码的基本原理在第 2.2 章 - 基本指令格式中进行了描述。这一切都是为了让指令解码更简单更快

      • 在不同指令格式之间共享解码单元
      • 将立即位放在特定位置以消除对硬件移位器的需求并在解码时减少fan-out

      RISC-V ISA 在所有格式中将源(rs1rs2)和目标(rd)寄存器保持在同一位置,以简化解码。除了 CSR 指令(第 9 章)中使用的 5 位立即数外,立即数总是符号扩展的,并且通常被打包到指令中最左边的可用位,并已被分配以降低硬件复杂性。特别是,所有立即数的符号位始终位于指令的第 31 位,以加速符号扩展电路。


      解码寄存器说明符通常在实现中的关键路径上,因此选择指令格式以使所有寄存器说明符在所有格式中保持在相同位置,代价是必须跨格式移动立即位(a与 RISC-IV 又名共享的属性。SPUR [11])。

      查看指令编码,您会发现 rs1rs2rd 在任何需要它们的指令格式中都只需要一个解码器,并且位 31 始终是符号位立即数,无论其长度如何,用于快速符号扩展

      现在关注立即数,您还会看到它们以“奇怪”的顺序排列,但它们也允许解码器在格式之间共享。例如,位 10:1 在所有格式中始终位于同一位置。与 U/J 中的 19:12 位和 S/B 中的 4:1 位相同。这 2 对实际上几乎相同,立即数在 J 和 B 中左移一位。通过这种方式交错位,移位的大部分繁重工作都留给了汇编程序,进一步简化了硬件

      2.3 立即编码变体

      S 和 B 格式之间的唯一区别是 12 位立即数字段用于在 B 格式中以 2 的倍数对分支偏移进行编码。不是像传统那样在硬件中将指令编码立即数中的所有位左移一位,中间位 (imm[10:1]) 和符号位保持在固定位置,而 S 格式的最低位 (inst[ 7]) 以B格式编码一个高位。

      同样,U 和 J 格式之间的唯一区别是 20 位立即数左移 12 位形成 U 立即数,并左移 1 位形成 J 立即数。选择 U 和 J 格式立即数中指令位的位置以最大限度地与其他格式和彼此重叠。


      符号扩展是立即数上最关键的操作之一(尤其是对于 XLEN>32),在 RISC-V 中,所有立即数的符号位始终保存在指令的第 31 位,以允许符号-扩展以与指令解码并行进行。

      虽然更复杂的实现可能有单独的分支和跳转加法器 计算,因此不会受益于在不同类型的指令中保持立即位的位置不变,我们希望降低最简单实现的硬件成本。通过旋转 B 和 J 立即数的指令编码中的位,而不是使用动态硬件多路复用器将立即数乘以 2,我们将指令信号扇出和立即多路复用器成本减少了大约 2 倍。加扰的立即数编码将增加可忽略不计的时间静态或提前编译。对于指令的动态生成,有一些额外的开销,但最常见的短前向分支具有直接的立即编码。

      如果您有兴趣,可以在official github page 中找到更多讨论

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2019-08-22
        • 2022-08-17
        • 1970-01-01
        • 2018-11-22
        • 2023-03-22
        • 2014-12-10
        • 1970-01-01
        • 2018-07-22
        相关资源
        最近更新 更多