目录
以FFT4为例,尝试实现手动定点化、半自动定点化和全自动定点化目标。
手动定点化
1.首先打code : hdlsetup(bdroot),不要加 ' ' 。模型会变红,数据流刚开始会是double类型,convert一下变成定点型变量。接着需要记录信号,放在示波器中观察,误差和精度。
可以看出没有误差,证明FFT4定点化到16位是没问题的。
因为这些数基本上可以由二进制小数简单组合,所以不需要位数太多,6位定点也行!
我们再看一下FFT64情况:乘法有个因子是浮点数,这里存在定点精度损失,但是由于乘法是继承定点类型设置,所以输出也是double类型。改动非常麻烦,FFT64就不建议手搭建了。
我寻思从基础模型看得更加清楚,从数据输入的精度误差,到持续加法乘法运算精度损失后得到的结果,手动与自动对比更加有效果。下图表示运算误差。我又想到截断误差roundoff,不知道有没有论文解释一下十进制小数转换二进制的时候误差分析,最好是概率误差分布图。(挖坑)
总之,手动定点化是方便的,但是模型多了之后是麻烦的,批量换数据类型是头痛的,还得找找好使的工具Tools。下面详细介绍半自动化和自动化操作。
全自动定点化工具使用
按照步骤,模块选中创建子系统,然后点定点化工具。
1准备2设定参数3开始寻找
结果:1.没找到哦 → 误差设置太精密了,位数太少了,返回设置参数重新跑。
2.找到了,但是分优化的各种多解情况,一般simulink会应用最后一个,变量是搜索时间。
3.找到了,但是不是我想要的结果,误差还是太大了,返回迭代。不禁想到,这个误差是多精确才算精确啊,误差客观存在,硬件实现只能设置目标,1e-2,1e-6,......,给定激励不停迭代。
4.天选之子,找到了且是我想要的,从未有过bug的烦恼,不知bug为何物。
以FFT64为例,我们设置参数如下,跑了一会后找到了最优解,一般用最好的那个。
看了误差前后对比图,确实在给定绿色范围之内。
再看模型,发现已经定点化sfix27了,但是输出还是定点化到了28位。
最后我们用Matlab脚本试试遍历一下。
(1)给定数据数量一定,随机数20*64组复数,跑20次,看看每次的FFT64与理论误差是多少。
左图可以看到遍历20次,不同的数据激励误差还是有溢出现象。
(2)循环次数一定,就1次,看数据量从1*64到20*64这些激励,对FFT64精度的影响。
右图,发现有的数据收敛,有的溢出,数据量小的时候还好,多了很大概率出现异常。
更新
定位有符号数22位,绝对误差容量1e-4,结果如下:
左图是数据量增多,误差累积增加,合理。但是有一些情况下还是溢出。
右图是数据量保持不变,遍历20次,大概有五次溢出,其他情况误差量级1e-2左右。
再次更新
定位有符号数25位,绝对误差容量1e-5,结果如下:
小结,对比一个好的结果
以上是定位有符号数sfix28位情况下:
从左图看出,对20*64组数据量来说,跑20次一致性是对的,误差在1e-4范围内。
从右图看出,对1*64~20*64数据量增多来说,误差累积是逐渐加大的,但也都在合理性当中。
最后,优化是个无止境的过程,能否达到最优解,Simulink工具和人力都只是工具,
花费时间和精力,只能慢慢滴接近。不过经验规律是,比起人来做定点化,Simulink还是方便的,只要电脑硬件优秀,迭代时间够长,可视化和操作性讲,仍然不错。