0. Abstract

本稿は SING (Sing Is Not GRAPE) チップの動作仕様を与える。形式的な仕 様ではなく、何をするか、どういうものかという記述になる。が、 「SINGチップ記述書」とか異なり、開発の経緯等は省略して現在の完成したチッ プについて記述する。

SING の基本的概念は、1チップ上に 比較的単純なベクトルプロセッサを非常に多数集積するアーキテクチャである。 単純にベクトルプロセッサを集積すると、システムの性能はオフチップメモリ への通信バンド幅で決まってしまい、多数のプロセッサを集積しても性能向上 は得られない。SING では、計算負荷の高いアプリケーションでは多くの場合に 適切なコーディングやアルゴリズムの変換により必要メモリバンド幅を劇的に 下げることができることに注目し、オフチップメモリバンド幅が比較的小さい ままで非常に多数のプロセッサを1チップに集積する。プロセッサは演算器と レジスタファイルを持ち、チップ内の制御プロセッサから放送される命令を SIMD 的に実行する。制御プロセッサはまた全プロセッサのレジスタにデータ を放送したり、個別のプロセッサのレジスタを読み書きすることができる。ま た、プロセッサ内に reduction tree をもたせることで、プロセッサにまたがっ た縮約演算を高速に実行する。

Contents

1. 更新履歴

1.1. 2009/3/1

「SINGチップ記述書」をベースに書き始める。

2. はじめに

SINGは、基本的には 1 チップに非常に多数の演算器を集積し、限られた範囲の 問題に対してではあるかもしれないがそれらを有効に使うためのアーキテクチャ である。 そのような方向を目指すアーキテクチャは、IBM, Sun, Intel, AMD 等の目指す On-chip Multiprocessor の他、再構成可能プロセッサ、SIMD 演 算ユニット等様々なものがあるが、 SING では SIMD 動作する多数の(単純な) ベクトルプロセッサを多数集積するというアプローチを取る。

SIMD プロセッサの場合、大きな問題は、1チップに多数のプロセッサを集積す ると、プロセッサ数とその速度の比例して外部メモリへのバンド幅を増やす必 要があることである。現在の半導体技術では、チップ間接続のバンド幅と1チッ プで実現可能な演算性能のギャップは極めて大きくなっており、これが SIMD プロセッサが使われなくなった理由であるといえる。

SING では、この問題を「外部メモリへのバンド幅を増やさない」という単純な 方法で「解決」する。重力多体問題や、密行列の演算のような、データ量に対 して演算量が多く、 n 個のデータに対して の演算、 あるいは 個のデータに対して の演算をす る、しかも演算を並列処理可能な応用では、プロセッサ側にはレジスタファイ ル程度のものだけをおき、そこに局所的に必要なデータを保持し、計算中は外 部メモリから全プロセッサにデータをブロードキャストしながら演算を行うと いうアプローチが可能である。これが SING の基本的なアイデアである。

実際には、例えば 512 個のプロセッサが全て同じデータを外部メモリから受 け取るのも使い勝手が悪いので、プロセッサを適当な数、例えば 16 個のグルー プに分けて、グループ毎に共有メモリをもたせる。同じグループのプロセッサ は同じメモリからデータを受け取る。但し、それぞれの共有メモリには、やは り外部メモリから書き込むことになる。

この詳細は図 1 に示す。グループ間にまたがって結果を合計 (縮約)することも可能にする。 SING プロセッサチップ自体は、なるべく内部に制御回路やシーケン サ等をもたない構造とし、各プロセッサへの命令を直接外部の制御プロセッサ から投入する。このプロセッサは FPGA で実現する。この場合、FPGA からプ ロセッサチップへの命令ストリームのために必要なバンド幅が性能ボトルネッ クになる可能性があることと、パイプラインレイテンシのための命令スケジュー リングの手間を省くために基本命令はベクトル命令とし、4個程度の短いベ クトルを1命令でパイプライン処理する。

全体システムは、このチップ+FPGA+メモリが数個のったボードを普通のPCに 1-2枚挿したシステムのクラスタとして実現する。いかにしてその上でアプリ ケーションを並列化するかといった問題はここでは扱わない。

以下、3章ではチップの基本的な構成についてまとめる。4章ではチップ各部の 詳細な記述を与える。5章では、 PE の演算器について、その動作の詳細をま とめる。 6章では命令セットを定義する。7章ではチップの I/O の詳細を定義する。 8章以下はおまけである。

3. チップの基本的構成

3.1. 基本概念

1 に SING の基本概念を示す。

Figure 1: SING の基本構成

一つのSING チップは、「放送ブロック」が多数集積され、一つの放送ブロック は多数の演算要素(Processor Element, PE)からなるという階層構造を持つ。 チップ単体では完結した計算機ではなく、外付けの制御プロセッサから命令ス トリームを受け取る。命令ストリームは基本的には水平型マイクロコードであ るが、命令のために必要な通信バンド幅を減らすためにベクトル命令とする。 また、同じく制御プロセッサを通して外部メモリ、ホスト計算機と通信する。

以下、下の階層から順に概略を述べる。

3.1.1. PE

PE は、浮動小数点/固定小数点/論理演算の演算器、アドレス生成ユニット (テーブルルックアップのための間接アドレッシング機能をもつ)、ローカルメモリ からなる。 PE は自分のローカルメモリにあるデータを使って演算する他、 自分の上位にある放送メモリからデータを受け取って、選択的に(あるPEだけが)、 あるいは非選択的に(全PEが)ローカルメモリに書くことができる。

PE の動作は SIMD であり、全 PEが(マスクレジスタによってディスエイブル されなければ)同一動作をする。これは古典的な SIMD 超並列計算機と変わら ない。

3.1.2. 放送ブロック

PE が複数(今回の実装では32個集まって)放送ブロックを構成する。 放送ブロックは、放送メモリと PE からなる。放送メモリは、同一ブロック内 の PEと以下の3通りの方法で通信する。

  1. データを放送する(PE から見ると普通のロード命令)
  2. 1つの PE にデータを転送する(PEのID番号を条件にする条件実行ロード命令)
  3. 1つのPEがデータを書き込む(PEのID番号をパラメタにとるストア命令)

PE からのアクセスとは独立(並行)に、チップ外の制御プロセッサは放送メモ リにランダムアクセス、あるいは全放送ブロックに同一データを放送すること ができる。放送メモリのデータを制御プロセッサが読み出すのは後述の結果縮 約ネットワークを通してになる。

このように、外部から放送ブロックへの書き込みと、放送ブロック内での PE への書き込みの両方に、放送モードとランダムアクセス(非放送)モードを設け ることで、 外部(制御プロセッサ)側からみると

の4種類の書き込みが可能になる。これらを使い分けることで、

を実行する。

3.1.3. 結果縮約ネットワーク

SING チップが計算結果を制御プロセッサに返すのは、結果縮約ネットワークを 通してである。 結果縮約ネットワークは、各放送ブロックからの出力を、加 算、論理演算等の縮約演算をしながら返すツリー型のネットワークである。 基本的な動作モードは、PE がストア命令で放送メモリに書いたデータを縮約 しながら読み出して出力するというものである。

3.1.4. ベクトルアドレス生成シーケンサ

