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