在 RISC-V 指令集手册,用户级 ISA 中,我无法理解第 11 页的第 2.3 节立即编码变体。
指令格式有 R、I、S 和 U 四种类型,然后是 S 和 U 类型的变体,它们是 SB 和 UJ,我想是指分支和跳转,如图 2.3 所示。然后是 RISC-V 指令产生的立即数类型,如图 2.4 所示。
所以我的问题是,为什么需要 SB 和 UJ?为什么要以这种方式洗牌立即位?说“RISC-V指令产生的立即数”是什么意思?它们是如何以这种方式生产的?
在 RISC-V 指令集手册,用户级 ISA 中,我无法理解第 11 页的第 2.3 节立即编码变体。
指令格式有 R、I、S 和 U 四种类型,然后是 S 和 U 类型的变体,它们是 SB 和 UJ,我想是指分支和跳转,如图 2.3 所示。然后是 RISC-V 指令产生的立即数类型,如图 2.4 所示。
所以我的问题是,为什么需要 SB 和 UJ?为什么要以这种方式洗牌立即位?说“RISC-V指令产生的立即数”是什么意思?它们是如何以这种方式生产的?
为了加快解码速度,基本 RISC-V ISA 将最重要的字段放在每条指令的相同位置。正如您在指令格式表中看到的,
其他位用于指令的次要操作码或其他数据(funct3
在位 12-14 和funct7
位 25-31 中)和立即数。立即数可以使用多少位取决于指令中存在多少寄存器号:
ADD
);ADDI
);LUI
可以使用 20 位立即数(主要操作码和目标寄存器号共需要 12 位)。现在从另一个角度考虑将使用这些立即值的指令。最简单的用户,I-immediate 和 S-immediate,只需要一个符号扩展的 12 位值。U 立即数指令需要 32 位值的高 20 位立即数。最后,分支/跳转指令需要值的低位中的符号扩展立即数,除了始终为零的最低位,因为 RISC-V 指令始终与偶数地址对齐。
但是为什么直接位被打乱了?这次想想解码立即场的物理电路。由于它是硬件实现,因此这些位将被并行解码;输出立即数中的每个位都有一个多路复用器来选择它来自哪个输入位。多路复用器越大,成本越高,速度越慢。
因此,指令编码中立即位的“混洗”是为了使每个输出立即位具有尽可能少的输入指令位选项。例如,立即数位 1 只能来自指令位 8(S-立即数或 B-立即数)、21(I-立即数或 J-立即数)或常量 0(没有立即数的 U-立即数或 R-类型指令) )。立即数位 0 可以来自指令位 7(S-立即数)、20(I-立即数)或常数零。立即位 5 只能来自指令位 25 或常数零。等等。
指令位 31 是一种特殊情况:对于 RV-64,立即数的位 32-63 始终是指令位 31 的副本。这种高扇出会增加延迟,如果还需要多路复用器,延迟会更大,所以它只有一个选项(除了常量零,稍后可以通过忽略整个立即数在管道中对其进行处理)。
值得注意的是,只需要主要操作码(0-6 位)就知道如何解码立即数,因此立即数解码可以与解码其余指令并行进行。
所以,回答问题:
编码是为了尽量让实际的硬件实现尽可能简单,而不是让读者一眼就能理解。
在实践中,编译器将生成输出,因此用户是否难以理解并不重要。
在可能的情况下,SB 类型尝试将相同的位用于与 S 类型相同的立即位位置,从而最大限度地降低硬件设计的复杂性。所以 imm[4:1] 和 imm[10:5] 都在同一个地方。立即数的最高位始终位于位置 31,因此您可以使用该位来决定是否需要符号扩展。同样,这使硬件更容易,因为对于多种类型的指令,最高位用于决定符号扩展。
选择RISC-V指令编码简化解码器
2.2 基本指令格式
RISC-V ISA 在所有格式中都将源(rs1 和 rs2)和目标(rd)寄存器保持在同一位置,以简化解码。除了 CSR 指令中使用的 5 位立即数(第 9 章)外,立即数始终是符号扩展的,并且通常被打包到指令中最左边的可用位,并且已被分配以降低硬件复杂性。特别是,所有立即数的符号位始终位于指令的第 31 位,以加速符号扩展电路。
2.3 立即编码变体
S 和 B 格式之间的唯一区别是 12 位立即数字段用于在 B 格式中以 2 的倍数对分支偏移进行编码。不是像传统那样在硬件中将指令编码立即数中的所有位左移一位,中间位 (imm[10:1]) 和符号位保持在固定位置,而 S 格式的最低位 (inst[ 7]) 以 B 格式对高位比特进行编码。
类似地,U 和 J 格式之间的唯一区别是 20 位立即数左移 12 位形成 U 立即数,并左移 1 位形成 J 立即数。选择 U 和 J 格式立即数中指令位的位置以最大限度地与其他格式和彼此重叠。
RISC-V 规范中也解释了 SB/UL 格式中立即数改组的原因
尽管更复杂的实现可能具有用于分支和跳转计算的单独加法器,因此不会受益于跨指令类型保持立即位的位置不变,但我们希望降低最简单实现的硬件成本。通过旋转 B 和 J 立即数的指令编码中的位,而不是使用动态硬件多路复用器将立即数乘以 2,我们将指令信号扇出和立即多路复用器成本降低了大约 2 倍。加扰的立即数编码将添加可以忽略不计timeto 静态或提前编译。对于指令的动态生成,有一些小的额外开销,但最常见的短前向分支具有直接的立即编码。