NI2フォーマット変換においてサポートするのは
の 6 つである。DLX の命令セットにもある。最終的には全 6 命令を 1 モジュー ルで行えるように設計したいが、さすがにカテゴリを分けないとやってられな いので 3 つに分ける。整数を I 、浮動小数点数を非整数 NI と書いて
の分類に基き、個々に設計していく。
なお、全体像としては、オペコードの下位 3 ビットと当該レジスタからのデー タ 64 ビットを入力として、64 ビットを出力するものとする。但し、64 ビッ トの入出力幅をフルに利用するのは倍精度のみで、それ以外は
と規定しておく。
更に、整数に関しては、全て符号付きで変換を行う。符号無しで扱いたいとき
にこの方法では 1 ビット欠損が出るが、そもそも DLX のアーキテクチャに符
号無しを明確に規定した変換命令が無いのが問題なのである。
DLX よ ORTHOGONALITY がないぞ! 浮動小数点のこともちっとは真面目に考えろ!
( チョーお怒りモード )
プロセッサ全体の動作を最低限確認できるように設計する。そのためフラグ等 は一切立てず、丸めも行わないで全て切り捨てている。
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
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
cvt_i2ni_complement | 408 | 4.624 | 1 | 408 |
cvt_i2ni_encode | 144 | 4.544 | 1 | 144 |
cvt_i2ni_shift | 396 | 3.498 | 1 | 396 |
cvt_i2ni_rflush | 137 | 1.801 | 1 | 137 |
i2ni の組み合わせ回路 | 1218 | 12.116 | 1 | 12 |
浮動小数点数→整数変換同様、とりあえずプロセッサ全体の動作を最低限確認 できるように設計する。そのためフラグ等は一切立てず、丸めも行わないで全 て切り捨てている。
というの不具合の解消に着手。ここでは他の演算器と違って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 ビット出力が得られるが、まだこの段階では
について全く考慮しておらず、これらはトップモジュールでのビット操作で解 決している。
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
cvt_ni2i_split | 166 | 2.605 | 1 | 166 |
cvt_ni2i_shift | 449 | 3.372 | 1 | 449 |
cvt_ni2i_complement | 384 | 4.635 | 1 | 384 |
とりあえずプロセッサ全体の動作を最低限確認できるように設計する。 そのためフラグ等は一切立てず、丸めも行わないで全て切り捨てている。
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 ビット出力が得られるが、まだこの段階では
について全く考慮しておらず、これらはトップモジュールでのビット操作で解 決している。
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
cvt_ni2i_split | 166 | 2.605 | 1 | 166 |
cvt_ni2i_shift | 449 | 3.372 | 1 | 449 |
cvt_ni2i_complement | 384 | 4.635 | 1 | 384 |