设置和删除不动点数学属性
使用通过状语从句: fimath 删除函数, 可以将定点操作与全局和本地 fimath 设置隔离开来. 您还可以从没有附加到输出变量的函数返回. 这使您可以对定点数学设置进行本地控制, 而不会干扰其他函数中的设置.
matlab 代码
function y = user_written_sum(u)
%Setup
- F = fimath('RoundingMethod','Floor',...
- 'OverflowAction','Wrap',...
- 'SumMode','KeepLSB',...
- 'SumWordLength', 32);
- u = setfimath(u,F);
- y = fi(0,true,32,get(u,'FractionLength'),F);
%算法
为 I = 1: 长度 (U)
y(:) = y + u(i);
结束
%清理
y = removefimath(y);
结束
输出没有附加的 fimath
当你运行代码时, fimath 控制函数内的算术, 但返回值没有附加 fimath. 这是由于在函数 removefimath 使用了 setfimath 和 setfimath.
- >> u = fi(1:10,true,16,11);
- >> y = user_written_sum(u)
- y =
- 55
DataTypeMode: 定点: 二进制点缩放
签名: 签名
WordLength:32
分数长度: 11
生成的 c 代码
如果您有 matlab 编码器软件, 则可以使用以下命令生成 c 代码.
- >> u = fi(1:10,true,16,11);
- >> codegen user_written_sum -args {
- u
- } -config:lib -launchreport
函数 fimath,setfimath 和 removefimath 定点数学, 但变量中包含的基础数据不会更改, 因此生成的 c 代码不会生成任何数据副本.
- int32_T user_written_sum(const int16_T u [10])
- {
- int32_T y;
- int32_T i;
- /* 建立 */
- y = 0;
- /* 算法 */
- for(i = 0; i <10; i ++){
- y + = u [i];
- }
- /* 清理 */
回归 y;
}
不匹配的菲马特
当您对 fi 对象进行操作时, 它们 fimath 属性必须相等, 否则您会收到错误.
- >> A = fi(pi,'ProductMode','KeepLSB');
- >> B = fi(2,'ProductMode','SpecifyPrecision');
- >> C = A * B.
使用 embedded.fi/mtimes 时出错
两个操作数的 embedded.fimath 必须相等.
若要避免此错误, 可以从表达式中的一个变量中删除 fimath. 在本例中, 表达式在上下文的中从 fimath 中删除 fimath, 而不修改 B 本身, 并使用附加到 fimath 的 B 计算产品.
- >> C = A * removefimath(B)
- C =
- 6.283203125
DataTypeMode: 定点: 二进制点缩放
签名: 签名
WordLength:32
分数长度: 26
RoundingMethod: 最近的
溢出动作: 饱和
- ProductMode:KeepLSB
- ProductWordLength:32
- SumMode:FullPrecision
在临时变量上更改 himath
如果您有没有附加 fimath 的变量, 但您想要控制特定的操作, 则可以在表达式的上下文中附加 fimath, 而无需修改变量.
例如, 产品是用 F 定义的 fimath 计算的.
- >> F = fimath('ProductMode','KeepLSB','OverflowAction','Wrap','RoundingMethod','Floor');
- >> A = fi(pi);
- >> B = fi(2);
- >> C = A * setfimath(B,F)
- C =
- 6.2832
DataTypeMode: 定点: 二进制点缩放
签名: 签名
WordLength:32
分数长度: 26
RoundingMethod: 地板
- OverflowAction:Wrap
- ProductMode:KeepLSB
- ProductWordLength:32
- SumMode:FullPrecision
- MaxSumWordLength:128
请注意, 变量 B 不会更改.
>> B
B =
2
DataTypeMode: 定点: 二进制点缩放
签名: 签名
WordLength:16
分数长度: 13
消除循环中的 fimath 冲突
您可以计算产品和总和, 使用 dsp 的累加器与地板舍入和包装溢出相匹配, 并在输出上使用最近的舍入和饱和溢出. 为了避免不匹配的 fimath 错误, 可以在与其他变量一起计算时删除输出变量上的 fimath.
matlab 代码
在本例中, 产品为 32 位, 累加器为 40 位, 使最小位与地板舍入和包装溢出, 就像 c 的本机整数规则一样. 输出使用最近的舍入和饱和溢出.
function [y,z] = setfimath_removefimath_in_a_loop(b,a,x,z)
%Setup
- F_floor = fimath('RoundingMethod','Floor',...
- 'OverflowAction','Wrap',...
- 'ProductMode','KeepLSB',...
- 'ProductWordLength',32,...
- 'SumMode','KeepLSB',......
- 'SumWordLength',40);
- F_nearest = fimath('RoundingMethod','最近',......
- 'OverflowAction','Wrap');
%设置此函数的本地 fimath
- b = setfimath(b,F_floor);
- a = setfimath(a,F_floor);
- x = setfimath(x,F_floor);
- z = setfimath(z,F_floor);
%使用最近的舍入创建 y
y = coder.nullcopy(fi(zeros(size(x)),true,16,14,F_nearest));
%算法
为长度 (X):J = 1
%最近分配成 Y
y(j)= b(1)* x(j)+ z(1);
%删除 y 与其他 fimaths 的 fimath 冲突
- z(1)=(b(2)* x(j)+ z(2)) - a(2)* removefimath(y(j));
- z(2)= b(3)* x(j) - a(3)* removefimath(y(j));
结束
%清理: 从输出中删除 fimath
- y = removefimath(y);
- z = removefimath(z);
结束
代码生成说明
如果您有 matlab 编码器软件, 则可以使用以下命令生成具有指定硬件特征的 c 代码.
- N = 256;
- t = 1:N;
- xstep = [ones(N / 2,1); - ones(N / 2,1)];
- num = [0.0299545822080925 0.0599091644161849 0.0299545822080925];
- den = [1 -1.4542435862515900 0.5740619150839550];
- b = fi(num,true,16);
- a = fi(den,true,16);
- x = fi(xstep,true,16,15);
zi = fi(零 (2,1), 真, 16,14);
- B = coder.Constant(b);
- A = coder.Constant(a);
- config_obj = coder.config('lib');
- config_obj.GenerateReport = true;
- config_obj.LaunchReport = true;
- config_obj.TargetLang = 'C' ;
- config_obj.GenerateComments = true;
- config_obj.GenCodeOnly = true;
- config_obj.HardwareImplementation.ProdBitPerChar = 8;
- config_obj.HardwareImplementation.ProdBitPerShort = 16;
- config_obj.HardwareImplementation.ProdBitPerInt = 32;
- config_obj.HardwareImplementation.ProdBitPerLong = 40;
代码生成 - config config_obj setfimath_removefimath_in_a_loop -args {B,A,X, 滋} -launchreport
生成的 c 代码
函数 fimath,setfimath 和 removefimath 定点数学, 但变量中包含的基础数据不会更改, 因此生成的 c 代码不会生成任何数据副本.
- void setfimath_removefimath_in_a_loop(const int16_T x [256],int16_T z [2],
- int16_T y [256])
- {
- int32_T j;
- int40_T i0;
- int16_T b_y;
- /* 建立 */
- /* 设置此函数的本地 fimath */
- /* 用最近的舍入创建 y */
- /* 算法 */
- for(j = 0; j <256; j ++){
- /* 最近的分配到 y */
- i0 = 15705 * x [j] +((int40_T)z [0] <<20);
- b_y =(int16_T)((int32_T)(i0>> 20)+((i0&524288L)!= 0L));
- /* 删除 y 与其他 fimaths 的 fimath 冲突 */
- z [0] =(int16_T)(((31410 * x [j] +((int40_T)z [1] <<20)) - ((int40_T)( - 23826
- * b_y)<< 6))>> 20);
- z [1] =(int16_T)((15705 * x [j] - ((int40_T)(9405 * b_y)<<6))>> 20);
- y [j] = b_y;
- }
- /* 清理: 从输出中删除 fimath */
- }
多态性代码
您可以编写 matlab 代码, 这些代码可用于浮点和定点类型, 使用 setfimathsetfimath 和 removefimath.
function y = user_written_function(u)
%Setup
- F = fimath('RoundingMethod','Floor',......
- 'OverflowAction','Wrap',...
- 'SumMode','KeepLSB');
- u = setfimath(u,F);
%算法
y = u + u;
% 清理
y = removefimath(y);
结束
定点输入
当使用定点输入调用该函数时, fimath F 将用于算术, 并且输出没有附加 fimath.
- >> u = fi(pi / 8,true,16,15,'RoundingMethod','Convergent');
- >> y = user_written_function(u)
- y =
- 0.785400390625
DataTypeMode: 定点: 二进制点缩放
签名: 签名
WordLength:32
分数长度: 15
为固定点生成 c 代码
如果您有 matlab 编码器软件, 则可以使用以下命令生成 c 代码.
- >> u = fi(pi / 8,true,16,15,'RoundingMethod','Convergent');
- >> codegen user_written_function -args {
- u
- } -config:lib -launchreport
函数 fimath,setfimath 和 removefimath 定点数学, 但变量中包含的基础数据不会更改, 因此生成的 c 代码不会生成任何数据副本.
- int32_T user_written_function(int16_T u)
- {
- /* 建立 */
- /* 算法 */
- /* 清理 */
回报你 + 你;
}
双输入
由于 setfimath 状语从句: removefimath 的英文浮点类型的传递, user_written_function 示例也适用于浮点类型.
function y = user_written_function(u)
%Setup
- F = fimath('RoundingMethod','Floor',......
- 'OverflowAction','Wrap',...
- 'SumMode','KeepLSB');
- u = setfimath(u,F);
%算法
y = u + u;
% 清理
y = removefimath(y);
结束
为双精度生成的 c 代码
当使用浮点输入编译时, 您将获得以下生成的 c 代码.
- >> codegen user_written_function -args {
- 0
- } -config:lib -launchreport
- real_T user_written_function(real_T u)
- {
回报你 + 你;
}
其中 real_T 类型被定义为 double:
typedef double real_T;
更多多态代码
编写此函数时, 可以将输出创建为与输入的类型相同, 因此浮点和定点都可以与输入一起使用.
function y = user_written_sum_polymorphic(u)
%Setup
- F = fimath('RoundingMethod','Floor',...
- 'OverflowAction','Wrap',...
- 'SumMode','KeepLSB',...
- 'SumWordLength', 32);
- u = setfimath(u,F);
如果是 isfi(你)
y = fi(0,true,32,get(u,'FractionLength'),F);
其他
y = 零 (1,1,class(u));
结束
%算法
对于 i = 1: 长度 (u)
y(:) = y + u(i);
结束
% 清理
y = removefimath(y);
结束
固定点生成的 c 代码
如果您有 matlab 编码器软件, 则可以使用以下命令生成定点 c 代码.
- >> u = fi(1:10,true,16,11);
- >> codegen user_written_sum_polymorphic -args {
- u
- } -config:lib -launchreport
函数 fimath,setfimath 和 removefimath 定点数学, 但变量中包含的基础数据不会更改, 因此生成的 c 代码不会生成任何数据副本.
- int32_T user_written_sum_polymorphic(const int16_T u [10])
- {
- int32_T y;
- int32_T i;
- /* 建立 */
- y = 0;
- /* 算法 */
- for(i = 0; i <10; i ++){
- y + = u [i];
- }
- /* 清理 */
回归 y;
}
生成的浮点 c 代码
如果您有 matlab 编码器软件, 则可以使用以下命令生成浮点 c 代码.
- >> u = 1:10;
- >> codegen user_written_sum_polymorphic -args {u} -config:lib -launchreport
- real_T user_written_sum_polymorphic(const real_T u [10])
- {
- real_T y;
- int32_T i;
- /* 建立 */
- y = 0.0;
- /* 算法 */
- for(i = 0; i <10; i ++){
- y + = u [i];
- }
- /* 清理 */
回归 y;
}
其中 real_T 类型被定义为 double:
typedef double real_T;
整数类型上的 setimath
按照既定的模式处理内置整数 (fi 对象),setfimath 将整数输入转换为具有附加 fimath 的等效 fi.
- >> u = int8(5);
- >> codegen user_written_u_plus_u -args {
- u
- } -config:lib -launchreport
- function y = user_written_u_plus_u(u)
%Setup
- F = fimath('RoundingMethod','Floor',...
- 'OverflowAction','Wrap',...
- 'SumMode','KeepLSB',...
- 'SumWordLength', 32);
- u = setfimath(u,F);
%算法
y = u + u;
% 清理
y = removefimath(y);
结束
类型输出由 fimath 指定为 32 位.
- int32_T user_written_u_plus_u(int8_T u)
- {
- /* 建立 */
- /* 算法 */
- /* 清理 */
回报你 + 你;
}
来源: https://www.cnblogs.com/52geek/p/10447850.html