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