図には示してないが、ベクトルから実際にレジスタファイル等を制御する信号 を生成する簡単なシーケンサが存在する。これらの動作の詳細は、 詳細記述においてはレジスタファイル等の記述のところでまとめて述べる。 演算器の動作制御はベクトル命令で、同じ命令の実行中は同じ制御信号をラッ チしているだけなので特に述べることはない。

3.1.5. 注意

ハードウェアにはインターロックや命令が実行可能かどうかの判断をするロジッ クは一切実装しない。指定したベクトル長が短い場合や、命令の種類によって は連続する命令間で干渉が起こることがありえるが、これはアセンブラなり人 間なりが必要なダミーサイクルを挿入して実行可能コードを生成する。

3.2. 外部インターフェースと動作モード

Figure 2: チップの外部インターフェースの概念

2 にチップの外部インターフェースの概念を示す。

命令ストリーム、入力データはそれぞれ専用の入力ポート(ISP, IDP)から供給され、結果 出力も専用ポート(ODP)からなされる。

IDP, ODP は可変長パケットベースの単純なプロトコルを持つ。 HyperTransport(HT) の write request だけを実装するようなものを考えて欲しい。

命令ストリームは固定長の命令を常時たれながしであり、 命令ワードをシリアライズして送るだけである。

物理的な接続にはシングルエンドの HSTL 規格を用いている。

ステータス出力は、エラーステータス、チップの動作状態、診断出力レジスタ 等を出力する。これは非同期出力であり、CMOS レベルの出力である。

3.2.1. ISP 命令ストリーム

1ベクトル命令は 108 ビットであり、これを 32 ビットの ISP ポートから4サ イクルに分割して入力する。余っているビットは使用されていない。

3.2.2. 入力データポート

IDP からの入力は BM だけに書く。ローカルメモリに直接書けるようにしても いいが、 BM と LM の転送命令はどうせあり、並行動作可能なので性能の面か らも不要である。

書き込みは、

  1. 放送
  2. 単一の BM への書き込み
  3. 複数の、しかし全部ではない BM への書き込み

の3モードがある。 GRAPE-6 の場合と同様に、BM の番号指定とマスク指 定を組み合わせたアドレス指定とすることで、単純な2のべきの数のサブグルー プは指定できるようにする。

さらに、放送ではなく、1パケットにBB個数分のデータを並べて全 BB にそれ ぞれ違うデータを書くことも可能にする。これは必須の機能ではないが、 FPGA 側の制御が若干簡単になるケースもある。

BM は PE へのデータ放送と IDP からの書き込みが並列に動作できる。これに よって多くの場面でデータ転送と計算をオーバーラップ動作させて実効性能を 上げることができる。

このため、 BM はデュアルポートメモリを使って実装されている。

3.2.3. 出力ポート

出力ポートは BM のデータを縮約しながら、あるいはランダムアクセスで指定 した放送ブロックの BM のものを、出力する。

出力指定コマンドは IDP から投入する。コマンド自体は PE のコマンドと類 似になるが、実行シーケンサは全く別のものとなる。縮約する演算器は PE の浮動小数点演算器と整数演算器をそのまま置く。

命令で指定されるものは

である。

3.2.3.1. ブロックマスク

特に縮約を伴う出力の時に、全てのブロックの結果を合計したくはない場合が ある。縮約に参加しないブロックは、縮約ネットワークに output valid を出 さない。ようにできる。 縮約ネットワークの ALU は、入力の一方が output valid でなければ他方の入 力をそのまま出力に出し、両方 output valid でなければ出力も output valid を出さない。

ブロックマスクは、単純に IDP からブロックマスクレジスタに書き込みを行 うことで設定する。つまり、 IDP からは、BM への書き込みの他、放送ブロッ クに属するレジスタへの書き込みを行う。

3.2.4. エラー検出・訂正

ISP, IDP の入力ではパリティチェックを行ない、 出力ではパリティつきでだす。 ECC にはしていない。

入力パリティエラーの検知は、内部のレジスタを読むことで行う。 (ここ後ろみて確認すること)

4. ハードウェア概要

チップ全体は以下の要素からなる。

Figure 3: SING の基本構成

3 にブロック間の関係を示す。

ISU, DIU についた放送ネットワークはそれぞれの出力を全 BB に配るだけの 単純なものである。以下、ISU から順に内容を述べる。

4.1. 動作クロック

SING チップは全体がクロック同期で動く。入力データはクロック付きでくるが、 これは違う周波数であってはならない。つまり、入力データクロック(典型的に はFPGA クロック)と SING の内部クロックは同じクロック発生器から供給され ている必要がある。ソースクロックは位相補償を行うためだけのものである。

なお、I/O に伴うクロックは内部クロックを周波数半分に分周したものであり、 立ち上がり、立ち下がりの両方のクロックエッジでデータがサンプルされる。

4.2. 命令ストリーム入力ユニット(ISU)

ISU の機能は単純であり、入力ポートから入ってきた命令語を組み立てて全放 送ブロックに送るだけである。

4.3. データ入力ユニット(DIU)

データ入力ユニットは、バンド幅が大きいという以外は ISU とほとんど同じ ものである。72ビットが内部クロック毎に入る。

4.4. 放送ブロック (BB)

Figure 4: 放送ブロックの基本構成

4 にBBの基本構成を示す。BB は以下の要素からなる

外部との接続は、 ISU は命令デコーダと、DIU, RRN はBM とつながる。PE は 直接に外部につながってはいない。

4.4.1. 放送メモリ(BM)

放送メモリは 72ビット1024語の完全デュアルポートメモリ(2アドレスでそれ ぞれ独立に read/write が指定できる)である。

Figure 5: 放送メモリ。

5 に BM の構成を示す。ポートはグローバル側とロー カル側と呼ぶことにする。グローバル側は DIU からの書き込みと RRN への出 力である。ローカル側はプロセッサエレメントへの放送または書き込みである。 BM 自体は単純なメモリで特別な機能は何もない。

4.4.2. PE

各プロセッサエレメント (PE) は

からなり、それぞれのメモリ要素は放送メモリから、または外部メモリポート から書き込み可能である。

外部メモリに書き込めるのは GRF Bポートから読み出したデータのみとする。

TREG はGRF に対して補助的な役割を果たす。

Figure 6: PE の論理的構造

6 にPE の論理構造を示す。

演算器は浮動小数点乗算器、浮動小数点加算器と、整数 ALU の3種を持つ。そ れらへの入力は基本的には上のTレジスタ、汎用レジスタ、ローカルメモリの3 つのメモリ要素の出力である。メモリ要素への書き込みは、 演算要素の出力または共有メモリからのものである。また、メモ リ要素の出力を共有メモリに出すこともできる。この時には1つの PE だけが 選択される。

演算ユニットは3個あるが、今回の実装ではそのうち浮動小数点加算器(FMUL)は独立 した入出力をもたせる。浮動小数点加減算器(FADD) と整数ALU (IALU)は入力、 出力ともに共有する。つまり、 FMUL-FADD, FMUL-IALU は並列動作可能である が FADD-IALU はどちらかの出力しかストアできない。これはマルチプレクサ や配線のサイズを減らすためだが、あまり必要ではなかったかもしれない。

BM への出力は GRF B ポートからである。

