在RISC-V指令集手册,用户级ISA中,我无法理解第11节“立即编码变体”第11页。
有四种类型的指令格式R,I,S和U,然后有S和U类型的变体,它们是SB和UJ,我想这意味着分支和跳转,如图2.3所示。然后是RISC-V指令产生的Immediate类型,如图2.4所示。
所以我的问题是,为什么需要SB和UJ?为什么以这种方式洗掉立即位?说“由RISC-V指令产生的即时”是什么意思?它们是如何以这种方式生产的?
答案 0 :(得分:13)
为了加速解码,基础RISC-V ISA将最重要的字段放在每条指令的相同位置。正如您在指令格式表中看到的那样,
其他位用于次要操作码或指令的其他数据(位12-14中的funct3
和位25-31中的funct7
)和立即数。立即数可以使用多少位取决于指令中存在多少个寄存器编号:
ADD
); ADDI
)的寄存器; LUI
,可以使用20位作为立即数(主要操作码和目标寄存器号一起需要12位) 现在从另一个角度思考将使用这些直接值的指令。最简单的用户,I-immediate和S-immediate,只需要符号扩展的12位值。 U-immediate指令需要32位值的高20位中的立即数。最后,分支/跳转指令需要在值的低位中立即符号扩展,但最低位始终为零,因为RISC-V指令始终与偶数地址对齐。
但为什么直接位被洗牌?想想这次解码立即场的物理电路。由于它是硬件实现,所以比特将被并行解码;输出立即数中的每个位都有multiplexer来选择它来自哪个输入位。多路复用器越大,成本越高,速度越慢。
"洗牌"因此,指令编码中的立即位是使每个输出立即位具有尽可能少的输入指令位选项。例如,立即位1只能来自指令位8(S-immediate或B-immediate),21(I-immediate或J-immediate)或常数0(U-immediate或R-type指令,它们没有立即数) )。立即位0可以来自指令位7(S-immediate),20(I-immediate)或常数0。立即位5只能来自指令位25或常数零。等等。
指令位31是一种特殊情况:对于RV-64,立即数32-63位始终是指令位31的副本。这种高扇出会增加延迟,如果它还需要一个延迟,它会更大多路复用器,因此它只有一个选项(除了常数零,可以在管道中稍后通过忽略整个立即数来处理)。
值得注意的是,只需要主要操作码(位0-6)就可以知道如何解码立即数,因此立即解码可以与解码其余指令并行完成。 / p>
所以,回答问题:
答案 1 :(得分:4)
完成编码是为了尽可能简化实际的硬件实现,而不是让读者一眼就能理解。
实际上,编译器会生成输出,因此用户不容易理解它并不重要。
如果可能,SB类型尝试对与S类型相同的立即位位置使用相同的位,这样可以最大限度地降低硬件设计的复杂性。所以imm [4:1]和imm [10:5]在两者之间都处于相同的位置。立即值的最高位始终位于第31位,以便您可以使用该位来确定是否需要符号扩展。同样,这使得硬件更容易,因为对于多种类型的指令,最高位用于决定符号扩展。
答案 2 :(得分:1)
选择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倍。加扰的立即编码将增加可忽略不计进行静态或提前编译的时间。对于动态生成指令,有一些小的额外开销,但是最常见的短前分支具有直接的立即编码。