此示例演示如何在matlab®代碼中設置固定點數學屬性。 您可以使用 fimath 對象控制賦值,加法,減法和乘法的定點數學屬性。可以使用fimath將fimath對象附加到 fi 對象。您可以使用從網路對象中刪除fimath對象。 如果您有matlab編解碼器™軟體,則可以從示例中生成c代碼。 設 ...
此示例演示如何在matlab®代碼中設置固定點數學屬性。
您可以使用 fimath 對象控制賦值,加法,減法和乘法的定點數學屬性。可以使用fimath
將fimath對象附加到 fi 對象。您可以使用從網路對象中刪除fimath對象。
如果您有matlab編解碼器™軟體,則可以從示例中生成c代碼。
設置和刪除不動點數學屬性
使用通過狀語從句: 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代碼,這些代碼可用於浮點和定點類型,使用setfimath setfimath
和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) { /* 建立 */ / *演算法* / /* 清理 */ 回報你+你; }
關註公眾號: MATLAB基於模型的設計 (ID:xaxymaker) ,每天推送MATLAB學習最常見的問題,每天進步一點點,業精於勤荒於嬉。
打開微信掃一掃哦!