Converter Design

フォーマット変換


概要

NI2NIにバグ発見!デノーマル時のubeが調節されていない

NI2フォーマット変換においてサポートするのは

  1. 単精度から単精度 ( CVTF2D )
  2. 単精度から整数 ( CVTF2I )
  3. 倍精度から単精度 ( CVTD2F )
  4. 倍精度から整数 ( CVTD2I )
  5. 整数から単精度 ( CVTI2F )
  6. 整数から倍精度 ( CVTI2D )

の 6 つである。DLX の命令セットにもある。最終的には全 6 命令を 1 モジュー ルで行えるように設計したいが、さすがにカテゴリを分けないとやってられな いので 3 つに分ける。整数を I 、浮動小数点数を非整数 NI と書いて

  1. CVTI2NI ( 整数→浮動小数点数 )
  2. CVTNI2I ( 浮動小数点数→整数 )
  3. CVTNI2NI ( 浮動小数点数→浮動小数点数 )

の分類に基き、個々に設計していく。

なお、全体像としては、オペコードの下位 3 ビットと当該レジスタからのデー タ 64 ビットを入力として、64 ビットを出力するものとする。但し、64 ビッ トの入出力幅をフルに利用するのは倍精度のみで、それ以外は

と規定しておく。

更に、整数に関しては、全て符号付きで変換を行う。符号無しで扱いたいとき にこの方法では 1 ビット欠損が出るが、そもそも DLX のアーキテクチャに符 号無しを明確に規定した変換命令が無いのが問題なのである。
DLX よ ORTHOGONALITY がないぞ! 浮動小数点のこともちっとは真面目に考えろ! ( チョーお怒りモード )


整数から浮動小数点数への変換 ( CVTI2NI )

プロセッサ全体の動作を最低限確認できるように設計する。そのためフラグ等 は一切立てず、丸めも行わないで全て切り捨てている。

モジュール毎の動作

module cvt_i2ni_complement(in,comp);
        input [31:0] in;
        output [31:0] comp;

MSB を見て正負を判断し、出力は全て正数となる。単純な方法だがこれで十分 で、絶対値が最大の負数 ( MSB のみ 1 でそれ以外のビットは全て 0 ) の場 合でも、後々うまく変換できそう。

module cvt_i2ni_encode(comp,enc,iszero);
        input [31:0] comp;
        output [4:0] enc;
        output iszero;

入力の 32 ビットの LSB を整数の 1 の位とした固定小数点数で、何ビット右シ フトすれば値が正規化されるかをエンコードする。

module cvt_i2ni_shift(comp,enc,sft);
        input [31:0] comp; // comp[31] is DUMMY, never used
        input [4:0] enc;
        output [31:0] sft; // sft[1:0] is always 0

正規化かつ、けち表現されている値を出力する。

module cvt_i2ni_rflush(s,e,f,todouble,cvt);
    input s; // sign
    input [10:0] e; // exp
    input [31:0] f; // mantissa
    input todouble; // integer to Double or Single
    output [63:0] cvt; // converted value

基本部分 の合成結果 ( CVT_I2NI )

モジュール名cost prim.時間 (ns)必要 数 小計 prim.
cvt_i2ni_complement 4084.6241 408
cvt_i2ni_encode 1444.5441 144
cvt_i2ni_shift 3963.4981 396
cvt_i2ni_rflush 1371.8011 137
i2ni の組み合わせ回路121812.1161 12
no clock, opt area -high, opt timing -high にて合成
[ primitive cost × 必要数 ] で、
必要な primitive cost が計算できる。


浮動小数点数から整数への変換 ( CVTNI2I )

浮動小数点数→整数変換同様、とりあえずプロセッサ全体の動作を最低限確認 できるように設計する。そのためフラグ等は一切立てず、丸めも行わないで全 て切り捨てている。

というの不具合の解消に着手。ここでは他の演算器と違ってBefore Rounding でTininessを検出しているが、今度からこの方法に統一する。

モジュール毎の動作

module cvt_ni2i_split(in,fromdouble,s,e,f);
        input [63:0] in;
        input fromdouble; // double to integer operation
        output s; // sign 
        output [10:0] e; // biased exp
        output [51:0] f; // packed mantissa

64 ビットの入力に対して、倍精度浮動小数点数から整数への変換ならば、た だスルーするだけで、単精度からの場合は、下 32 ビットから適切に分解する。 ちなみに単精度分解の際、指数は右詰めで、仮数は左詰めである。

module cvt_ni2i_shift(upf,ube,sft);
        input [52:0] upf; // unpacked mantissa 
        // upf[20:0] is dummy , never used
        input [4:0] ube;  // unbiased exponent
        output [31:0] sft; 

module cvt_ni2i_complement(in,s,comp);
        input [31:0] in;
        input s; // signbit
        output [31:0] comp;

これで正しい符号つきの 32 ビット出力が得られるが、まだこの段階では

  1. 指数が負かどうか
  2. 指数が整数フォーマットに比べて大きいかどうか

について全く考慮しておらず、これらはトップモジュールでのビット操作で解 決している。

基本部分 の合成結果 ( CVT_NI2I )

モジュール名cost prim.時間 (ns)必要 数 小計 prim.
cvt_ni2i_split 1662.6051 166
cvt_ni2i_shift 4493.3721 449
cvt_ni2i_complement 3844.6351 384
no clock, opt area -high, opt timing -high にて合成
[ primitive cost × 必要数 ] で、
必要な primitive cost が計算できる。


浮動小数点数間の変換 ( CVTNI2NI )

とりあえずプロセッサ全体の動作を最低限確認できるように設計する。 そのためフラグ等は一切立てず、丸めも行わないで全て切り捨てている。

モジュール毎の動作

module cvt_ni2ni_split(in,fromdouble,s,e,f);
        input [63:0] in;
        input fromdouble; // double to integer operation
        output s; // sign 
        output [10:0] e; // biased exp
        output [51:0] f; // packed mantissa

64 ビットの入力に対して、倍精度浮動小数点数から整数への変換ならば、た だスルーするだけで、単精度からの場合は、下 32 ビットから適切に分解する。 ちなみに単精度分解の際、指数は右詰めで、仮数は左詰めである。

ちなみに fromdouble というのは tosingle と同じ

module cvt_ni2i_shift(upf,ube,sft);
        input [52:0] upf; // unpacked mantissa 
        // upf[20:0] is dummy , never used
        input [4:0] ube;  // unbiased exponent
        output [31:0] sft; 

module cvt_ni2i_complement(in,s,comp);
        input [31:0] in;
        input s; // signbit
        output [31:0] comp;

これで正しい符号つきの 32 ビット出力が得られるが、まだこの段階では

  1. 指数が負かどうか
  2. 指数が整数フォーマットに比べて大きいかどうか

について全く考慮しておらず、これらはトップモジュールでのビット操作で解 決している。

基本部分 の合成結果 ( CVT_NI2I )

モジュール名cost prim.時間 (ns)必要 数 小計 prim.
cvt_ni2i_split 1662.6051 166
cvt_ni2i_shift 4493.3721 449
cvt_ni2i_complement 3844.6351 384
no clock, opt area -high, opt timing -high にて合成
[ primitive cost × 必要数 ] で、
必要な primitive cost が計算できる。


一歩前へ[Back]
僕のホームへ[Home]
研究室のページへ[Amano Lab.]
Takahiro Kawaguchi kawaguti@aa.cs.keio.ac.jp
Last modified: Dec. 14, 1997