FPGA里怎么做小数乘法
2015-04-27 17:28
423 查看
经常有同学问, fpga里小数乘法怎么搞?
如果你乐意, 按照IEEE754标准做"浮点"型运算的ip当然最好(虽然面积上不太好).
不过,很多情况下,没有这个必要.
一般我们就用"定点"了.
你得自己"定个点", 比如用16位, 分成8位整数8位小数(后面记为"(8.8)"), 即"定点"在第8位.
那么:
1 -> 16'h0100;
1.5 -> 16'h0180;
-1.5 -> -1.5*256 + 65536(补码) -> 16'hFE80(其实就是-16'sh0180, 让综合器给我们算补码去~~);
...
1.164 -> 1.164*(1<<<8) = 298 = 16'h012A;
所以 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的.
因为 (8.8) 乘 (8.8) 得到 (16.16), 为了恢复成 (8.8), 所以帯符号右移8位即可.
把低8位小数舍掉, 高8位整数也丢了, 所以你得保证你的16位(8.8)的"定点小数"乘积不能超过范围,
多数数字信号处理系数都是区间[-1.0, 1.0]的,多半不存在问题,
积分什么的, 还有其它可能有问题的自己想清楚就行, 当然你要保留16位整.16位小也可以~~~
总结:
module fixpmul
#(
parameter IW = 8, //整数位宽
parameter FW = 8 //小数位宽
)(
input signed [IW+FW-1 : 0] a,
input signed [IW+FW-1 : 0] b,
output signed [IW+FW-1 : 0] o
);
(* multstyle = "dsp" *) wire signed [IW*2+FW*2-1 : 0] long;
assign long = a * b;
assign o = long >>> FW;
endmodule
复制代码
其中的(* multstyle = "dsp" *)是Quartus的综合指令,对于Vivado则是:(* use_dsp48 = "yes" *),他们会指示综合器使用内部DSP单元的乘法器来实现乘法。
在大多数的数字信号处理过程中,我们都认为信号的表意是∈(-1,1),因此,以16位数据为例,一般都用(1.15)(即一位整数(其实只是符号),15位小数)的格式。
所有绝对值小于1的系数c的(1.15)表达便是:c * (1 <<< 15);而乘法:
(1.15) = ((1.15) * (1.15)) >>> 15这样实际上也扔掉了最高位,但只有在-1*-1的时候会溢出,所以务必保证你的信号不会取到-1(-32768),即信号区间(-1,1)。
如果你乐意, 按照IEEE754标准做"浮点"型运算的ip当然最好(虽然面积上不太好).
不过,很多情况下,没有这个必要.
一般我们就用"定点"了.
你得自己"定个点", 比如用16位, 分成8位整数8位小数(后面记为"(8.8)"), 即"定点"在第8位.
那么:
1 -> 16'h0100;
1.5 -> 16'h0180;
-1.5 -> -1.5*256 + 65536(补码) -> 16'hFE80(其实就是-16'sh0180, 让综合器给我们算补码去~~);
...
1.164 -> 1.164*(1<<<8) = 298 = 16'h012A;
所以 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的.
因为 (8.8) 乘 (8.8) 得到 (16.16), 为了恢复成 (8.8), 所以帯符号右移8位即可.
把低8位小数舍掉, 高8位整数也丢了, 所以你得保证你的16位(8.8)的"定点小数"乘积不能超过范围,
多数数字信号处理系数都是区间[-1.0, 1.0]的,多半不存在问题,
积分什么的, 还有其它可能有问题的自己想清楚就行, 当然你要保留16位整.16位小也可以~~~
总结:
module fixpmul
#(
parameter IW = 8, //整数位宽
parameter FW = 8 //小数位宽
)(
input signed [IW+FW-1 : 0] a,
input signed [IW+FW-1 : 0] b,
output signed [IW+FW-1 : 0] o
);
(* multstyle = "dsp" *) wire signed [IW*2+FW*2-1 : 0] long;
assign long = a * b;
assign o = long >>> FW;
endmodule
复制代码
其中的(* multstyle = "dsp" *)是Quartus的综合指令,对于Vivado则是:(* use_dsp48 = "yes" *),他们会指示综合器使用内部DSP单元的乘法器来实现乘法。
在大多数的数字信号处理过程中,我们都认为信号的表意是∈(-1,1),因此,以16位数据为例,一般都用(1.15)(即一位整数(其实只是符号),15位小数)的格式。
所有绝对值小于1的系数c的(1.15)表达便是:c * (1 <<< 15);而乘法:
(1.15) = ((1.15) * (1.15)) >>> 15这样实际上也扔掉了最高位,但只有在-1*-1的时候会溢出,所以务必保证你的信号不会取到-1(-32768),即信号区间(-1,1)。
相关文章推荐
- fpga里小数乘法怎么搞?
- 科普:矩阵乘法是怎么做的?怎么判断两个矩阵是否可以相乘?不使用行列式
- 小数在JS中表示怎么不准确
- fpga 定点小数计算
- 第1课:软件工程师该怎么了解 FPGA 架构
- 公开课主题:FPGA中原码、补码和小数的运算
- 小数高精度乘法
- 全局时钟global clock--怎么设置FPGA的全局时钟资源
- C# 怎么把double 存成两位精度小数
- 程序是怎么跑起来的(3)---计算机进行小数运算时出错的原因
- HDU 1063 / PKU 1001 (小数高精度乘法,JAVA写的)
- (小数)javascript(js)的小数点乘法除法问题
- 怎么使float保留两位小数或多位小数
- FPGA浮点小数与定点小数的换算及应用
- 怎么用正则表达式判断数字(包括正,负,小数。。)
- POJ 2390 (小数高精度乘法)
- Android怎么让EditText只显示两位小数(格式化法)
- js中浮点数乘法,多位小数处理
- 花了近一天的时间写了小数的高精度乘法,并通过了POJ1001,颇有成就感。
- 随机四则运算(小数)阿西巴分数怎么做?!