結局、マルチプレクサ A は 4 入力1出力の独立なマルチプレクサ4個からなる。 但し、 FADDSUB/IALU の A 入力については、固定 ID であるプロセッサ番号、 放送ブロック番号も入力として選択できる。さらに、乗算器からの 直接フィードバックも入力にできる。従って、このマルチプレクサだけは 7 入力となる。マルチプレクサ B も同様に3入力1出力の独立なマルチプレクサ3 個である。これらのマルチプレクサの動作はマイクロコードによって指定され る。

なお、LM については Tレジスタの値をアドレスにすることを可能にする。こ れにより間接アクセスを実現する。

4.4.2.1. 浮動小数点フォーマット

浮動小数点データフォーマットは以下の通りとする。

指数形式は IEEE-754 と同じ。 短語 で0x3FF000000 が 1 になるもの。

0 は指数 0

無限大は指数 all 1 (短語で 0x7FFFFFFFF, 0xFFFFFFFFF)

無限大と0の掛け算の結果は 0とする。 こういった演算例外についてはアプリケーション側で面倒をみる必要がある。 面倒なので NaN はサポートしない。

丸めは bias-corrected force-1 rounding である。これは、 演算結果の MSB の下のビットの一つでも 0 でないビットがあれば、 MSB を 1 にする方式で ある。

元々 MSB が 1 であれば、これは実効的に切り捨てである。これに対して元は MSB が 0 であった場合は切り上げになる。というわけでほぼ四捨五入になっ ていることは理解されよう。

しかし、MSB の下が全て 0 であった場合にも MSB を1にすると、丸めた後の 値の平均が丸めた前と同じにならない。 5ビットの数の下4ビットを丸める場 合を考えると、可能な値は 00000b から 11111b (ここでは b がつくのは2進 数を表すとする)の32通りで、平均は 15.5 である。ところが丸めた後が 10000b であるとするともちろん丸めたあとの平均は 16 になってしまう。こ のバイアスを補正するためには 00000b は 00000b のまま、つまり、下位ビッ トが all 0 の時には MSB をそのままにする (10000b はもちろんそのままで ある)ようにしておけばよい。

この丸め方式は、 IEEE 754 で採用されている round-to-nearest-even 方式 に比べて

という利点と

という欠点がある。

今回は、1ビットの損よりも、実装の単純さから来る開発期間の短縮を 優先した。

なお、語形式として、非正規化数をサポートする。 これの解釈は、「hidden bit を 補わない」というものである。

何故こんなものを使うかというと、

  1. 積算、総和の時に、積算順序によらないで結果が同じになるようにする。
  2. 倍精度乗算の時に使う。

ためである。

4.4.2.2. 浮動小数点乗算器の構成

今回の実装では、浮動小数点演算器が持つ乗算器は のもの とする。これにより、短語乗算は1サイクル1結果を出す(乗算器の半分は無駄 になる)。また、倍精度乗算は部分積2つに分けて、掛け算と掛け算+加算の組 合せで実行する。

浮動小数点乗算器では以下の手順で乗算を行う。

  1. 仮数の切り出しを行う。パラメタの指定に従って、25ビットまたは 50ビッ トシフトする。また、正規化表現(ケチ表現)でシフトしない場合にはMSB に 1 を補う。同時に指数も仮数のシフトに応じて調整する。つまり、25ま たは50を引く。アンダーフローしたら 0 にする。
  2. 仮数を 25 ビットまたは50ビットに丸める。これはパラメタの指定に従っ て、指定があれば25ビットに丸める。何も指定がない時には A ポート側は 50 ビットに丸める。
  3. 仮数の乗算を行う。入力は A ポート 50ビット、B ポート 25ビットで、結 果は 75 ビットになる。
  4. 結果を正規化する場合には、最上位が 0 なら1ビットシフトして、別に計 算していた指数から 1 を引く。
  5. 結果を正規化しない場合には、無条件に1ビット右シフトして、別に計 算していた指数に 1 を足す。
  6. シフトした結果の最上位を切りとった、残りが新しい仮数になる。結果を 短語にしまう場合には 24 ビットに、長語にしまう場合には60ビットに丸 めを行う。
  7. 指数はバイアス表現なので足してからバイアスである 0x3fe を引く。で、 上の仮数による調整を行ったあとで、オーバーフローしていたら 0x7ff、 アンダーフローしていたら 0 にする。但し、入力の指数のどちらかが 0x7ff の 時にはそのままとし、そうでなくてどちらかが 0 であれば 0 とする。 また、仮数が0になった場合も指数を 0 とする。但し、この場合も入力の 指数のどちらかが 0x7ff の時にはそのまま 0x7ff である。

乗算器入力ポートの制御線は A と B で異なる。Aは

であり、B入力ポートに以下の制御線が必要ということになる

それぞれ4ビットづつである。 さらに出力の丸めモードでもう1ビット。合計9ビットの制御線になる。

つまり、制御線は以下のようになる:

   SHIFT50A   ポートAの仮数を50ビット上にシフト
   ROUND50A   ポートAの仮数を(シフト後)50ビットに丸める
   ROUNDA     ポートAの仮数を(シフト後)25ビットに丸める
   NORMALA    ポートAの入力を正規化数とみなす
   SHIFT25B   ポートBの仮数を25ビット上にシフト
   SHIFT50B   ポートBの仮数を50ビット上にシフト
   ROUNDB     ポートBの仮数を(シフト後)25ビットに丸める
   NORMALB    ポートBの入力を正規化数とみなす
   ROUND      出力を丸める
   NORMALO    出力を正規化する
動作は内部1段のパイプラインである。

4.4.2.3. 浮動小数点加減算器

加減算器のほうも乗算器と同様に非正規化数を扱うことができる必要がある。 また、演算は長語で行うが、出力は短語に丸めることが可能でなければならな い。このため、以下のような制御線がある。

   NORMALA    ポートAの入力を正規化数とみなす
   NORMALB    ポートBの入力を正規化数とみなす
   SIGNB      B の符号を反転する(減算)
   ROUND      出力を25ビットに丸める
   NORMALO    出力を正規化する
演算結果フラグ(後述の M レジスタに格納される)は、演算結果が 正であることを示す(符号ビットを反転)ものとする。

4.4.2.4. 固定小数点 ALU

これは普通の固定小数点 ALU であり、以下の演算をサポートする。 語長はALU は今回の実装では 72 ビットのみとする。

オペレーションは

 命令コード オペレーション
 0x00       A+B
 0x01       A-B
 0x02       A+1
 0x03       A-1
 0x04       not A
 0x05       A and B
 0x06       A or B
 0x07       A xor B
 0x08       max (A,B)
 0x09       min (A,B)
 0x0A       A
 0x0B       B
 0x0C       A lshiftl B
 0x0D       A lshiftr B
 0x0E       A bshiftl B
 0x0F       A bshiftr B
 0x10       logical not A
 0x1F       immidiate
 
これらは 5ビットの命令コードで指定する。l[b]shiftl[r]は、論理(バレル) 左(右)シフトである。算術演算、論理シフトについては符号ありと符号なしの 両方の演算を可能にする。符号あり演算は 2 の補数である。

Max, min は符号なし、ありの両方でちゃんと動くようにする。符号なしのモー ドでは正の浮動小数点数も同様に扱うことができる(正規化されていれば)。但 し、符号が変わるものについては扱えない。符号がある浮動小数点数の選択は 浮動小数点加減算器のフラグと条件付き実行で行う。 Max, min をもたせる理 由は、 RRN のところでは必要であり、 RRN の ALU とPE の ALU を同じものに したいからである。

