Matlab/Simulink Coder: 代码生成中的数据处理类型控制

目录

1. 概要

2. Simulink模块的数据类型属性

2. Simulink single模块

3. single函数实现类型转换

4. 确认是否实现了单精度处理

5. 代码中有何差异?

6. 大杀器?


1. 概要

        用Matlab/Simulink自动代码生成工具生成代码中,缺省的浮点数据类型为double类型。但是,对于嵌入式处理,有时出于处理负荷的考虑,可能会希望将数据处理由双精度处理改为单精度处理,甚至采用定点数处理,尽管这样可能会有一些性能损失的代价。那如何控制Matlab/Simulink自动代码生成工具生成非缺省的双精度数据处理类型的C模型呢?作者最近的开发中踩了不少坑,基于这些实际开发中的踩坑经验总结一下实现单精度(single)处理代码生成的一些相关要点。如果要实现定点处理C模型的话,其处理方法应该也是大同小异。

2. Simulink模块的数据类型属性

        Simulink模块的属性中有“Data Type”一项,其缺省属性通常为继承输入数据类型。除非有什么特殊要求,通常来说使用缺省选项即可。不同模块有不同的数据类型指定方式,以下略举几例。

         以下是一个增益模块的数据类型属性选项:

        如上图所示,除了继承输入数据类型外,还提供其它各种精度选项,从双精度到单精度、各种长度的整型数,以及定点数类型,应有尽有。大部分基本处理模块的数据类型都是这样的,但是也有一些例外,比如说像以下所示的滤波器模块。

        以下为一个Biquad滤波器模块的数据类型属性例:

        如上所示,Biquad滤波器的各段滤波器的输入跟随输入数据类型,而各段输出数据类型则跟随本段的输入数据类型。此外,滤波器系数类型也跟随输入数据类型。这也意味着整个滤波器的内部处理的数据类型全部由输入数据类型决定。

2. Simulink single模块

        如上节所述,缺省情况下都选择跟随输入数据类型,因此只要将一个系统的输入数据类型置为所期望的类型就解决了大部分的问题。

        Simulink提供了一个single用于将数据从双精度(或者其它类型)转换为单精度类型。如下图所示:

        这样的话,就将核心处理模块的输入数据转换为单精度类型了。

3. single函数实现类型转换

        是不是输入数据类型置为单精度类型了就足以保证其后所有处理都按照单精度类型进行呢?当然没有这么简单。 一般来说双目(或者说二元)运算的结果数据类型都是会由两个输入数据类型中位宽较大的那个来决定。所以,即便主数据路径的输入数据类型为单精度,但是如果参与运算的另外的输入(比如说从初始化脚本中初始化的增益参数等)如果是双精度的话仍然会导致双精度类型的运算并产生双精度类型的结果并向下游模块传递。

        如图所示,thd是一个在初始化脚本中指定的常数(在脚本中初始化可以方便灵活地修改),虽然它的类型可以在信号属性中进行指定,但是如果有很多这种常数或者变量参数,一一在模型中指定是非常麻烦而且也不方便后续维护。所以在模块属性中如下图一样指定:

然后在脚本中统一用single()函数进行变化就非常便利,如以下示例:

if single_sel == 1
    limL = single(limL);
    thd = single(thd);
end

 

4. 确认是否实现了单精度处理

        如何确认模型的确实现了比如说所希望的单精度处理呢?

        Simulink提供了很方便的确认方法。如下图所示,在执行仿真后,信号的维度及其精度信息会显示于其上(忘记了是缺省地就这么显示还是说需要进行什么设置),这样就可以方便地确认数据类型控制是否达成了目的。

        如果没有达到预期,比如说上图中Sound Restorer模块的输出如果没有变成single的话,则可以沿着模块层次向下检查从那个节点开始不符合预期,然后按方抓药即可。 如果仿真信息表明一个模块的输入和输出都是single,那么针对这个模块进行代码生成就可以确认所生成的C代码是进行单精度类型运算的。

 

5. 代码中有何差异?

        这里主要说一下单精度C模型和双精度C模型的差异。

        在生成的C代码(这里只讨论embedded coder所生成的ert模型)中会有一个头文件rtwtypes.h,其中有各种精度数据类型的aliases的定义,如下图所示:

        双精度C模型中的数据都是采用real_T,而单精度C模型中的数据则都是采用real32_T。

        那有些读者可能已经想到了,我不对simulink模型处理,在生成C代码后再修改一下real_T的定义不就可以了?比如说:

typedef fload real_T;

        笔者一开始也是这么想的,但是这样有一点点一厢情愿,因为有一个例外,就是代码中的常数不受这个real_T的影响。

       如以下代码段(滤波器处理)所示,其中常数后面跟了一个“F”。这个“F”就表示这个常数是当作单精度类型来处理。这样由单精度的simulink模型生成的代码。

        如果没有进行单精度类型指定的话,那生成的代码中的常数后面就不会跟一个“F”了,如下所示滤波器系数就是当作双精度数来处理的。

 

6. 大杀器?

        在撰写这个总结的过程,发现还有一个功能没有用到过,但是看名字就觉得可能威力巨大,如下图所示:

        难道可以这样直接一键式地进行模型整体向单精度模型或者定点运算模型的转换? 

        没有调查就没有发言权,容我研究一番再来向大家。

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值