RISC-V
オープンなISA(命令セットアーキテクチャ)。固定長32bit命令を基本とするRISC設計で、学習・研究・商用まで幅広く使われる。現在VerilogでRV32Iを実装中。
32bit即値の生成
RV32Iは命令が32bit固定長のため、1命令で任意の32bit即値をレジスタにロードできない。即値フィールドはU型で最大20bit、I/S/B型では12bitに制限されている。
任意の32bit値を作るには lui(上位20bit)と addi(下位12bit)の2命令を組み合わせる。アセンブラ疑似命令 li はこれに自動展開される。
x86は可変長命令のため即値をそのまま後置できるが、RISC系(MIPS・ARMも同様)では「2命令合成」かリテラルプールからの lw が定石。
B形式の即値ビット配置
B形式(分岐命令)の12bit即値は命令ワード内でビットが分散している。意図的な設計で、主な理由は2つ。
- 符号ビットをbit31に統一: I/S/B/J/U全フォーマットで符号ビットがbit31にある。デコーダがオペコードを見る前に符号拡張の準備ができる。
- S形式との回路共有: ストアのオフセット(S形式)と分岐オフセット(B形式)はビット配置を共通化し、同じ加算器を流用できる。
Verilogでのデコード例:
wire [31:0] imm_b =
{{19{instr[31]}},
instr[31], // imm[12](符号)
instr[7], // imm[11]
instr[30:25], // imm[10:5]
instr[11:8], // imm[4:1]
1'b0}; // imm[0] = 0(2byteアライン)ベース+オフセットアドレッシング(lw)
lw rd, imm(rs1) の実効アドレスは rs1 + imm。即値がある理由は、配列・構造体・スタックフレームへのアクセスが「ベースアドレス + 固定オフセット」で表現できるため。
即値がなければ add で都度アドレスを計算する必要があり、命令数とレジスタ消費が増える。
3オペランド形式(vs x86)
RISC-Vは add rd, rs1, rs2(rd = rs1 + rs2)という3オペランド形式。左から順に「書き込み先 → 読み出し1 → 読み出し2」で一貫している。
x86のAT&T記法は add src, dst(dst = dst + src)という2オペランド形式。デスティネーションが読み書き両方される。Intel記法はさらに順序が逆なので混乱しやすい。