logical not は A 入力が 0 であれば 1 (長語境界と短語境界の両方の LSB を1)、0 でなければ 0 にする命令である。これにより、ビット演算ではない 論理式評価を可能にする。単純に論理積を取るためには多少面倒な操作が必要 だが、まあ、できないよりはましであろう。

immidiate (即値)命令は、入力ポートはつかわないで命令フィールドの一部の ビット値からそのまま短語の値を生成して出力する。この時に、レジスタ書き 込みフィールドはそのまま使うので、データを以下のフィールドに分解して入 れる

FADDSUB 制御フィールドの下4ビットは使わない。

整数乗算命令はもたない。浮動小数点の仮数の処理には定数倍等が必要だが、 浮動小数点演算ユニットを使って処理する。

メモリ、レジスタから短語がくる時には MSB 側に入る。LSB は 0 で埋める必 要がある。バレルシフトはこの時短語に対して正しい結果になることを要求し ない。

演算結果フラグについては、 演算が A-B, A+B, A+1, A-1 の時、 結果が非負な らフラグがセットされる。それ以外の時は結果が all 0 ならフラ グがセットされるということにする。符号なしモードでの減算では、 MSB の 上へのキャリを見て結果の符号を判断する必要がある。

IALU の制御コードは以下のようになる。

   IALUOP[0:4] ALU 自体の命令コード
   UNSIGNED    符号なし演算を指定(1の時に)
   

4.4.2.5. 条件付き命令

SIMD プロセッサであり局所的な(PEによって違う動作になる)ジャンプ命令は 存在できないので、条件付き実行命令によってジャンプでできることをする必 要がある。

全命令が条件付きにすることが可能であり、条件付きの時にはマスク レジスタ (Mレジスタ)の値によって結果をストアするかどうかを判定する。

Mレジスタへの書き込みを指定した時にセットされるフラグは、整数 ALU と浮動小数点加減算器 のフラグのどちらかを選択する。

条件のネストに対応するためには M レジスタが複数必要なので、これは複数 もたせて命令のオペランドで制御 M レジスタと結果 M レジスタを指定する。 M0 レジスタは常に 1 (真)を返す。

 IMR[0:2] 書き込み制御を  M レジスタのどれから取るか。 0 は ALL 1
 OMR[0:2] 演算器の出力を M レジスタのどれに書くか。 0 は 書かない
 IFSEL    FADD と IALU のどちらのフラグ出力を取るか

4.4.2.6. T レジスタ

T レジスタの動作は単純である。演算中は

T レジスタは短語・長語を区別しないで、短語命令であれば MSB 側だけが使 われる。

ブロックとしての Tレジスタは以下の入出力を持つ

入力:

  DIN[0:71]  72 ビットデータ入力
  WADDR[0:3] 書き込みアドレス
  MASK       書き込みマスク。0なら書かない
  WE         ライトイネーブル。
  RADR[0:3]  読み出しアドレス
  SHORTSTOP  書き込み(入力)データをそのまま出力に回す。
出力

  DOUT[0:71]       72 ビットデータ出力
  DOUTEARLY[0:71]  72 ビット出力。メモリアドレス用

7 に T レジスタの基本的回路を示す。

Figure 7: Tレジスタの入出力定義

4.4.2.7. レジスタファイル (GRF)

レジスタファイルは2出力1入力であり、長語1語を短語2語としてアクセス可能 にする。つまり、ベクトル命令実行時に短語か長語かでアドレスの増えかたが 違う。

4.4.2.8. ローカルメモリの動作

ローカルメモリは1ポートなので、書き込み中に読み出しは行えない。これは、 つまり、ある命令が LM への書き込みであった時にそれの次の2命令は LM から の読出しを行うことができないということである。

4.4.2.9. ローカルメモリのアドレスモード

ローカルメモリのアドレスモードには、直接アドレスと T レジスタ間接があ る。Tレジスタ間接は、ベクトル演算時に T レジスタの値がそのままローカル メモリアドレスとなるものであり、アドレス修飾(オフセットを足したりとか する)の機能はもたない。

4.5. 結果縮約ネットワーク (RRN)

RRN は PE の浮動小数点ユニットと ALU と同じものである縮約ユニッ ト (RU) からなるツリー構造を持つ。動作モードとして、縮約モードとランダ ムアクセスモードの2つをもつ。縮約モードでは2つの入力に対して命令 語で指定された演算がなされる。 ランダムアクセスモードでは、指定した BB からの入力がそのまま伝わる。

4.5.1. RU 命令語

各 RU は以下の命令語を受け取り、それに従って動作する。

   FSEL        出力選択。1ならFADDSUB の出力を取る。 0 なら IALU
   NORMALA     ポートAの入力を正規化数とみなす
   NORMALB     ポートBの入力を正規化数とみなす
   SIGNB       B の符号を反転する(減算)
   ROUND       出力を25ビットに丸める
   NORMALO     出力を正規化する
   IALUOP[0:4] IALU の命令コード
   UNSIGNED    符号なし演算を指定(1の時に)

  

4.6. 出力データストリーム処理ユニット (DOU)

DOU の機能は単純であり、72(パリティつけて81)ビットの入力データ、分周クロック、 OV 信号からベースクロックで動くシリアライズした出力を作るだけであ る。

出力のデータ線数は21、クロックの本数は3本とする。パリティは付けるが ECC はなしですます。図 8 に DOU の入出力を示す。

Figure 8: DOU の入出力。

なお、真っ当な ODP ポートの他に、ステータスレジスタとして 8 ビットの内 部レジスタを設けて、出力の LSB 8 ビットをストアできるようにする。この ステータスレジスタはチップの出力ピンを直接ドライブし、LED (そのままは つかないと思うが)などで診断情報の表示に使う。結果をステータスレジスタ に出すか出力ポートに出すかの指定は

   ODPOE       ODP から出力する
   SREGEN      ステータスレジスタに書き込む
というフィールドを RRN 命令語に追加することで行う。

5. PE 演算の詳細

前章では、 SING チップの各部について基本的な動作を記述した。ここでは特 に演算器について、動作の詳細を解説する。なお、これはあくまでも仕様記述 であり、演算器の内部動作はここの記述した通りとは限らない。が、演算結果 はここに書いてある通りでなければならない(不一致はこの仕様書または実 チップのバグである。)

5.1. 浮動小数点データフォーマット

浮動小数点データフォーマットは以下の通りとする。

指数形式は IEEE-754 と同じ。 短語 で0x3FF000000 が 1 になるもの。つま り、 IEEE-754 の規定のように、正規化された仮数を の範囲 の数と解釈する場合には、指数のオフセットが 0x3FF ということになる。

但し、通常の IEEE 計算と違って、非正規化数というデータ型を持つものとす る。通常の正規化数では、仮数は hidden bit を持つものと暗黙に解釈される。 つまり、(16進で)

  指数 3FF
  仮数 000000
という表現は、仮数の MSB の「上」に1があるもの、つまり、仮数が

      1000000
であるものと解釈される。仮数の小数点はちょうどこの MSB とその上の hidden bit のあいだにあるので、

      (1)000000 -> 1.0
      (1)800000 -> 1.5
      (1)FFFFFF -> 1.999999....
