找回密码
 注册
关于网站域名变更的通知
查看: 365|回复: 1
打印 上一主题 下一主题

FPGA --- FPGA里小数乘法怎么搞???

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-7-29 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
经常有人问, FPGA里小数乘法怎么搞?
1 x4 ^1 u& o: p' T/ Y( l* b' \/ m! M% J# A7 s
) Y. m3 T3 n1 C" \
如果你乐意, 按照IEEE754标准做"浮点"型运算的ip当然最好(虽然面积上不太好).2 I* ]9 }( R% Q9 L7 y
不过,很多情况下,没有这个必要.  c+ b/ t" G, {8 r
; C- s  O; _- z6 b! i- [

# G; h  z" X9 Q& b+ H一般我们就用"定点"了.
) a: _$ p1 ^; R6 v) v- [5 \你得自己"定个点", 比如用16位, 分成8位整数8位小数(后面记为"(8.8)"), 即"定点"在第8位.. g6 e+ H) y' B
那么:
/ b+ o1 @6 h. o! _# L' {1 -> 16'h0100;
! W, V; B2 B8 x2 n: D1.5 -> 16'h0180;7 ~) F+ E3 J% y8 M+ P
-1.5 -> -1.5*256 + 65536(补码) -> 16'hFE80(其实就是-16'sh0180, 让综合器给我们算补码去~~);
4 Z8 A1 i  x, Q4 q2 W  d9 U( k2 m; K...# r2 j% T- v* @0 v, {) T1 k
1.164 -> 1.164*256 = 298 = 16'h012A;
9 C; j/ d7 z; N' f! o- D% O) n. _# h& i' O7 B5 C3 E) s% M
8 u' r  W8 s( ~% V  `+ k
所以 signed input [15:0] a (也是"8整.8小")和 1.164相乘给 signed output [15:0] mul (也是"8整.8小"), 直接写:. I! n1 u/ d* e( Q5 x0 O, U
assign mul = (a * 16'sh012A) >>>8;1 Y: G9 G7 K& J* }
就行了, 当然, 你的fpga里有DSP block最好, 不然也要几百个LE的.# S$ _/ d! ?3 d$ a( x0 t3 R

6 O; ~9 f& n0 G; ~6 i8 r  q9 `
$ p4 Z6 k, s1 x) D) n' [# J8 U
因为 (8.8) 乘  (8.8) 得到  (16.16), 为了恢复成 (8.8), 所以帯符号右移8位即可.' Y9 x( \) n7 A+ ^( F7 l, w, f
把低8位小数舍掉, 高8位整数也丢了, 所以你得保证你的16位(8.8)的"定点小数"乘积不能超过范围, 多数数字信号处理系数都是区间[-1.0, 1.0]的,多半不存在问题, 积分什么的, 还有其它可能有问题的自己想清楚就行, 当然你要保留16位整.16位小也可以~~~% [9 ?4 f0 O3 h% h! g
( D) b; R, y! B8 Q; z
* Z* A. o+ ]$ H2 Y0 M4 t
总结:
1 Q5 e. ~5 ?) k- ~2 }" B, Bmodule fixpmul7 M+ U2 R" M- x
#(7 `# G- c% u6 F& ~3 x& N
    parameter IW = 8,) t! N( X- W$ U
    parameter FW = 8
4 Q* w. ~8 ^! i9 E8 v5 l)() f, E+ y9 G# z. ]* U- C  k
    input signed [IW+FW-1 : 0] a," Q$ p/ I6 r5 F" X1 v7 F7 u% w" B
    input signed [IW+FW-1 : 0] b,
3 T: b7 r5 s: }6 i    output signed [IW+FW-1 : 0] o. J# F/ |& V/ j6 a4 b- M
);- T  j3 X. O) M) C) ]
    (* multstyle = "dsp" *) wire signed [IW*2+FW*2-1 : 0] long;
% t& |  `) I/ |  ], L* M- @0 ]( m# O% K    assign long = a * b;6 [, k8 V- O! F. R
    assign o = long >>> FW;/ j& J1 E2 w* `2 l
endmodule
! e% ?9 Q. P- x; t4 t) x
# [4 F" g+ }1 q2 d* h

" @3 i% u: |  @, ~PS: 作为一个完美主义者的想法: 以8位整型为例, 其实 8位有符号 乘 8位有符号得到的 16位有符号, 中的第14位(权2^14的位, 符号位右边的位), 很讨厌, 它只有在 -128 * -128时才等于1, 其它65535种情况, 全是0, 很浪费.
; |( g6 p- ]6 N0 c9 j, P6 H# S% R所以我们一般在数字信号处理系统中, 永远把[-1,1]映射到[-127,127], 这样那个讨厌的第14位永远用不到, 然后就可以: wire signed [15:0] mul = a * b; wire signed [14:0] out = {wire[15], wire[13:0]}, 8位有符号 乘 8位有符号 得到 15位有符号, 节约一位.
: q" R: N' X0 s% G3 V) G& A
6 |- V; x/ t- U  Y

$ N. \2 a, q! l' f/ a
7 S% K, u  }2 `' z+ R
# X* e$ n, l/ e* x

该用户从未签到

2#
发表于 2019-7-29 18:24 | 只看该作者
FPGA里小数乘法怎么搞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-20 23:10 , Processed in 0.109375 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表