減算型でいく。基数 4 の SRT でいってみたいのだが、とりあえず基数 2 で。
サイクル数は 1 + 18 ( iteration ) + 2 = 21 サイクルを目標に。
ゲートは 10000 くらいでやりたいところ。
Weitek 3364 は 4 進 SRT で 165,000 ゲートの 3.9 % を、
TI 8847は 8b seed Goldschmidt 法で 180,000 ゲートの 5.0 % を使用している。
乗算型除算器の方が、ゲートを食う分だけ速いらしい。
基数 2 の SRT 法は、適当に修正された被除数から出発して、部分剰余の絶対 値を常に 0.25 以上にするようなアルゴリズムである。 これによって、除数と被除数のビット数に関わらず、常に一定のビットを参照 するだけで商を求めることができる。 とりあえず 通常の SRT で作ってみることにする。
単精度も標的にしつつ設計してみよう。
module fdiv_split(in,isdouble,s,e,upf); input [63:0] in; input isdouble; output s; // sign output [10:0] e; // biased exp ( zero adjusted ) output [52:0] upf; // unpacked mantissa
単精度か倍精度かで主に判断する、が、ただ分割するだけではなく
という作業を行う。
module fdiv_encode(upf,enc,isfzero); input [52:0] upf; output [5:0] enc; output isfzero;
module fdiv_presft(upf,enc,n); input [52:0] upf; input [5:0] enc; output [53:0] n;
module fdiv_qselect_top(nb,na,po,mo,zpo,zno); input [53:0] nb,na; // divisor , dividend (initial partial remainder) output [53:0] po,mo; // partial remainder output [54:0] zpo,zno; // on the fly conversion
但し、最初、商は 1 で固定である。
module fdiv_premux(in0,in1,start,out); input [380:0] in0,in1; input start; output [380:0] out;
実行時間の大部分は商を求める繰り返し部分だが、そこに投入する入力を選択する。
module fdiv_qselect(nb,pi,mi,zpi,zni,po,mo,zpo,zno); input [53:0] nb; // divisor input [53:0] pi,mi; // plusone , minusone input [54:0] zpi,zni; // zpi[54],zni[54] is dummy output [53:0] po,mo; // partial remainder , output output [54:0] zpo,zno; // on-the-fly conversion
module fdiv_exception(a,b,isdouble,out,flags,istrue); input [63:0] a,b; input isdouble; output [63:0] out; output [4:0] flags; // V,O,Z,U,I output istrue; // output is TRUE or Don't care
module fdiv_resultinf(rmode,sc,ovi); input [1:0] rmode; // roundmode input sc; // sign of result output ovi;
module fdiv_adjq(p54,m54,zp54,zn54,cancel,adjq); input [53:0] p54,m54; input [54:0] zp54,zn54; output cancel; // 1bit cancellation of quotient digit output [54:0] adjq; // with roundbit and stickybit
module fdiv_adje(ea,eb,enca,encb,cancel,isdouble,adje,sftbit); input [10:0] ea,eb; input [5:0] enca,encb; input cancel; input isdouble; output [12:0] adje; output [12:0] sftbit;
module fdiv_postsft(adjq,sftbit,sft); input [54:0] adjq; // 53b + r + s input [12:0] sftbit; output [54:0] sft;
ここでは精度については気にせず、単に右シフトを行って 55 ビットのフォー マットに収まるようにしている。
module fdiv_round(sftq,s,isdouble,rmode,roundq,carry,iex); input [54:0] sftq; input s; // sign input isdouble; input [1:0] rmode; output [52:0] roundq; output carry; output iex; // inexact exception flag
但し、このモジュールは内部に丸めの純粋なロジックモジュール ( fdiv_roundlogic ) を持っている。
module fdiv_roundlogic(sib,lsb,rob,stb,rmode,pone,iex); input sib,lsb,rob,stb; input [1:0] rmode; // 00:RN , 01:RZ , 10:RP , 11:RM output pone; output iex; // to inexact exception flag
module fdiv_adjall(adje,roundq,carry,isdouble,ovi,oute,outf,flags); input [12:0] adje; input [52:0] roundq; // roundq[52] is dummy // rounded , but uneconomized quotient input carry; // carry by rounding input isdouble; input ovi; // overflow-infinity output [10:0] oute; output [52:0] outf; // uneconomized format output [4:0] flags;
module fdiv_rflush(s,adje,roundq,isdouble,rflush); input s; // sign input [10:0] adje; // exp input [52:0] roundq; // roundq [52] is dummy input isdouble; output [63:0] rflush;
module fdiv_mux(normsef,normflags,excesef,exceflags,isexcetrue,mux,muxflags); input [63:0] normsef,excesef; // sign , exp , mantissa input [4:0] normflags,exceflags; input isexcetrue; output [63:0] mux; output [4:0] muxflags;
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
fdiv_split | 198 | 1.866 | 2 | 396 |
fdiv_encode | 365 | 6.988 | 2 | 730 |
fdiv_presft | 842 | 4.368 | 2 | 1684 |
fdiv_qselect_top | 268 | 0.739 | 1 | 268 |
fdiv_exception | 716 | 6.755 | 1 | 716 |
fdiv_premux | 1183 | 2.426 | 1 | 1183 |
fdiv_qselect | 1894 | 5.284 | 1 | 1894 |
fdiv_resultinf | 4 | 0.733 | 1 | 4 |
fdiv_adjq | 1103 | 10.406 | 1 | 1103 |
fdiv_adje | 831 | 9.367 | 1 | 831 |
fdiv_postsft | 2345 | 5.135 | 1 | 2345 |
fdiv_round | 464 | 8.860 | 1 | 464 |
fdiv_adjall | 283 | 6.981 | 1 | 283 |
fdiv_rflush | 170 | 1.882 | 1 | 170 |
fdiv_mux | 217 | 2.535 | 1 | 217 |
ここで特殊数とは、SNaN と QNaN と Inf と 0 を指し、入力に対してこれら を排他的にアサートされる 4 ビットで入力の状態を決定する。全てのビット が立っていなければ、それは通常の有限数を意味する。以下の仕様に基づいて 作る。
演算種類 | 結果 | 例外 |
---|---|---|
SNaN / SNaN SNaN / QNaN と QNaN / SNaN SNaN / 0 と 0 / SNaN SNaN / Inf と Inf / SNaN SNaN / W と W / SNaN Inf / Inf と 0 / 0 | QNaN | V |
QNaN / QNaN QNaN / 0 と 0 / QNaN QNaN / Inf と Inf / QNaN QNaN / W と W / QNaN | QNaN | - |
0 / Inf と W / Inf 0 / W | 符号付き 0 | - |
Inf / 0 と Inf / W | 符号付き Inf | - |
W / 0 | 符号付き Inf | Z |
W / W | ?(W,Inf,0) | ?(O,U,I) |
各ステージに分割したモジュールのインターフェースは以下の通り。
module fdiv_1(CLK,a,b,isdouble,rmode,start, fp,fm,fzp,fzn,fnb,fovi,frmode,fs,fea,feb,fenca,fencb, fisdouble,fexception,fexceflags,fisexcetrue,fstart); input CLK; input [63:0] a,b; input isdouble; input [1:0] rmode; input start; output [53:0] fp,fm; output [54:0] fzp,fzn; output [53:0] fnb; output fovi; output [1:0] frmode; output fs; output [10:0] fea,feb; output [5:0] fenca,fencb; output fisdouble; output [63:0] fexception; output [4:0] fexceflags; output fisexcetrue; output fstart;
module fdiv_2(CLK,fstart, fp,fm,fzp,fzn,fnb,fovi,frmode,fs,fea,feb,fenca,fencb, fisdouble,fexception,fexceflags,fisexcetrue, sp,sm,szp,szn,snb,sovi,srmode,ss,sea,seb,senca,sencb, sisdouble,sexception,sexceflags,sisexcetrue, dp,dm,dzp,dzn,dnb,dovi,drmode,ds,dea,deb,denca,dencb, disdouble,dexception,dexceflags,disexcetrue); input CLK; input fstart; input [53:0] fp,fm; input [54:0] fzp,fzn; input [53:0] fnb; input fovi; input [1:0] frmode; input fs; input [10:0] fea,feb; input [5:0] fenca,fencb; input fisdouble; input [63:0] fexception; input [4:0] fexceflags; input fisexcetrue; input [53:0] sp,sm; input [54:0] szp,szn; input [53:0] snb; input sovi; input [1:0] srmode; input ss; input [10:0] sea,seb; input [5:0] senca,sencb; input sisdouble; input [63:0] sexception; input [4:0] sexceflags; input sisexcetrue; output [53:0] dp,dm; output [54:0] dzp,dzn; output [53:0] dnb; output dovi; output [1:0] drmode; output ds; output [10:0] dea,deb; output [5:0] denca,dencb; output disdouble; output [63:0] dexception; output [4:0] dexceflags; output disexcetrue;
module fdiv_3(CLK, p,m,zp,zn,ovi,rmode,s,ea,eb,enca,encb, isdouble,exception,exceflags,isexcetrue, disdouble,ds,dadje,dsftq,dovi,drmode,dexception,dexceflags,disexcetrue); input CLK; input [53:0] p,m; input [54:0] zp,zn; /* input [53:0] nb; */ input ovi; input [1:0] rmode; input s; input [10:0] ea,eb; input [5:0] enca,encb; input isdouble; input [63:0] exception; input [4:0] exceflags; input isexcetrue; output disdouble; output ds; output [12:0] dadje; output [54:0] dsftq; output dovi; output [1:0] drmode; output [63:0] dexception; output [4:0] dexceflags; output disexcetrue; reg disdouble; reg ds; reg [12:0] dadje; reg [54:0] dsftq; reg dovi; reg [1:0] drmode; reg [63:0] dexception; reg [4:0] dexceflags; reg disexcetrue;
module fdiv_4( isdouble,s,adje,sftq,ovi,rmode,exception,exceflags,isexcetrue); out,flags); input isdouble; input s; input [12:0] adje; input [54:0] sftq; input ovi; input [1:0] rmode; input [63:0] exception; input [4:0] exceflags; input isexcetrue; output [63:0] out; output [4:0] flags;
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
fdiv_1 | 6245 | 12.252 | 1 | 6245 |
fdiv_2 | 1 | |||
fdiv_3 | 5236 | 15.357 | 1 | 5236 |
fdiv_4 | 1139 | 17.443 | 1 | 1139 |
最終ステージが少し時間がかかりすぎているので、除算前の処理を重くして、 負荷分散させてやることが必要である ( 19971225 )
module div_qselect(b,rsi,rci,zpi,zni,rso,rco,zpo,zno); input [31:0] b; // divisor input [31:0] rsi,rci; // sum/carry of partial remainder , input input [30:0] zpi,zni; // on-the-fly conversion output [31:0] rso,rco; // sum/carry of partial remainder , output output [31:0] zpo,zno;
キャリーセーブ表現の部分剰余 rsi , rci から商を判定して
を返す。
商の選択が少し変形していびつだが、範囲にちゃんと入るようになっている。
部分剰余 | 対応ビット列 | 商 | 対応ビッ ト列 |
---|---|---|---|
0 以上 | 0.11 0.10 0.01 0.00 | +1 | 01 |
-0.5 以上 0 未満 | 1.11 | 0 | 10 |
-0.5 未満 | 1.10 1.01 1.00 | -1 | 00 |
部分剰余のアルゴリズムは
これを表にすると
qi | 減数 B2 | LSBofCarry |
---|---|---|
+1 | ~B | 1 |
0 | 0 | 0 |
-1 | B | 0 |
となる。
また、on - the - fly 変換は具体的に以下の通り。
qi | ZPi | ZNi |
---|---|---|
+1 | { ZPi - 1 , 1 } | { ZPi - 1 , 0 } |
0 | { ZPi - 1 , 0 } | { ZNi - 1 , 1 } |
-1 | { ZNi - 1 , 1 } | { ZNi - 1 , 0 } |
モジュール名 | cost prim. | 時間 (ns) | 必要 数 | 小計 prim. |
---|---|---|---|---|
div_encode | 149 | 3.343 | 2 | 358 |
div_presft | 420 | 3.920 | 1 | 618 |
div_qselect_top | 163 | 0.739 | 1 | 163 |
div_qselect | 1141 | 5.373 | 1 | 1141 |
div_postsft | 491 | 3.732 | 1 | 491 |