|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
背景
- h) i9 l" Z W1 l; Q* V% |5 s+ p5 A6 x9 X5 w
7 m8 } A$ I7 j0 ~1 ^ K
首先,我们要明确的是不管是什么数字,一切数字在计算机中都是采用二进制表示的,就算你是小数点数。所以,这些概念,我们一定要捋清楚。下面,我们马上就来看看。4 l9 i' f1 _( m5 {( }0 h
' ^2 |$ S; M) {" d% ]
, x+ V5 y6 `9 ~1 u/ p C
定点数的表示与计算# O! U k4 l4 a7 s8 ~* N
/ p( [) p8 G: s. z! n
, P6 D5 |, {$ C0 ~定点数具有三种表示的形式,原码、反码、以及补码。
( E) G. O& G% X, a
& [/ _. u* \, a; S% p: p- F+ i- E) J, ]6 K6 D7 e
) x$ b* l' q$ h, Y$ l0 F0 t7 D
018 P) _- U" ]" T3 X
. g; A- h1 z0 Y5 f7 V0 e
原码
6 M! `1 O/ H. \8 [; S
5 q% N$ i7 h' G7 u, _关于原码,例如二进制 0△110 表示+0.75;1△110表示的是-0.75.这一点很好理解,因为0.75*2^3(定点三位)=6 也就是二进制110.简单的说如何将小数转换为十进制数呢。利用matlab提供的整转二进制函数dec2bin很容易获得转换结果。即需要先将十进制小数乘以一个比例因子2^B-1,并进行四舍五入操作取整。转换函数的表达式子是:4 |7 j+ n2 Z% g/ [' W4 _# Z; }
/ c% l6 Z2 L/ K+ n
: N W. t0 C# k) m( K( c
9 q3 X2 o! H- o* D* a; f; n需要说明的是十进制的小数转换为二进制存在误差,其误差大小由二进制数的位数决定的。" _; s" i; k+ E6 x X
7 n9 y T) ?* o% `" Z% Y
x表示实际的数(一个浮点数), q表示它的Qn型定点小数(一个整数)。
& [0 \8 P$ D+ `; }# v* G6 o( V0 |! {
& O% Z7 r+ X. I2 C6 ]: i" t" L% w5 h+ E+ I) q$ s* G8 k
0 ]* p" P2 I4 K( Y; L! ~02
" C! m7 b2 w2 F j
9 L) t6 K3 z b) A2 L% a反码
. {$ ]# ?. n. o" f9 f% m6 T. {$ ^# b6 j
g8 Y4 n% v( l+ [' K5 u" o8 W正数的反码与原码相同,负数的反码为原码除符号位的所有位取反,及得到负数的反码。例如说,十进制的-0.75的二进制原码表示为x=1△110,其反码为1△001- [' [/ {2 y( _. _8 r" @. A
9 k, k2 R# ~ n% U
$ H$ y( p* p% R7 Z$ P q8 V
6 o* r) y* A. r& k03
+ p5 \9 T8 k3 C. S* O" B0 L" X2 M e2 n
补码% o! ~6 ]! S7 [. q F$ ]! ~# Y3 n
+ N) j# X' f% S8 r负数的补码就是在反码的最低位加1.补码最重要的特性就是将减法用加法运算实现。同样,将十进制数转换成补码形式的二进制数也可以用dec2bin函数实现。
$ m2 B7 t. Y9 o. N) a: W! |7 j+ A) i/ |
3 t" [0 T. y+ U1 e) u2 e( A, b
. {( Z. o* r8 |" d/ g我们用数学表达式总结一下如何将小数定点化
. W6 S* n8 M$ m( u1 y. W& }. \, {5 w' H/ p* G8 @
& J* z* N( Y: J. }( m# S( ^3 d. m3 D7 p- v, t( x. [
假设q1,q2,q3表达的值分别为x1,x2,x3
) L) u0 X+ \' h
f' M4 U0 @! {$ t6 `% \q3 = q1 + q2 若 x3 = x1 + x2; A. o* s6 b8 H8 R% j3 ~+ F2 }
+ d7 G; U. G- g
q3 = q1 - q2 若 x3 = x1 - x2) Y) v0 Q' i- w: S* y
8 @7 M( S, T' T% F% O' D1 yq3 = q1 * q2 / 2^n若 x3 = x1 * x27 O9 B, J2 ]3 ]; s6 g1 t7 w5 N! T
S- n) E( B2 W3 g) H6 r
q3 = q1 * 2^n / q2若 x3 = x1 / x2 \9 i" c% ` T- s
/ J) G6 m' s! r2 Q" m) C6 z+ ~对于加减法到比较简单,对于乘除法,我们对/ 2 ^ n和* 2^n可以简单的用移位来计算。所以定点小数的运算比浮点小数要快的多。
* z( H1 O! b) J! }3 [
- q0 l$ o' w& n1 i2 p& M9 Z
3 x7 e* P& E- L0 z% j
' j) _: d) `4 C' S8 ?9 S2 b' Z3 q经常有人问, FPGA里小数乘法怎么搞?
7 X8 v" J: N4 t* e. }. ^! N$ b$ ]! X$ Q. I
如果你乐意, 按照IEEE754标准做"浮点"型运算的ip当然最好(虽然面积上不太好).不过,很多情况下,没有这个必要.% P' u% i v- Q& H
" {2 k! a X; f3 V
一般我们就用"定点"了.你得自己"定个点", 比如用16位, 分成8位整数8位小数(后面记为"(8.8)"), 即"定点"在第8位.那么:1 -> 16’h0100;1.5 -> 16’h0180;-1.5 -> -1.5256 + 65536(补码) -> 16’hFE80(其实就是-16’sh0180, 让综合器给我们算补码去~~);1.164 -> 1.164256 = 298 = 16’h012A' G' _% _( W0 u5 V5 I
& C8 o/ Z) a- Y6 R4 s所以 signed input [15:0] a (也是"8整.8小")和 1.164相乘给 signed output [15:0] mul (也是"8整.8小"), 直接写:assign mul = (a * 16’sh012A) >>>8;就行了, 当然, 你的fpga里有DSP block最好, 不然也要几百个LE的.
9 G" N: _8 I' K8 l! L/ m( v% X+ N) e/ L# B, d
|
|