と解釈される。で、指数は固定小数点であり、符号ビットは 0 が正、1が負で ある。例えば 0x400000000 は 2.0 0x7FF000000 は -1.0 になるわけである。

非正規化数と解釈する時には、この hidden bit を補わないで解釈する。つま り、

      000000 -> 0.0
      800000 -> 0.5
      FFFFFF -> 0.999999....
と、そのまま解釈する。この解釈では、指数がいくつであっても仮数が000000 なら表現する値は 0 である。正規化数か非正規化数かの指定は演算器のオペ コードで行ない、データ自体は自分がどちらであるかを示すタグのようなもの はもたない。

この非正規化数の基本的な用途は積算である。つまり、積算の最終結果の指数 くらいの値を初めから足し込まれる変数にセットしておくことで、積算時の丸 め誤差が積算順序に依存しないようにするのである。

乗算器は通常非正規化数を扱う必要はないが、倍精度乗算のための部分積の計 算では非正規化数が入力に現れる。仮数の途中を切り出してくるからである。 このため、乗算器でも非正規化数を入出力ともにサポートする。通常の正規化 数同士の乗算では、結果のシフトは1または0ビットビットだが、非正規化数の 乗算ではもしも結果を正規化しようとするとフルサイズのシフタが必要になる。 これは回路規模に響くので、入力のどちらかが非正規化数ならば出力も自動的 に非正規数になるものとする。入力の両方が正規化数の場合に結果を非正規化 数にすることは可能である。

0、無限大等は以下のように表現する。

0 は指数 0

無限大は指数 all 1 (短語で 0x7FFFFFFFF, 0xFFFFFFFFF)

無限大と0の掛け算の結果は 0とする。

5.2. 乗算器

浮動小数点乗算器では以下の手順で乗算を行う。

5.2.1. 仮数の切り出し

短語の場合には無関係だが、長語の場合には部分積を求めるために 仮数を切り出す。これは、以下のように行う。

60 bit の仮数が以下の形を持っていたとする。以下、数字一つが2進数1ビッ トを表す。0/1 でないのは 位置を示しているからである。

   012345678911234567892123456789312345678941234567895123456789
   
シフトしない場合には、これはとりあえずこのままである。但し、入力が正規 化表現の時にはここで上に1を補う。そうでなければ 0 を補う。つまり、シフ トしない時にはこのステージの出力は必ず61ビットとなる。

   x012345678911234567892123456789312345678941234567895123456789
こんなふう。それから25ビットまたは 50ビットのシフトを行う。つまり25ビッ トシフトなら

   x012345678911234567892123456789312345678941234567895123456789
   4567893123456789412345678951234567890000000000000000000000000
                                       |                       |
                                       |------25 個0-----------|
50ビットシフトなら

   x012345678911234567892123456789312345678941234567895123456789
   9512345678900000000000000000000000000000000000000000000000000
              |                                                |
              |--------------------- 50 個0--------------------|
というふうになる。仮数を持ち上げた分指数は引く必要がある。これは 単純に 25 または 50 を引き、負になったら 0 にする。

制御コードは以下のもの

   SHIFT50A   ポートAの仮数を50ビット上にシフト
   SHIFT25B   ポートBの仮数を25ビット上にシフト
   SHIFT50B   ポートBの仮数を50ビット上にシフト
   NORMALA    ポートAの入力を正規化数とみなす
   NORMALB    ポートBの入力を正規化数とみなす

5.2.2. 仮数の丸め

パラメータで指定があれば、仮数を 25 ビットで丸める。前のステージから の 61 ビット出力の25ビット目

   x012345678911234567892123456789312345678941234567895123456789
                           |
                           ここ
を、

  1. もしもそれ以下のビットが全て 0 ならばそのまま
  2. それ以外の場合、つまりそれ以下のビットが1つでも 0 でなければ、この
位置を 1 にする。

制御コードは以下のもの

   ROUNDA     ポートAの仮数を(シフト後)25ビットに丸める
   ROUND50A   ポートAの仮数を(シフト後)50ビットに丸める
   ROUNDB     ポートBの仮数を(シフト後)25ビットに丸める

5.2.3. 仮数乗算

仮数の乗算を行う。入力は25ビットで、結果は 50 ビットになる。

5.2.4. 仮数の後処理

5.2.4.1. 正規化する場合

正規化する場合には、MSB が 0 なら1ビット左論理シフトして、指数は結果の 指数から 1 引く。

5.2.4.2. 正規しない場合

正規化しない場合には、無条件に 1ビット右論理シフトして、指数は結果の 指数に 1 を足す。この時に、 LSB は切り捨てられるのではなく、下に延びる。 出力の仮数は 60ビットなのでこれが可能である。

5.2.4.3. 丸め

結果を丸める場合には、上から24ビットに対して、入力の丸めと同様に、

  1. もしもそれ以下のビットが全て 0 ならばそのまま
  2. それ以外の場合、つまりそれ以下のビットが1つでも 0 でなければ、この
位置を 1 にする。

という処理を行う。これは、上のシフトを行った後で行う。 制御コードは以下のもの

   ROUND      出力を丸める
   NORMALO    出力を正規化する

5.2.5. 指数の処理

指数は入力の指数を足して、 0x3FE を引く。上の仮数による調整を行ったあ とで、オーバーフローしていたら 0x7ff、アンダーフローしていたら 0 にす る。但し、入力の指数のどちらかが 0x7ff の時にはそのままとし、そうでな くてどちらかが 0 であれば 0 とする。 また、仮数が0になった場合も指数を 0 とする。ただし、この場合も 入力の指数のどちらかが 0x7ff の時にはそのまま 0x7ff である。

5.3. 加減算器

浮動小数点加減算は以下のような手順で行う。

2つの入力をin1, in2 と書くことにする。in1 の指数、符号と仮数をそれぞ れ exp1, sign1, mantissa1 と書き、in2 についても同様とする。

最初に、 減算であれば sign2 を反転しておく。また、入力が正規化数であれ ば乗算の時と同様に仮数 MSB の上に1を補う。そうでなければ 0 を補う。

次に指数が小さいほうの仮数をシフトする。シフタは1つなので、実際には、

  1. まず exp1 と exp2 のどちらが大きいか判定し、
  2. 指数が大きいほうと小さいほうをの仮数を入れ替え
  3. 指数が小さいほうの仮数を指数の差だけ右論理シフトする

という操作になる。仮数を m2[0:60] (m2[60]が MSB)というふうに書いた時に、 シフト量 s = exp1 - exp2 を使って、シフト後の m2 は以下のように書ける

 m2new[i]=0  if i > 60 - s
 m2new[i]=m2[i+s] if 60-s >=i>0
 m2new[0]=m2[s] if m2[j]=0 for all j<s
 m2new[0]=1     if m2[j]=1 for any j<s
つまり、LSB の値は、シフトアウトしたものが全て 0 でなければ強制的に 1 にされる。

これを mantissa1 に加える。 sign1 と sign2 が違えば減算になる。この結 果は桁上がりも含めて63ビットの符号つき整数である。これを、まず符号と62ビッ トの絶対値に分ける。結果が正であれば、出力の符号が入力1(スワップされていれば2)の符号、負であればそれをを反転したものになる。

プライオリティエンコーダで最上位の1の位置を決める。これがLSBなら0、MSB なら61が出力になるものとする。この値を p とする。

