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