RISC-V:即时编码变体

Amm*_*urd 12 cpu-architecture riscv

在RISC-V指令集手册,用户级ISA中,我无法理解第11节"立即编码变体"第11页.

有四种类型的指令的格式R,I,S和U,再有是S和U类型的是SB和UJ我想平均分支和跳转如图2.3的变体.然后是RISC-V指令产生的Immediate类型,如图2.4所示.

所以我的问题是,为什么需要SB和UJ?为什么以这种方式改变立即位?说"RISC-V指令产生的即时"是什么意思?它们是如何以这种方式生产的?

在此输入图像描述

在此输入图像描述

Ces*_*arB 15

为了加速解码,基础RISC-V ISA将最重要的字段放在每个指令的相同位置.正如您在指令格式表中看到的那样,

  • 主要操作码始终位于0-6位.
  • 目标寄存器(如果存在)始终位于第7-11位.
  • 第一个源寄存器(如果存在)始终位于第15-19位.
  • 第二个源寄存器(如果存在)始终位于20-24位.

其他位用于次要操作码或指令的其他数据(funct3位12-14和funct7位25-31),以及立即数.立即数可以使用多少位取决于指令中存在多少个寄存器号:

  • 具有一个目的地和两个源寄存器(R型)的指令没有立即,例如添加两个寄存器(ADD);
  • 具有一个目的地和一个源寄存器(I型)的指令具有12位用于立即数,例如添加一个具有immediate(ADDI)的寄存器;
  • 具有两个源寄存器和没有目标寄存器(S类型)的指令(例如存储指令)也有12位用于立即数,但它们必须位于不同的位置,因为寄存器号也在不同的位置;
  • 最后,仅具有目标寄存器且没有次要操作码(U型)的指令LUI可以立即使用20位(主要操作码和目标寄存器号一起需要12位).

现在从另一个角度思考将使用这些直接值的指令.最简单的用户,I-immediate和S-immediate,只需要符号扩展的12位值.U-immediate指令需要32位值的高20位中的立即数.最后,分支/跳转指令需要在值的低位中立即符号扩展,除了最低位始终为零,因为RISC-V指令始终与偶数地址对齐.

但是,为什么立即洗牌?想想这次解码立即场的物理电路.由于它是硬件实现,所以比特将被并行解码; 输出立即数中的每个位都有一个多路复用器来选择它来自哪个输入位.多路复用器越大,成本越高,速度越慢.

因此,指令编码中的立即位的"混洗"是使每个输出立即位具有尽可能少的输入指令位选项.例如,立即位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)就可以知道如何解码立即数,因此立即解码可以与解码其余指令并行完成.


所以,回答问题:

  • SB类型使分支范围加倍,因为指令始终与偶数地址对齐;
  • UJ类型具有与U类型相同的整体指令格式,但是立即值是低位而不是高位;
  • 通过减少每个输出立即位的选择数量,立即比特被混洗以降低解码立即值的成本;
  • "由RISC-V指令立即生成"表显示了可以从RISC-V指令解码的不同类型的立即值,以及每个位来自指令的位置;
  • 它们由每个输出立即位产生,使用主要操作码(位0-6)来选择输入指令位.

  • @akurd带有带符号的12位数字,范围从-2048到+2047.在B-immediate(SB型)中,您有一个带符号的13位数字,最低位设置为零,范围从-4096到+4094.至于为什么分支/跳转指令需要低位的立即数,如果它们没有,则它们不能转到它们附近的指令. (2认同)

Phi*_*ght 5

进行编码是为了尝试使实际的硬件实现尽可能简单,而不是让读者一目了然。

在实践中,编译器会生成输出,因此用户是否容易理解并不重要。

在可能的情况下,SB 类型尝试对与类型 S 相同的立即位位置使用相同的位,从而最大限度地降低硬件设计的复杂性。所以 imm[4:1] 和 imm[10:5] 两者都在同一个地方。立即数的最高位始终位于位置 31,以便您可以使用该位来决定是否需要符号扩展。同样,这使硬件更容易,因为对于多种类型的指令,最高位用于决定符号扩展。