Version 0.8 コントリビュータ: Alon Amid, Krste Asanovic, Allen Baum, Alex Bradbury, Tony Brewer, Chris Celio, Aliaksei Chapyzhenka, Silviu Chiricescu, Ken Dockser, Bob Dreyer, Roger Espasa, Sean Halle, John Hauser, David Horner, Bruce Hoult, Bill Huffman, Constantine Korikov, Ben Korpan, Robin Kruppe, Yunsup Lee, Guy Lemieux, Filip Moc, Rich Newell, Albert Ou, David Patterson, Colin Schmidt, Alex Solomatnikov, Steve Wallach, Andrew Waterman, Jim Wilson. 現在のバージョンで分かっている問題点: - エンコーディングフォーマットをより改善する必要がある。 - ベクトルメモリに関するコンシステンシモデルを明らかにする必要がある。 - 特権アーキテクチャとの相互関係について説明する必要がある。 1. イントロダクション --------------------- このドキュメントはRISC-Vのベースベクトル拡張について説明するものである。このドキュメントはベースベクトル拡張のすべての個々の機能について説明するものである。 本ドキュメントは、実装及び評価に用いられるベクトル仕様の安定版プロポーザルのドラフト仕様である。ドラフトのラベルが外れると、Version 0.8はツールチェインの開発、機能シミュレータ、初期の実装に関して十分に安定しているという意図を持ち、マイナーチェンジ及びアップデートが行われていく。 「ベースベクトル拡張」という言葉はベクトルISAコンポーネントの標準的な集合を説明するためのインフォーマルな用語として使用されている。ドラフト版の仕様は特定のベクトル機能がベクトル命令としてどのように実装することができるのかについて把握する意味を持っているが、どのようなベクトル命令のセットが与えられたプラットフォームに対して十分であるかについて決定されている訳ではない。 各実際のプラットフォーム プロファイルは、そのプラットフォームで採用されているベクター拡張の必須コンポーネントを正式に指定します。“V”という文字のついたRISC-V仕様は、標準的なサーバ・アプリけーしょプロセッサ向けのプラットフォームプロファイルです。組み込みプラットフォームを含む他のプラットフォームは、これらの拡張機能のサブセットを実装することを選択できます。特定のプロファイルに準拠する実装の必須サポート手順の正確なセットは、各プロファイル仕様が批准されるまで変更される可能性があります。 このベースベクトル命令は、暗号処理や機械学習などの様々なドメイン向けに拡張された追加ベクトル命令として動作するように設計されている。 2. 実装により決定される定数パラメータ ------------------------------------- 各hartはベクトル拡張をサポートすることにより以下の3つのパラメータを持つことになる。 1. 1ベクトル要素の最大ビットサイズ\ *ELEN*\ 。2の累乗の必要がある。 2. ベクトルレジスタのビットサイズ\ *VLEN ≥ ELEN*, 2の累乗の必要がある。 3. ストリップビット距離\ *SLEN*\ 。VLEN ≥ SLEN ≥ 32 である必要がある。それぞれは2の累乗の必要がある。 プラットフォームのプロファイルにはこれらのパラメータに関して更なる制約が入る可能性がある。例えば、ELEN ≥ max(XLEN,FLEN)や、最小VLEN値、SLEN値の設定など。 VLENのサイズを2の累乗であるという制限を除去する提案が行われている。 ELENのサイズをLMULと異なる(xxx)ようにしようという提案が行われている。 ISAは上記の制約情報をバイナリコードで記述することができ、hartは個のバイナリコードを参照することで異なるパラメータで異なる動作ができるようになる。 コードにより実装パラメータの違いを表現できるようになる。 .. ベクトル状態がアクティブなスレッドコンテキストは、 VLEN, ELEN, SLENパラメータのいずれかが異なるハードウェアスレッド間では、 実行中に合流することはできない。 3. ベクトル拡張のプログラミングモデル ------------------------------------- ベクトル拡張ではベースとなるスカラRISC-V ISAに対して32個のベクトルレジスタと、5つの非特権CSRレジスタ(``vstart``, ``vxsat``, ``vxrm``, ``vtype``, ``vl``, ``vlenb``)が加えられる。ベースのスカラISAが浮動小数点命令を含まない、\ ``fcsr``\ レジスタがさらに追加され、\ ``vxsat``\ と\ ``vxrm``\ のコピーが格納される。以下に各CSRレジスタの仕様を示す。 表1. 新ベクトルCSR ======= ========= ====== ============================================= Address Privilege Name Description ======= ========= ====== ============================================= 0x008 URW vstart ベクトルスタート位置を示すレジスタ 0x009 URW vxsat 浮動小数点飽和フラグレジスタ 0x00A URW vxrm 浮動小数点丸めモードレジスタ 0xC20 URO vl ベクトル長レジスタ 0xC21 URO vtype ベクトルデータ型レジスタ 0xC22 URO vlenb VLEN/8 (ベクトルレジスタのバイト単位での長さ) ======= ========= ====== ============================================= 3.1 ベクトルレジスタ ~~~~~~~~~~~~~~~~~~~~ ベクトル拡張ではベースのスカラRISC-V ISAに対して32個のアーキテクチャベクトルレジスタ\ ``v0``-``v31``\ が加わっている。 それぞれのベクトルレジスタはVLENビットだけのビットを保持する。 Zfinx(“F in X”)は新しいISAのオプションとして考えられているもので、浮動小数点命令が整数レジスタファイルをレジスタ引数として取ることができるようになるものである。0.8ベクトル拡張ではこのオプションとの互換性を持っている。 3.2 ``mstatus``\ 内でのベクトルコンテキストの状態 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``mstatus[24:23]``\ に\ ``VS``\ フィールドとしてベクトルのコンテキスト状態を表すためのビットが追加された。これは\ ``sstatus[24:23]``\ のシャドウである。このビットは、浮動小数点のコンテキストを表現するための\ ``FS``\ フィールドと同様の目的で定義されている。 ``VS``\ ビットフィールドがOffの状態で任意のベクトル命令を実行しようとするか\ ``vl``, ``vtype``, ``vlenb``, ``vstart`` CSRにアクセスしようとすると不定命令例外が発生する。 ``VS``\ フィールドがInitialもしくはCleanの状態でベクトルの状態を変更する任意の命令を実行するか、\ ``vl``, ``vtype``, ``vstart``\ レジスタへのアクセスを行うと\ ``VS``\ フィールドはDirtyに変更される。 実装では、ベクトルの状態に変更が発生しなくても\ ``VS``\ フィールドの状態は常にDirtyに設定しておくこともできる。\ ``VS``\ フィールドを細かく実装するかどうかはオプションである。 浮動小数点コンテキスト状態を示す\ ``FS``\ ビットフィールドがOffに設定されている状態で\ ``f``\ レジスタへのアクセス、もしくは\ ``fcsr``, ``vxsat``, ``vxrm`` CSRへのアクセスを行うと不定命令例外が発生する。 ``VS``\ フィールドと\ ``FS``\ フィールドのどちらかがOffに設定されている場合、\ ``f``\ レジスタ、\ ``fcsr``, ``vxsat``, ``vxrm``\ にアクセスするベクトル命令はすべて不定命令例外が発生する。しかし、これらのCSRは\ ``FS``\ がOff以外の値に設定されている場合はCSRアクセス命令により読み出すことができる。この場合は\ ``VS``\ フィールドの状態には依存しない。 ``FS``\ がInitialかCleanに設定されている場合、\ ``fcsr``, ``vxsat``, ``vxrm`` CSRもしくは\ ``f``\ レジスタを変更させるような命令を実行すると、\ ``FS``\ フィールドはDirtyに変更される。 ``FS``\ フィールドがDirtyに設定されている場合、コンテキストスイッチングを行う場合にはすべての\ ``fcsr``\ を退避しておかなければならない。 .. 固定小数点演算のみの実装であり浮動小数点に関する情報を退避・復帰させるメリットが生じない場合、\ ``FS``\ フィールドをハードワイヤでDirty固定しておきコストを削減することができる。この場合、\ ``fcsr``\ レジスタはいつでもアクセス可能である。 3.3 ベクトル型レジスタ, ``vtype`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``vtype``\ レジスタはXLENビット長のRead-onlyなCSRであり、ベクトルレジスタファイルに含まれるデフォルトのデータ型を示している。\ ``vtype``\ は\ ``vsetvl{i}``\ 命令の実行でしかアップデートすることができない。ベクトル型は各ベクトルレジスタ内の要素の構成についても決定し、どのように複数のベクトルレジスタをグループ化するかについても決定する。 初期のドラフト版では、\ ``vtype``\ レジスタは通常のCSR書き込み命令でも書き込みを行うことが可能であった。\ ``vsetvl{i}``\ 命令でのみアップデートが可能である仕様に変更したのは、\ ``vtype``\ レジスタの管理をより簡単化するためである。 ベースベクトル拡張では、\ ``vtype``\ レジスタは3つのフィールドを持っている。\ ``vill``, ``vsew[2:0]``, ``vlmul[1:0]``\ である。 表2. ``vtype``\ レジスタレイアウト +----------+------------+--------------------------------------------+ | Bits | Name | Description | +==========+============+============================================+ | XLEN-1 | vill | 不正な値が設定されると1が設定される | +----------+------------+--------------------------------------------+ | XLEN-2:7 | | 予約(write 0) | +----------+------------+--------------------------------------------+ | 6:5 | vediv[1:0] | EDIV拡張に使用される | +----------+------------+--------------------------------------------+ | 4:2 | vsew[2:0] | SEW(Standard-Element | | | | -Width:標準エレメント幅)の設定に使用される | +----------+------------+--------------------------------------------+ | 1:0 | vlmul[1:0] | ベクトルレジ | | | | スタのグループ乗算(LMUL)の設定に使用される | +----------+------------+--------------------------------------------+ .. 最小のベース実装では、\ ``vtype``\ では4ビットが必要である。\ ``vsew[1:0]``\ の2ビットと\ ``vlmul[1:0]``\ の2ビットである。\ ``vill``\ の不正な値の設定は、\ ``vsew[1:0]``\ を使用した64ビットのコンビネーションによりエンコードできる。これにより\ ``vill``\ ビットの実装を省略することができる。 ``vediv[1:0]``\ フィールドは以下に説明するEDIV命令で使用される。 .. ベクトルベース拡張に対するさらなる標準・カスタム拡張に関しては、上記のフィールドを拡張してより多くのデータタイプをサポートできるようにする。 It is anticipated that an extended 64-bit instruction encoding would allow these fields to be specified statically in the instruction encoding. 3.2.1. ベクトル標準エレメント幅\ ``vsew`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``vsew``\ の値は動的\ **標準エレメント幅: standard element width(SEW)**\ を設定する。デフォルトでは、ベクトルレジスタはVLEN / SEW標準幅エレメントに分割されているように見ることができる。ベースベクトル拡張では、SEWはmax(XLEN,FLEN)までのサイズを指定することができる。 表3. ``vsew[2:0]``\ (standard element width)エンコーディング ========= = = ==== vsew[2:0] SEW ========= = = ==== 0 0 0 8 0 0 1 16 0 1 0 32 0 1 1 64 1 0 0 128 1 0 1 256 1 1 0 512 1 1 1 1024 ========= = = ==== 表4. VLEN=128ビットの場合の例 === ============================ SEW ベクトルサイズあたりの要素数 === ============================ 64 2 32 4 16 8 8 16 === ============================ 3.2.2 ベクトルレジスタグルーピング(``vlmul``) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 複数のベクトルレジスタを1つにグループ化することができ、単一のベクトル命令で複数のベクトルレジスタを取り扱うことができる。ベクトルレジスタグループは、標準幅の要素から構成される、2倍以上のより長いベクトル長を操作することができるようになる。ベクトルレジスタグループは、よりベクトル長の長いアプリケーションにおいて効率的に命令を実行できるようになる。 **ベクトルレジスタグループ**\ という名前はベクトル命令によって取り扱われる1つ以上のベクトルレジスタのことを指す。グループ内のベクトルレジスタの数は\ **LMUL**\ により管理される。この値は2の累乗である必要があり、\ ``vtype``\ レジスタの\ ``vlmul``\ フィールドで設定される(LMUL=2^\ ``vlmul[1:0]``)。 VLMAX=LMUL*VLEN/SEWは、現在のSEWおよびLMULの構成で実行できる単一のベクトル命令の最大データエレメントの数である。 ===== = ==== ======= ========== ============================ vlmul LMUL #groups VLMAX Grouped registers ===== = ==== ======= ========== ============================ 0 0 1 32 VLEN/SEW vn (グループに1つのレジスタ) 0 1 2 16 2*VLEN/SEW vn, vn+1 1 0 4 8 4*VLEN/SEW vn, …, vn+3 1 1 8 4 8*VLEN/SEW vn, …, vn+7 ===== = ==== ======= ========== ============================ ``vlmul=01``\ の場合、ベクトルレジスタ\ ``v``\ nはベクトルレジスタ\ ``v``\ n+1も含み、2倍のビット長を操作することになる。ベクトルオペランドにより指定されるオペランドで、奇数番号のベクトルレジスタを指定した場合は不定命令例外が発生する。 同様に、\ ``vlmul=10``\ である場合、ベクトル命令は4つのベクトルレジスタを同時に操作する。また、ベクトル命令により指定されるベクトルオペランドが4の倍数でなかった場合は不定命令例外が発生する。\ ``vlmul=11``\ である場合は、8つのベクトルレジスタを同時に操作し、ベクトルオペランドとして使用されるベクトルレジスタが8の倍数でない場合は不定命令例外が発生する。 このグループパタン(LMUL=8の場合の\ ``v0``, ``v8``, ``v16``, ``v24``)は0.6で初めて導入され、浮動小数点の値がベクトルレジスタにオーバライドされた場合に浮動小数点の呼び出し規約に問題が発生することを避けるために導入された。一方で過去の半ではベクトルレジスタのグループ名は連続して付けられていた(LMUL=8では、\ ``v0``, ``v1``, ``v2``, ``v3``\ となる)。0.7以降では、浮動小数点レジスタは再び分離された。 レジスタマスク命令は、LMULの設定に関係なく常に単一ベクトルレジスタに対して機能する。 3.2.3. ベクトルタイプ不正 ``vill`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``vill``\ では直前に実行された\ ``vsetvl{i}``\ 命令によりサポートされない値が\ ``vtype``\ に書き込まれたことをエンコードするために使用される。 ``vill``\ ビットはCSRのXLEN-1ビットにより設定される。これにより、不正な値が設定されたかどうかを符号判定の分岐命令により判定できる。 もし、\ ``vill``\ ビットが設定されている場合、どのようなベクトル命令(ベクトルコンフィグレーション命令以外)を実行しても不定命令例外が発生する。 ``vill``\ が設定されていると、\ ``vtype``\ の他の\ ``XLEN-1``\ ビットは0に設定される。 3.3. ベクトル長レジスタ\ ``vl`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XLENビット長の読み込み専用CSRである\ ``vl``\ は\ ``vsetvli``\ および\ ``vsetvl``\ 命令でのみアップデートすることができるレジスタで、\ **fault-only-first**\ ベクトルロード命令バリアントである。 ``vl``\ レジスタは、ベクトル命令によりアップデートされる要素の数を符号なし整数として保持している。任意の書き込み先ベクトルレジスタグループにおいて、インデックスが\ ``vl``\ 以上の場合は、ベクトル命令が実行されても何も変化しない。\ ``vstart``\ ≥\ ``vl``\ の場合、書き込み先ベクトルレジスタグループにおいてどのような要素もアップデートされない。 結論として、\ ``vl``\ =0の場合は\ ``vstart``\ の値にかかわらず書き込み先ベクトルレジスタグループには何も書きこまれない。 .. スカラ整数レジスタもしくはスカラ浮動小数点レジスタの場合は\ ``vstart``\ ≦\ ``vl``\ でも実行される。 ``vl``\ に実装されるビットの長さは、その実装が最小のデータタイプにおいて実行することができる最大の要素数に依存する。最小のベクトル実装であるRV32IVでは、少なくとも\ ``vl``\ では0-32までの値を保持する(VLEN=32, LMUL=8, SEW=8でVLMAXが32となる)を保持するために6ビットが必要となる。 3.4 ベクトルバイト長レジスタ\ ``vlenb`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``XLEN``\ ビット長の読み込み専用CSRレジスタ\ ``vlenb``\ はVLEN/8の値、つまりバイト単位でのベクトル長を保持する。 ``vlenb``\ の値は任意の実装において、設計時に決められる定数である。 .. このCSRを使わない場合、いくつかの命令を実行してVLENのバイト単位での値を計算する必要がある。退避の必要な現在の\ ``vl``\ および\ ``vtype``\ の値を取得して計算を行う必要がある。 3.5. ベクトルスタートインデックスCSR\ ``vstart`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``vsatrt``\ は読み込み専用のCSRで、ベクトル命令により実行される最初の要素のインデックスを示している。 通常、\ ``vstart``\ はベクトル命令の例外時にハードウェアにより書き込まれる。\ ``vsatrt``\ の値はどの要素により例外がが発生したか(同期例外及び非同期例外で同様である)を示しており、復帰可能な例外である場合は、どの場所から復帰するかを示している。 すべてのベクトル命令は\ ``vstart``\ CSRで示されるエレメントの場所から実行され、例外が発生した要素よりも前の要素の結果が邪魔されることがないように設計されている。命令の実行が完了すると、\ ``vstart``\ CSRは0にリセットされる。 ``vsetvl{i}``\ 命令を含むすべてのベクトル命令は\ ``vstart``\ CSRをゼロに設定する。 不定命令例外を発生させたベクトル命令では、\ ``vstart``\ の値は変更されない。 ``vstart``\ レジスタの値が\ ``vl``\ 以上場合は、どの要素にも実行されず、書き込みベクトルレジスタの\ ``vl``\ がゼロに設定されることはない。 ``vstart``\ CSRは最大の要素インデックス(VLMAXよりも1つ小さな値)もしくはlg2(VLEN)まで書き込むことができるようなビットサイズが定義される。\ ``vstart``\ CSRの上位のビットはハード的にゼロが設定される(ゼロ読み出し、書き込みは無視される)。 ベクトル長の最大値はLMULの最大設定値(8)およびSEWの最小値(8)により計算され、VLMAX_max=8*VLEN/8=VLENとなる。例えば、VLEN=256であれば、\ ``vstart``\ は8ビットであり、0から255までを表現することができる。 ``vstart``\ CSRは非特権コードにより書き込みを行うことができるが、いくつかの実装では\ ``vstart``\ にゼロ以外の値を書き込むと大幅に速度が低下する可能性がある。したがって、\ ``vstart``\ はアプリケーションプログラマが使用すべきではない。いくつかのベクトル命令では\ ``vstart``\ が非ゼロの場合には実行することができず、以下に定義された不定命令例外が発生する。 特権用以外のコードでも\ ``vstart``\ が見えることによって、ユーザレベルのスレッドライブラリをサポートすることができる。 実装では、\ ``vstart``\ の値に何らかの値が設定されている状態では例外を発生することを許しており、そのような実装では同じ\ ``vtype``\ 設定においてベクトル命令は結果を生成しない。 たとえば、いくつかの実装ではベクトル算術演算を実行中には決して例外を発生せず、命令の実行が完了するまで例外の発生を待つことができる。このような実装ではベクトル算術演算命令において\ ``vstart``\ が非ゼロである場合は例外が発生することを許している。 3.6. ベクトル固定小数点丸めモードレジスタ\ ``vxrm`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ベクトル固定小数点丸めモードレジスタは2ビットのRead-Write丸めモードビットフィールドを持っている。ベクトル固定小数点丸めは\ ``fcsr``\ レジスタの上位ビットのビットフィールドを反映しているが、異なるCSRビットアドレスが割り当てられている。浮動小数点を持たないシステムの場合は、ベクトル拡張を追加する場合には\ ``fcsr``\ レジスタを追加する必要がある。 固定小数点の丸めアルゴリズムは以下のように指定される。丸め前の値が\ ``v``\ であり、\ ``d``\ ビット長であるとする。この場合丸め後の値は\ ``(v >> d) + r``\ であり、\ ``r``\ は以下に示す丸めモードの表によって決定される。 +----------+---------+------+--------------------+--------------------+ | Bits [1] | Bits[0] | 略称 | 丸めモード | 丸めイン | | | | | | クリメント\ ``r`` | +==========+=========+======+====================+====================+ | 0 | 0 | rnu | r | ``v[d-1]`` | | | | | ound-to-nearest-up | | | | | | (add +0.5 LSB) | | +----------+---------+------+--------------------+--------------------+ | 0 | 1 | rne | rou | ``v[d-1 | | | | | nd-to-nearest-even | ] & (v[d-2:0]!=0`` | +----------+---------+------+--------------------+--------------------+ | 1 | 0 | rdn | round-down | ``0`` | | | | | (truncate) | | +----------+---------+------+--------------------+--------------------+ | 1 | 1 | rod | round-to-odd (OR | ``!v[d] | | | | | bits into LSB, aka | & v[d-1:0] != 0`` | | | | | “jam”) | | +----------+---------+------+--------------------+--------------------+ 以下の丸め関数は、命令の説明時に丸めの操作を説明表現するために使用する。 :: roundoff_unsigned(v, d) = (unsigned(v) >> d) + r roundoff_signed(v, d) = (signed(v) >> d) + r Bits[XLEN-1:2]はゼロである。 丸めモードは\ ``csrwi``\ 命令により1命令で設定できる。 3.7. ベクトル固定小数点飽和フラグ\ ``vxsat`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``vxsat``\ CSRは1ビットの読み書き可能なビットを保持しており、固定小数点命令の計算結果が書き込み先レジスタのフォーマットに合わせるために飽和した場合に設定される。 ``vxsat``\ ビットは\ ``fcsr``\ レジスタの上位ビットにミラーリングされる。 3.7. ``fcsr``\ のベクトル固定小数点フィールド ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``vxrm``\ および\ ``vxsat``\ は分離されたCSRであり浮動小数点CSR\ ``fcsr``\ からアクセスすることができる。\ ``fcsr``\ レジスタは浮動小数点をサポートしていない実装でも、ベクトル拡張をサポートしている場合には追加する必要がある。 ==== ====== ======================== Bits Name Description ==== ====== ======================== 10:9 vxrm 固定小数点丸めモード 8 vxsat 固定小数点精度飽和フラグ 7:5 frm 浮動小数点丸めモード 4:0 fflags 浮動小数点例外フラグ ==== ====== ======================== .. これらのフィールドは\ ``fcsr``\ にパッキングされるのは、コンテキストの保存と回復を高速化させるためである。 3.8. ベクトル拡張のリセット状態について ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ベクトル拡張はリセット時に矛盾の発生していない状態でなければならない。特に、\ ``vtype``\ および\ ``vl``\ は\ ``vsetvl``\ 命令により読み込みおよびリストアできなければならない。 リセット時には\ ``vtype.vill``\ は1が設定されており、残りの\ ``vtype``\ レジスタはゼロが設定されており、\ ``vl``\ は0が設定されている状態が推奨される。 ``vstart``, ``vxrm`` ,\ ``vxsat``\ CSRはリセット時にはどのような値が設定されていても構わない。 ベクトルユニットを使用するときはいかなる時も最初に\ ``vsetvl{i}``\ を実行し、\ ``vstart``\ をリセットさせる必要がある。\ ``vxrm``\ および\ ``vxsat``\ フィールドはソフトウェアにより使用前に明示的にリセットを行うべきである。 ベクトルレジスタはリセット時にはどのような値が設定されていても構わない。