matlab fi工具箱使用

先定义两个运算属性,这两个运算一个是直接截掉高位,一个是做了饱和处理。

F0 = fimath('OverflowAction','Wrap','RoundingMethod','Floor');
F1 = fimath('OverflowAction','Saturate','RoundingMethod','Floor');

fi的语法为

fi(value,signed,word_length,fraction_length,F)

其中,WordLength是字长,FractionLength是小数位宽,等同于小数点距离LSB的距离,可以是负数。

例1
00.000_0111010000,只保留中间的有效位,量化为011101,则WordLength=6,FractionLength=9
000000
0101101_0000.00,量化为0101101,则WordLength=7,FractionLength=-4

范例:
定义定点数a

a=fi(1.3256,1,6,4,'OverflowAction','Wrap','RoundingMethod','Floor')

运行结果为:

a = 

    1.3125

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 6
        FractionLength: 4

        RoundingMethod: Floor
        OverflowAction: Wrap
           ProductMode: FullPrecision
               SumMode: FullPrecision

查看a的二进制保存形式:

>> bin(a)

ans =

    '010101'

对a进行截位,只保留高四位,丢掉低两位,结果保存到b中:

>> b=fi(a,1,4,2,'OverflowAction','Wrap','RoundingMethod','Floor')

b = 

    1.2500

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 4
        FractionLength: 2

        RoundingMethod: Floor
        OverflowAction: Wrap
           ProductMode: FullPrecision
               SumMode: FullPrecision
>> bin(b)

ans =

    '0101'

对应到verilog语法可以如此表示:

wire [5:0] a = 6'b010101;
wire [3:0] b = a[5:2];

对于乘积和加法,可以自定义运算后保留的位宽。具体可参考fimath ProductMode and SumMode
分别有全精度,保留LSB/MSB,自定义精度三种模式。

ProductMode = 'FullPrecision';%乘积运算结果模式
SumMode = 'FullPrecision';%加法运算结果模式
ProductMode = 'KeepLSB';%乘积运算结果模式
ProductWordLength = 12;%乘积运算结果位宽
SumMode = 'KeepLSB';
SumWordLength = 12;
F.ProductMode = 'SpecifyPrecision';
F.ProductWordLength = 8;%乘积运算结果位宽
F.ProductFractionLength = 7;%乘积运算结果小数位宽
F.SumMode = 'SpecifyPrecision';
F.SumWordLength = 8;
F.SumFractionLength = 7;

当设置ProductModeKeepLSBKeepMSB时,需要指定ProductWordLength,分别代表保留低位和保留高位的位宽;当设定为SpecifyPrecision时,需要指定ProductWordLengthProductFractionLength;当设定为FullPrecision时,字长属性无效。
举个例子,如果\(a\)\(s(6,4)\),\(b\)\(s(7,4)\),则\(a*b=s(6+7,4+4)=s(13,8)\).
\(s(13,8)\)进行截位,只保留两位整数位,保留5位小数位,截位方式不进行多余的饱和处理,得到\(c\),结果为\(s(7,5)\).对应\(verilog\)代码为

wire [5:0] a;
wire [6:0] b;
wire [6:0] c;
wire [12:0] a_times_b;
assign a_times_b = $signed(a)*$signed(b);//full precision
assign c = a_times_b[9:3];//SpecifyPrecision

对于matlab模拟以上操作,下面是截位运算。

a=fi(1.23,1,6,4,'OverflowAction','Wrap','RoundingMethod','Floor','ProductMode','SpecifyPrecision','ProductWordLength',7,'ProductFractionLength',5);
b=fi(2.54,1,7,4,'OverflowAction','Wrap','RoundingMethod','Floor','ProductMode','SpecifyPrecision','ProductWordLength',7,'ProductFractionLength',5);
c=a*b;
disp(c)

运行结果为

   -1.0312

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 7
        FractionLength: 5

        RoundingMethod: Floor
        OverflowAction: Wrap
           ProductMode: SpecifyPrecision
     ProductWordLength: 7
 ProductFractionLength: 5
               SumMode: FullPrecision

查看\(a,b,c\)的二进制值:

>> bin(a)

ans =

    '010011'

>> bin(b)

ans =

    '0101000'

>> bin(c)

ans =

    '1011111'

进行全精度运算:

a.ProductMode='FullPrecision';
b.ProductMode='FullPrecision';
c=a*b;
disp(c)
bin(c)

结果为

    2.9688

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 13
        FractionLength: 8

        RoundingMethod: Floor
        OverflowAction: Wrap
           ProductMode: FullPrecision
               SumMode: FullPrecision

ans =

    '0001011111000'

可以看到,对全精度运算结果保留其[9:3],为指定精度运算结果,与verilog设计一致。
最后强调一下,对于乘法运算,两个操作数的'ProductMode','ProductWordLength','ProductFractionLength'属性值需要一样;
对于加法运算,两个操作数的加法属性也需要一样,否则会报错。

posted @ 2024-12-28 01:19  蕉太羊  阅读(385)  评论(1)    收藏  举报