出力を正規化しないというパラメータが指定されている場合、 p が 59 以下 ならば実際にシフトの必要はない。この場合には仮数のシフトは発生せず(シ フト量sは 0 であり)、出 力の指数は exp1 のままになる。但し、 p が 60または 61 の場合、非正規化 数になるように結果のシフトをする必要がある。この場合、結果を右論理シフ トする。シフト量 s は p-59 であり、その分指数を増やす。

出力を正規化する場合、シフト量は p-60 (正なら右論理シフト、負なら左論 理シフト)になる。

以上をまとめると、シフタの動作は入力を min[0:60],出力をmout[0:60]シフ ト量を s(正の時右シフト)として以下のようになる

 mout[i]=0        if i>60-s
 mout[i]=min[i+s] if 60-s >=i>0
 mout[i]=0        if 0< i< -s 
 mout[0]=min[s]   if m2[j]=0 for all 0<=j<s
 mout[0]=1       if m2[j]=1 for any 0<=j<s
指数は常に exp1 に s を加えることになる。この結果、オーバーフローが起 これば指数を 0x7ff に、アンダーフローが起これば指数を 0 にする。

さらに、結果を 25 ビットに丸めるというパラメータが指定されていれば、 mout[0:35]が全て0でなければ mout[36] を 1 にする。同時に mout[0:35] は 0 にする。

最終的な結果の仮数は mout[0:59] になる。これからわかるように mout[60]は使われないので、シフ タはこのビットを出力する必要はない。

上の演算手順から、以下のような制御線があることになる。

   NORMALA    ポートAの入力を正規化数とみなす
   NORMALB    ポートBの入力を正規化数とみなす
   SIGNB      B の符号を反転する(減算)
   ROUND      出力を25ビットに丸める
   NORMALO    出力を正規化する

5.4. 整数 ALU

これは演算手順というほどのものはない。命令コードは一応以下の割り当てにする。

 opcode   operation 
 0x0      A+B
 0x1      A-B
 0x2      A+1
 0x3      A-1
 0x4      not A
 0x5      A and B
 0x6      A or B
 0x7      A xor B
 0x8      max (A,B)
 0x9      min (A,B)
 0xA      A
 0xB      B
 0xC      A lshiftl B
 0xD      A lshiftr B
 0xE      A bshiftl B
 0xF      A bshiftr B
 0x10     logical not A
 0x1F     immidiate
 
なお、命令コード 4,5,6,7 の論理演算は全てビット毎である。

この他、 UNSIGNED 指定ビットがある。これは以下のオペレーションに影響する。

 opcode   operation 
 0x8      max (A,B)
 0x9      min (A,B)
 0xC      A lshiftr B
すなわち、 大小比較は、 SIGNED の場合には2の補数として行う。UNSIGNED ならば絶対値の比較になる。実装は、73ビットに符号拡張した減算を行って、 MSBを見るのが簡単である。SIGNED の時には符号拡張し、 UNSIGNED の時には しない。

右論理シフトの場合には符号拡張が起こるので、シフト前に最上位ビットが 1 で unsigned でなかった時ににはシフトして空いたところには 1 が埋められ る。それ以外の場合は論理シフトでは 0 が入る。

以下の命令では演算結果が正の時(UNSIGNEDの時には73ビット に拡張した MSBを見て)にフラグビットがセットされる。これらの命令では、 演算結果には UNSIGNED かどうかは影響しないが、フラグには影響することになる。

 opcode   operation 
 0x0      A+B
 0x1      A-B
 0x2      A+1
 0x3      A-1
また、それ以外の命令では、結果が all 0 の時にフラグがセットされる。

これらは UNSIGNED ビットに影響されない。

5.4.1. シフト命令の動作詳細

バレルシフト、論理シフトのどちらも、シフト量が語長を超える場合の動作を 規定しておく必要がある。

右シフトと左シフトで別命令なので、シフト量は常に絶対値として解釈される。 シフト量の最大値は71 なので、シフト量指定の 8 ビットより上は単に無視さ れる。72から 127までのシフト量が指定された場合の動作はバレルシフトと論 理シフトで異なり、

となる。

6. 命令セット定義

命令は以下の種類に分かれる。

PE 命令は各 PE に放送される。これは ISU を通る。それ以外の命令は全て IDP のデータパケットとして投入される。IDP 命令はIDP を通って BM やそれ 以外の PE 固有でないチップ内レジスタにアクセスする命令、 RRN 命令は RRN の動作を指定する命令である。

以下、 PE 命令、それ以外の順番で 命令フォーマットと動作を記述する。

6.1. PE 命令

PE 命令は基本的に水平型マイクロコードであり、 PE の全てのユニットにつ いてその動作を記述する。具体的には、命令自体の記述としてループ長 (4 を 越えてはいけない)があり、それに各ユニットの制御コードが続く。

なお、ベクトル命令である関係上、制御コードの遅延については BB 内の制御 ロジックで処理するものとする。つまり、投入される PE 命令は水平型マイク ロコードといっても論理的に同じ命令のフィールドが記述され、メモリ読み出 し、演算器制御、メモリ書き込みといった一連の動作に必要な遅延は BB のな かでハードウェア的に実現される。

なお、ループ長は、レジスタ、メモリ(マスクレジスタ含む)への書き込みを抑制するた めにのみ用いられる。

PE 命令は以下のフィールドからなる。これらが MSB からつめて入る。以下の サブセクションで順番に詳細を述べる。最後に形式をまとめる。

6.1.1. ループ長(LL)

LL フィールドはベクトル命令の繰り返し数を指定する。今回の実装ではフィー ルド長は 3 ビットで、最大値は 4 とする。それ以上を指定した時の動作は保 証しない。0 の時には実効的の NOP (no operation) となる。

6.1.2. M レジスタ制御(MRC)

MRC フィールドは以下の指定を行う。

 IMR[0:2] 書き込み制御を  M レジスタのどれから取るか。 0 は ALL 1
 OMR[0:2] 演算器の出力を M レジスタのどれに書くか。 0 は 書かない
 IFSEL    FADD と IALU のどちらのフラグ出力を取るか
少しわかりにくいが、M レジスタの出力セレクトが IMR である。これによ る書き込み指定は、Mレジスタ自身を含めて全てのストレージ書き込みに適用 される(他の指定との AND)になる。

合計7ビット。

6.1.3. T レジスタ制御

T レジスタの制御コードは以下の通り

  WRITE       書き込むかどうか。 1 なら書き込む。
  SHORTSTOP   書き込み(入力)データをそのまま出力に回す。
  ISEL[0:1]   入力セレクト
              00: FMUL
              01: FADDSUB/IALU
              10: BM
合計4ビット。

MRC の項で述べたように、マスクレジスタは MRC で指定されたものが適用さ れる。また、アドレス初期値は読み出し、書き込みともに 必ず 0 なので指定の必要はない。

なお、 shorstop 動作の時にはマスクレジスタ指定は無視され、マスクレジス タの指定にかかわらず前の命令での T レジスタ入力ポートへの入力データが そのまま出力ポートにでる。

6.1.4. アドレスに関する規約

レジスタファイルのアドレス指定は全て短語アドレスで行う。長語アクセスの 時には LSB は無視される(non-aligned access はサポートしない)。これはロー カルメモリ、放送メモリでも同様である。

