1. 使用FPGA实现定点小数计算
FPGA中不适合做浮点数运算,但有时又会涉及到小数的运算,这时就需要用到Q格式数据。
2. Q格式
Q:如果想要表示一个小数,但FPGA里没法加小数点,那该如何表示小数呢?
A:可以使用定点小数!
定点小数的小数点预设在固定的位置,因此不用加小数点就可以区分二进制数的整数部分和小数部分,Q格式就是所谓的定点小数表示方法。
通常我们用Qn来表示定点小数,n代表小数的个数,精度为2^(-n),如Q16,它有16位二进制来表示小数点后的数据,精度为 2^(-16) ;Q8,它有8位二进制来表示小数点后的数据,精度为 2^(-8)。
Q:如何将十进制小数 X 转换成二进制定点小数 X’ ?(以Q8为例)
A:先把X就当成二进制数!先转换整数部分,数据格式是Q8,整数直接左移8位给小数留8位空间,也就是乘(2^8);再转换小数部分,数据格式是Q8,也是左移8位以保留小数的前8位,也就是乘 (2^8)。因此,整体转换方法就是直接乘 (2^8)!!!
3. 运算
Example 1: 3.14 + 3.14 = ? (16位Q8 = 1 + 7 + 8,1位符号位,7位整数位,8位小数位)
解:
- 数值转换 3.14 x (2^8) = 16’d804 = 16’b0000_0011_0010_0100
- 加法运算 3.14 + 3.14 = 16’b0000_0011_0010_0100 + 16’b0000_0011_0010_0100 = 16’b0000_0110_0100_0110 = 16’d1608
- 结果展示 16’d1608 / (2^8) = 6.28125 ; 3.14 + 3.14 = 6.28 ;结果相差0.00125,结果的小数前两位相同,与精度一致。
Example 2: 3.14 x 3.14 = ? (16位Q8 = 1 + 7 + 8,1位符号位,7位整数位,8位小数位)
解:
- 数值转换 3.14 x (2^8) = 16’d804 = 16’b0000_0011_0010_0100
- 乘法运算 3.14 x 3.14 = 16’b0000_0011_0010_0100 x 16’b0000_0011_0010_0100
= 32’b0000_0000_0000_1001_1101_1101_0001_0000 = 32’d646416 - 结果展示 32’d646416 / (2^16) = 9.863525390625 ; 3.14 x 3.14 = 9.8596 ;结果相差0.003925390625,结果的小数前两位差0.01,与精度一致。