定点数基础:为什么需要定点化?
做无线通信算法的人,迟早要面对一个问题:你的算法在电脑上跑得挺好,一上芯片就崩了。为什么?
说白了,电脑里跑的是浮点数,芯片里跑的是定点数。这两者之间,隔着一道天堑。
我记得刚入行那会儿,在做一个OFDM接收机项目。Matlab仿真时性能漂亮得很,结果FPGA综合完一测,误码率直接爆表。查了三天,最后发现是浮点转定点时,某个中间变量的位宽没给够。嗯,从那以后,我再也不敢轻视定点化这件事。
为什么需要定点化?
你想想看,一个浮点数在硬件里长什么样?它需要指数位、尾数位、符号位。一个单精度float就是32位,双精度double是64位。这在CPU里没问题,但在ASIC或FPGA里,每一比特都是成本。
我做过一个粗略的估算:
- 一个32位浮点乘法器,面积大约是定点乘法器的3-5倍
- 功耗更是高出2-3倍
- 延迟也更大
所以,定点化的核心目的就两个:省面积、降功耗。在无线通信这种对实时性要求极高的场景里,定点化几乎是唯一的选择。
核心观点:定点化不是可选项,而是工程落地的必经之路。你在Matlab里跑得再欢,不上定点化,就永远停留在理论阶段。
浮点数与定点数的区别
这个问题,我习惯用一个简单的例子来说明。
浮点数:0.15625 × 2³ = 1.25
定点数:假设我们用Q8格式,1.25 = 01.01000000(二进制)
区别在哪?
- 浮点数:小数点可以「浮动」,动态范围大,但硬件复杂
- 定点数:小数点位置固定,硬件简单,但需要提前知道数值范围
我曾经在项目中遇到过一个坑:用浮点仿真时,某个中间变量范围是[-1.2, 1.2],我心想Q2.14格式够用了。结果实际信号进来,偶尔会蹦到1.5。嗯,这就是定点化最怕的事——溢出。
| 特性 | 浮点数 | 定点数 |
|---|---|---|
| 动态范围 | 大(±10³⁸) | 小(取决于位宽) |
| 精度 | 相对精度恒定 | 绝对精度恒定 |
| 硬件成本 | 高 | 低 |
| 功耗 | 高 | 低 |
| 设计复杂度 | 低(不用操心范围) | 高(需要仔细定标) |
Q格式表示法详解
Q格式,说白了就是告诉硬件:你的小数点在哪。
Qm.n 表示法:
- m:整数部分位数(含符号位)
- n:小数部分位数
- 总位宽 = m + n
举个例子:Q4.12 格式
- 总位宽16位
- 1位符号位 + 3位整数 + 12位小数
- 表示范围:[-8, 7.999755859375]
- 精度:2⁻¹² ≈ 0.000244
我的习惯:做定点化设计时,我一般先画一张「数值范围-精度需求」表。范围决定整数位宽,精度决定小数位宽。两者一加,就是总位宽。
常见的Q格式:
- Q1.15:16位,范围[-1, 0.999969],精度2⁻¹⁵。常用于音频信号
- Q2.14:16位,范围[-2, 1.999939],精度2⁻¹⁴。常用于基带信号
- Q4.12:16位,范围[-8, 7.999756],精度2⁻¹²。常用于AGC之后
- Q8.8:16位,范围[-128, 127.996094],精度2⁻⁸。常用于控制参数
这里有个容易搞混的地方:Q格式的m到底包不包含符号位?
我个人的习惯是:包含。Q1.15就是1位符号+15位小数。但有些资料里Q1.15表示1位整数+15位小数,符号位另算。你最好在项目文档里明确写清楚,不然容易出问题。
我曾经踩过的坑:有一次跟算法团队对接,他们文档里写「Q16格式」,我以为是Q1.15,结果人家是Q0.16(纯小数)。两个团队各做各的,联调时数据全对不上。从那以后,我要求所有定点化文档必须写清楚m和n,不准用模糊表述。
定点化运算规则
定点数的加减乘除,跟整数运算差不多,但多了个「小数点对齐」的问题。
加法/减法:
- 两个数的小数点必须对齐
- 结果位宽 = max(m₁, m₂) + max(n₁, n₂) + 1(防止溢出)
乘法:
- 结果位宽 = m₁ + m₂ + n₁ + n₂
- 结果的小数点位置 = n₁ + n₂
- 通常需要截位或舍入
举个例子:
Q4.12 × Q4.12 = Q8.24
结果需要截取到Q4.12,保留高16位
除法:
- 先将被除数左移,再除以除数
- 结果位宽 = m₁ + n₂(近似)
- 除法在硬件里很贵,能避免就避免
避坑指南:我曾经在做一个LTE信道估计模块时,用了大量除法。结果综合出来面积超标3倍。后来全部改成查表+乘法,面积降了70%。记住:硬件里除法是奢侈品,能用乘法就别用除法。
定点化设计流程
我一般按这个步骤来做定点化:
- 范围分析:跑大量仿真数据,找出每个变量的最大值、最小值
- 精度分析:确定每个变量需要的精度,通常跟信噪比要求挂钩
- 位宽分配:根据范围和精度,确定Q格式
- 定点仿真:用定点模型跑一遍,跟浮点结果对比
- 迭代优化:如果性能不达标,调整位宽或格式
这个流程看起来简单,但实际做起来很磨人。我记得有个项目,光定点化就迭代了5轮。每次觉得差不多了,一测性能又差那么0.5dB。最后发现是某个滤波器的系数精度不够。
下面这张图是我自己总结的定点化知识体系,你可以参考一下:
这张图把定点化的核心要素都串起来了。你从「为什么需要」出发,理解动机;然后搞清楚「浮点vs定点」的区别;接着掌握「Q格式」的具体表示;最后学会「运算规则」。四个分支缺一不可。
一句话总结:定点化就是把浮点算法「翻译」成硬件能高效执行的语言。翻译得好不好,直接决定你的芯片能不能跑、跑多快、功耗多少。
好了,这一章的内容就这些。定点数基础打牢了,后面讲量化误差、舍入模式、溢出处理时,你才能跟得上。
公众号:蓝海资料掘金营,微信deep3321