定点数基础:为什么需要定点化?

做无线通信算法的人,迟早要面对一个问题:你的算法在电脑上跑得挺好,一上芯片就崩了。为什么?

说白了,电脑里跑的是浮点数,芯片里跑的是定点数。这两者之间,隔着一道天堑。

我记得刚入行那会儿,在做一个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%。记住:硬件里除法是奢侈品,能用乘法就别用除法。

定点化设计流程

我一般按这个步骤来做定点化:

  1. 范围分析:跑大量仿真数据,找出每个变量的最大值、最小值
  2. 精度分析:确定每个变量需要的精度,通常跟信噪比要求挂钩
  3. 位宽分配:根据范围和精度,确定Q格式
  4. 定点仿真:用定点模型跑一遍,跟浮点结果对比
  5. 迭代优化:如果性能不达标,调整位宽或格式

这个流程看起来简单,但实际做起来很磨人。我记得有个项目,光定点化就迭代了5轮。每次觉得差不多了,一测性能又差那么0.5dB。最后发现是某个滤波器的系数精度不够。

下面这张图是我自己总结的定点化知识体系,你可以参考一下:

定点化知识体系 定点化设计 为什么需要 省面积·降功耗 浮点vs定点 动态范围·精度 Q格式表示 Qm.n详解 运算规则 加减乘除 硬件成本 实时性 功耗约束 范围分析 精度分析 位宽分配 浮点仿真 → 定点实现 → 性能验证

这张图把定点化的核心要素都串起来了。你从「为什么需要」出发,理解动机;然后搞清楚「浮点vs定点」的区别;接着掌握「Q格式」的具体表示;最后学会「运算规则」。四个分支缺一不可。

一句话总结:定点化就是把浮点算法「翻译」成硬件能高效执行的语言。翻译得好不好,直接决定你的芯片能不能跑、跑多快、功耗多少。

好了,这一章的内容就这些。定点数基础打牢了,后面讲量化误差、舍入模式、溢出处理时,你才能跟得上。


公众号:蓝海资料掘金营,微信deep3321