6.1.5. レジスタファイル制御(RFC)

レジスタファイルの制御コードは以下の通り

  WRITE       書き込むかどうか。 1 なら書き込む。
  ISEL[0:1]   入力セレクト
              00: FMUL
              01: FADDSUB/IALU
              10: BM
  WADR[0:5]   書き込みアドレス初期値
  WADRI       書き込みアドレスをインクリメントする(1)/しない
  WWL         書き込みワード長 1:長語、 0:短語
  RADRA[0:5]  読み出しAアドレス初期値
  RADRIA      読み出しAアドレスをインクリメントする(1)/しない
  RWLA        読み出しAワード長 1:長語、 0:短語
  RADRB[0:5]  読み出しBアドレス初期値
  RADRIB      読み出しBアドレスをインクリメントする(1)/しない
  RWLB        読み出しBワード長 1:長語、 0:短語
  
合計 27 ビット。

6.1.6. ローカルメモリ制御(LMC)

ローカルメモリの制御コードは以下の通り

  WRITE       書き込むかどうか。 1 なら書き込む。
  ISEL[0:1]   入力セレクト
              00: FMUL
              01: FADDSUB/IALU
              10: BM
  ADR[0:8]    アドレス初期値
  ADRI[0:3]   アドレスインクリメントの値
  TREGADR     アドレスを TREG から取る
  WL          ワード長 1:長語、 0:短語
書き込みがある命令のあとの2命令は、読み出したデータは保証されない。 ADRI は1の時に連続アクセスになる、つまり長語ならアドレス増分は ADRI で 指定した値の2倍になるものとする。

これは 18 ビット。

6.1.7. FMUL 制御(FMC)

浮動小数点乗算器の制御コードは以下の通り。

   SHIFT50A   ポートAの仮数を50ビット上にシフト
   ROUND50A   ポートAの仮数を(シフト後)50ビットに丸める
   ROUNDA     ポートAの仮数を(シフト後)25ビットに丸める
   NORMALA    ポートAの入力を正規化数とみなす
   SHIFT25B   ポートBの仮数を25ビット上にシフト
   SHIFT50B   ポートBの仮数を50ビット上にシフト
   ROUNDB     ポートBの仮数を(シフト後)25ビットに丸める
   NORMALB    ポートBの入力を正規化数とみなす
   ROUND      出力を丸める
   NORMALO    出力を正規化する
   ISELA[0:1] Aポート入力セレクト
              00: レジスタファイル A ポート
              01: レジスタファイル B ポート
              10: T レジスタ
              11: ローカルメモリ
   ISELB[0:1] Bポート入力セレクト
              00: レジスタファイル A ポート
              01: レジスタファイル B ポート
              10: T レジスタ
              11: ローカルメモリ
14 ビット。

6.1.8. FADDSUB 制御

浮動小数点加減算器の制御コードは以下の通り。

   NORMALA    ポートAの入力を正規化数とみなす
   NORMALB    ポートBの入力を正規化数とみなす
   SIGNB      B の符号を反転する(減算)
   ROUND      出力を25ビットに丸める
   NORMALO    出力を正規化する
   ISELA[0:2]  Aポート入力セレクト
               000: レジスタファイル A ポート
               001: レジスタファイル B ポート
               010: T レジスタ
               011: ローカルメモリ
               100: PE 番号(固定)
               101: BM 番号(固定)
               110: 乗算器フィードバック
               111: 未定義
   ISELB[0:1]  Bポート入力セレクト
               00: レジスタファイル A ポート
               01: レジスタファイル B ポート
               10: T レジスタ
               11: ローカルメモリ
10 ビット。

FADDSUB はフラグ出力を持つ。これは、演算結果が正である時にセットされる (符号ビットを反転したものがそのまま使われる)。

ISELA の乗算器フィードバックは直前の乗算器の演算結果がそのまま入る。

フィードバックパスの場合には、マスクやベクトル長とは無関係に必ず 前の命令での乗算器の4サイクル分の出力結果がそのまま加算器の入力となる。

6.1.9. IALU 制御

整数 ALU の制御コードは以下の通り

   IALUOP[0:4] ALU 自体の命令コード
   UNSIGNED    符号なし演算を指定(1の時に)
6 ビット。

フラグ生成は以下のルールに従う

  演算が A-B, A+B, A+1, A-1  の時: 結果が正ならフラグがセットされる
  それ以外の時: 結果が all 0 ならフラグがセットされる

6.1.10. FADDSUB/ALU 出力セレクト

FADDSUB と IALU の出力はどちらか一方だけがメモリ等のマルチプレクサに入 るという仕様なので、まず手前で選ぶ必要がる。これをこのフィールドで指定 する。

   FSEL        出力選択。1ならFADDSUB の出力を取る。 0 なら IALU

6.1.11. BM 制御(BMC)

BMの制御コードは以下の通り

  WRITE       書き込むかどうか。 1 なら書き込む。
  ADR[0:10]   アドレス初期値
  PEADR[0:4]  BM書き込みの時にアクセスする PE 番号
  WL          ワード長 1:長語、 0:短語
書き込みがある命令のあとの2命令は、読み出しデータは保証されない。

これは 18 ビット。

6.2. 命令コードの長さ

とりあえず全てまとめると以下の通り。

 ループ長              3
 M レジスタ制御        7
 T レジスタ制御        4
 レジスタファイル制御 27 
 ローカルメモリ制御   18
 FMUL 制御            14
 FADDSUB 制御         10
 IALU 制御             6
 FADDSUB/IALU選択      1
 BM 制御              18
 合計                108
これが全てそのまま送りこまれる。

6.3. IDP/BM 命令

IDP 命令(データパケット)は以下の形式を取る:

先頭ワード (72ビットワード)はパラメータ指定等であり、 その後に先頭ワードによって指定された語数のデータが続く。

先頭ワードの形式は以下の通り

   LEN[0:7]   データ語数
   ADDR[0:12] BM の先頭アドレス
   BBN[0:4]   BB 番号の指定
   BBNM[0:4]  番号のマスク
   SEQ[0]     シーケンシャルライトフラグ
合計32ビット。

これを MSB からつめる。 下に 40ビットくらいあまるけど未使用。

LEN は長語単位の語数指定であり、 0 は 256 語と解釈される。

BBN は実際に書く BB の番号を指定する。放送やマルチキャストを可能にする ために、 BBNM で指定されたビット位置だけを比較し、BBNM が0であるビット 位置は無視する。

SEQ は同一データを放送(またはマルチキャスト)するか、 BB 毎に違うデータ を送るかを制御する。 SEQ=0 の時は放送である。 SEQ=1 の時にはLEN で指定 された語数のデータをアクティブな(下の放送ブロックマスクレジスタがセッ トされていない) BB の数だけ送り、送られたものが順番に BB0 から書かれる。 この時には BBN, BBNM は無視される。つまり、データパケットは以下のよう になる

 0     パケットヘッダ
 1     BB0 のアドレス ADDR のデータ
 2     BB0:ADDR+1
 ....
 LEN   BB0:ADDR+LEN-1
 LEN+1 BB1:ADDR
 ....
となり、パケットの総語数は (有効なBBの数) LEN + 1 となる。

