1 #include "FIRF16.h"
2 #include <stdio.h>
3 #include "Error.h"
4 
5 #define SNR_THRESHOLD 60
6 
7 /*
8 
9 Reference patterns are generated with
10 a double precision computation.
11 
12 */
13 #define REL_ERROR (2.0e-2)
14 
15 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
16 static __ALIGNED(8) float16_t coeffArray[32];
17 #endif
18 
checkInnerTail(float16_t * b)19 static void checkInnerTail(float16_t *b)
20 {
21     ASSERT_TRUE(b[0] == 0.0f);
22     ASSERT_TRUE(b[1] == 0.0f);
23     ASSERT_TRUE(b[2] == 0.0f);
24     ASSERT_TRUE(b[3] == 0.0f);
25 }
26 
27 // Coef must be padded to a multiple of 4
28 #define FIRCOEFPADDING 2
29 
test_fir_f16()30     void FIRF16::test_fir_f16()
31     {
32 
33 
34         const int16_t *configp = configs.ptr();
35         float16_t *statep = state.ptr();
36         const float16_t *orgcoefsp = coefs.ptr();
37 
38         const float16_t *coefsp;
39         const float16_t *inputp = inputs.ptr();
40         float16_t *outp = output.ptr();
41 
42         unsigned long i;
43 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
44         int j;
45 #endif
46         int blockSize;
47         int numTaps;
48 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
49         int round;
50 #endif
51 
52 
53         /*
54 
55         Python script is generating different tests with
56         different blockSize and numTaps.
57 
58         We loop on those configs.
59 
60         */
61         for(i=0; i < configs.nbSamples() ; i += 2)
62         {
63            blockSize = configp[0];
64            numTaps = configp[1];
65 
66 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
67             /* Copy coefficients and pad to zero
68            */
69            memset(coeffArray,127,32*sizeof(float16_t));
70            round = numTaps >> FIRCOEFPADDING;
71            if ((round << FIRCOEFPADDING) < numTaps)
72            {
73              round ++;
74            }
75            round = round<<FIRCOEFPADDING;
76            memset(coeffArray,0,round*sizeof(float16_t));
77 
78            //printf("blockSize=%d, numTaps=%d, round=%d (%d)\n",blockSize,numTaps,round,round - numTaps);
79 
80 
81            for(j=0;j < numTaps; j++)
82            {
83               coeffArray[j] = orgcoefsp[j];
84            }
85 
86            coefsp = coeffArray;
87 #else
88            coefsp = orgcoefsp;
89 #endif
90 
91            /*
92 
93            The filter is initialized with the coefs, blockSize and numTaps.
94 
95            */
96            arm_fir_init_f16(&this->S,numTaps,coefsp,statep,blockSize);
97 
98            /*
99 
100            Input pointer is reset since the same input pattern is used
101 
102            */
103            inputp = inputs.ptr();
104 
105            /*
106 
107            Python script is filtering a 2*blockSize number of samples.
108            We do the same filtering in two pass to check (indirectly that
109            the state management of the fir is working.)
110 
111            */
112 
113            arm_fir_f16(&this->S,inputp,outp,blockSize);
114            outp += blockSize;
115            checkInnerTail(outp);
116 
117            inputp += blockSize;
118            arm_fir_f16(&this->S,inputp,outp,blockSize);
119            outp += blockSize;
120            checkInnerTail(outp);
121 
122            configp += 2;
123            orgcoefsp += numTaps;
124 
125         }
126 
127 
128         ASSERT_EMPTY_TAIL(output);
129 
130         ASSERT_SNR(output,ref,(float16_t)SNR_THRESHOLD);
131 
132         ASSERT_REL_ERROR(output,ref,REL_ERROR);
133 
134     }
135 
136 
setUp(Testing::testID_t id,std::vector<Testing::param_t> & params,Client::PatternMgr * mgr)137     void FIRF16::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
138     {
139 
140        (void)params;
141 
142        switch(id)
143        {
144         case FIRF16::TEST_FIR_F16_1:
145         break;
146 
147        }
148 
149 
150        inputs.reload(FIRF16::FIRINPUTS_F16_ID,mgr);
151        coefs.reload(FIRF16::FIRCOEFS_F16_ID,mgr);
152        configs.reload(FIRF16::FIRCONFIGS_S16_ID,mgr);
153        ref.reload(FIRF16::FIRREFS_F16_ID,mgr);
154 
155        output.create(ref.nbSamples(),FIRF16::OUT_F16_ID,mgr);
156        /* > Max  8*ceil(blockSize,8) +  blockSize + numTaps - 1 as generated by Python script */
157        state.create(47+47,FIRF16::OUT_F16_ID,mgr);
158     }
159 
tearDown(Testing::testID_t id,Client::PatternMgr * mgr)160     void FIRF16::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
161     {
162         (void)id;
163         output.dump(mgr);
164     }
165