浮点除法器硬件实现细节
我试图在硬件中实现一个32位浮点硬件分频器,我想知道是否可以得到任何关于不同algorithm之间权衡的build议?
我的浮点单元当前支持乘法和加法/减法,但是我不打算将它切换到融合的乘加(FMA)浮点体系结构,因为这是一个embedded式平台,我试图最小化面积使用。
很久很久以前,我遇到了这个简单易用的在这个时间段的军事FPU中使用的浮点/定点除法algorithm:
- 
input必须是无符号的,并移位,使得 x < y并且都在范围< 0.5 ; 1 >< 0.5 ; 1 >不要忘记存储 sh = shx - shy和原始符号的差别
- 
find f(通过迭代),所以y*f -> 1….在这之后x*f -> x/y是除法结果
- 
将 x*f移回sh并恢复结果符号(sig=sigx*sigy)x*f可以像这样容易地计算出来:z=1-y (x*f)=(x/y)=x*(1+z)*(1+z^2)*(1+z^4)*(1+z^8)*(1+z^16)...(1+z^2n)哪里 n = log2(num of fractional bits for fixed point, or mantisa bit size for floating point)
我在我的数字运算中使用这个divison,高级divison的C ++实现是这样的:
 fixnum fixnum::operator / (const fixnum &x) // return = this/x { fixnum u,v,w; int k=0,s; s=sig*x.sig; // compute result signum u=this[0]; u.sig=+1; v=x; v.sig=+1; w.one(); while (geq(v,w)) { v=v>>1; k++; } // shift input in range w=w>>1; while (geq(w,v)==1) { v=v<<1; k--; } w.div(u,v); // use divider block w=w>>k; // shift result back w.sig=s; // set signum return w; } 
这是在任何晶体pipe计数的时候开发的…所以你应该能够使用你的+和*单元进行压缩。 希望它可以帮助….
[edit1:]这里是我的浮点实现
 void arbnum::div(const arbnum &x,const arbnum &y,int acc) { // O(log(N)*(sqr+mul+inc)) ~ O(1.5*log(N)*(N^2)) // x<y = < 0.5 ; 1 > // x*f -> x/y , y*f -> 1 int i,nz; arbnum c,z,q; c=x; z.one(); z.sub(z,y); // z=1-y q=z; q.inci(); c.mul(c,q); // (x/y)'=x*(1+z) c._normalize(); nz=z.nfbits(); if (acc<=0) acc=(nz+c.nfbits())<<1; for (i=int_log2(acc);i>=0;i--) { // z.mul(z,z); z.sqr(z); nz<<=1; if (nz>acc) nz=acc; z._normalize(nz); q=z; q.inci(); c.mul(c,q); // (x/y)'=x*(1+z)*(1+z^2)*(1+z^4)*(1+z^8)*(1+z^16)... if (i) c._normalize(acc+nz); } c._normalize(acc); overflow(); c.sig=sig; *this=c; } 
编号是:
 DWORD *dat; int siz,exp,sig,bits; 
  dat[siz] :mantisa MSW = dat[0] 
  exp :mantisa的MSB的基数2指数 
  sig :mantisa的signum 
  bits :使用mantisa位来加速某些操作 
  a.inci() : a++ 
  a.zero a=0 
  a.one a=1 
  a.geq(x,y) :compare |x|,|y|  ,为|x|<|y|返回0  , 1 > 2 == a.add(x,y) : a=x+y 
  a.sub(x,y) : a=xy 
  a.mul(x,y) : a=x*y 
  a.sqr(x) : a=x*x 
  a.nfbits() :返回使用的小数位数( 00000100.00011100b -> 6 ) 
  a._normalize() :标准化数(尾数的MSB = 1) 
  a.overflow() :如果发现这个num是?.111111111111111111111111111111111111111111111b那么它回到?+1.0b 
  acc是期望的尾数位精度(我arbnum有无限的尾数精度位)