メモリは 1024ワードであるので、

  0x000-0x7ff    放送メモリ
  0x800-0xfff    放送ブロック制御レジスタ
  0x1000-0x17ff  RRN 制御コマンドレジスタ
  0x1800-0x1fff  未定義
というメモリマップにしてアドレスの上位ビットでメモリとそれ以外を区別す る。放送ブロック制御レジスタは以下の通り

  0x800  ブロックマスクレジスタ (BMR)
  0x802  エラーステータスクリア。データ長は 1 だが無視
  
ブロックマスクレジスタはLSB からの各ビットが BB0 から BBn (n は実装依 存。今回は 16) の状態を制御する。対応するビットが1にセットされると、 縮約モードの時には RRN 命令が無視され、出力の OV がでない。また、 IDP SEQ モードの時に書き込みがスキップされる。

6.4. RRN 命令

RRN 命令は、 IDP データパケットのアドレス 0x1000 への書き込みとして指定 される。命令のフィールドは以下の通り。

   ADR[0:12]   アドレス初期値
   N  [0:7]    語数
   BBADR[0:4]  アクセスする BB 番号
   REDUC       縮約モードかどうか。 1 なら縮約、 0 なら PE 選択。
   WL          ワード長 1:長語、 0:短語
   FSEL        出力選択。1ならFADDSUB の出力を取る。 0 なら IALU
   NORMALA     ポートAの入力を正規化数とみなす
   NORMALB     ポートBの入力を正規化数とみなす
   SIGNB       B の符号を反転する(減算)
   ROUND       出力を25ビットに丸める
   NORMALO     出力を正規化する
   IALUOP[0:4] ALU 自体の命令コード
   UNSIGNED    符号なし演算を指定(1の時に)
   ODPOE       ODP から出力する
   SREGEN      ステータスレジスタに書き込む
      
これを MSB から詰め込む。

メモリは 1024長語(2048短語)であるので、

  0x000-0x7ff    放送メモリ
  0x800-0xfff    放送ブロックステータスレジスタ
  0x1000-0x1fff  未定義
となる。ステータスレジスタは

  0x800 ブロックマスクレジスタ
  0x802 エラーステータスレジスタ
        ビット位置  0: IDP パリティエラー
                    1: ISU パリティエラー
もうちょっとなんかいるかもしれない。

N は語数指定であり、 0 は 256 語と解釈される。

なお、非縮約モードが指定された時にはブロックマスクレジスタは無視される。

7. チップ I/O 定義

7.1. クロック入力

クロック CLK はベースクロック。

7.2. 分周クロック出力

ISU 入力で4分周したクロック信号が入るが、これがそのままでるもの。 RRN の分周クロックはこれを基準にする。

7.3. リセット入力

リセット RST は、

をクリアする。さらに、入力シンクロナイザを再同期させる。

それ以外はそのまま。

7.4. IDP モード指定

IDPモード指定 IDPMODE0 IDPMODE1

 IDPMODE0 IDPMODE1    意味
    0        0        9ビット毎にクロック
    0        1        18ビット毎にクロック (72-79 は 8 ビットにクロック)
    1        0        36ビット毎にクロック (72-79 は 8 ビットにクロック)
    1        1        未使用

7.5. エラーステータス出力

チップのエラーステータス出力は、基本的は各 BB のエラーステータスの OR をとったものと、入力同期エラーの2種類がでる。定義されているものは

 ISPERR   ISP の入力パリティエラー
 IDPERR   IDP の入力パリティエラー
 PHASERRR ISP/IDP の入力フェーズエラー

7.6. ISP

   ISCLK[0:3]    入力ソースクロック
   ISDATA[0:31]  入力データ
   ISPPHASE[0:3] フェーズ信号
ISDATAを4クロック分くっつけた後のものを IS[0:127] と呼ぶ。 これは 9 ビット毎に1ビットパリティを持つ。パリティは 10 ビット目、つま り IS[10n] になる。

4サイクルのデータは、下からくるものとする。つまり、

 Cycle 0  IS[0:31]
 Cycle 1  IS[32:63]
 Cycle 2  IS[64:95]
 Cycle 3  IS[96:127]
の順番でくる。

7.7. IDP

   IDCLK[0:8]   入力ソースクロック
   IDDATA[0:79] 入力データ 
   IDPPHASE[0:8] フェーズ信号
   DS           データストローブ
   DSCLK        データストローブクロック

7.8. ODP

   ODCLK[0:2]   出力ソースクロック
   ODDATA[0:20] 出力データ 

7.9. チップ状態表示

チップが何をしているかが目でわかるものをいろいろつける。

が基本なので、それぞれについて、「作動中」を示す出力ピンをつける。

  IDPSTATUS IDP からデータパケットが来ている
  ISPSTATUS ISP から NOP でない命令が来ている
  DOPSTATUS DOP から データを出している

  
これは、非同期動作でかまわない。システムクロックと同期したりする必要は 全くない。

この他に、各 PE のレジスタを直接表示する仕掛けをつける。具体的には、

    SREGEN=1
で指定された出力命令で出力ポートに出る72ビットのうちLSB 8 ビットをその まま表示する。

   PEOUT[0:7] ステータス表示
これらは、非同期動作でかまわない。システムクロックと同期したりする必要は 全くない。

8. メモ

8.1. 統計情報等の収集について

ソフトウェアの効率評価等のためには、実行効率をハードウェア的に測定する ような仕掛けが欲しいような気もする。具体的には、例えば以下のようなもの である。

こういうのをハードウェアで常時モニタするのはそれほど面倒なわけではない。 それ用のカウンタを準備して、そこから読めるようなパスをつけるだけだから である。

しかし、今回は、少しでも面倒なことは、それが

場合にはつけないことにしたいという基本方針(なんてものがいつのまに出来 たのか知らないけど)に従って、つけない。

ソフトウェアエミュレーションは、要するに LM か GRF にこれらのカウンタ をとっておいて、コンパイラかアセンブラが命令毎、あるいはマスクレジスタ が変わる毎に必要な数を加算すればよい。

8.2. IALU 即値

2004/8/30 現在での命令セットでは、 IALU に即値をオペランドにとる命令が ない。 +1 命令とシフト命令はあるから、 log N ステップで任意の数を置け るからこれでいいかな?繰り返し使う数はレジスタに置くしかないし。

8.3. IDP ストローブをどうするか?

2005/5/26

とりあえず2サイクル毎ということで。

9. 名前

当初使っていた VPM という名前は今一つであるというのは確か。今まで提案された中でもっともインパクト のある名前は

SING, for SING is Not GRAPE

であるのはなかなか疑いをいれないところ。とりあえずこれを開発コードネー ム(HARP とか相当)としては採用する。

同工異曲なものとしては King, Ming, Ring, Wing とかが可能だけど、まあ、 このなかでは Sing が美しいですね。うむ。

もうちょっとましな名前募集中。

10. その他の情報

10.1. この仕様書でカバーしないものには以下がある

これらはハードウェア設計には関係するが通常のユーザーが見る必要はないの で仕様書に含めない。別ドキュメントを用意する。

アセンブラは別ドキュメント、コンパイラドキュメントは準備中である。

11. 略語定義

ALU Arithmetic and Logic Unit 算術・論理演算器

BM: broadcast memory 放送メモリ

HT HyperTransport

IDP Input Data Port

ISP Instruction Stream Port

ODP Output Data Port