[ep-processor-libraries/dsplib.git] / ti / dsplib / src / DSPF_sp_fircirc / c66 / DSPF_sp_fircirc_d.c
1 /* ======================================================================= */
2 /* DSPF_sp_fircirc_d.c -- Circular FIR Filter */
3 /* Driver code; tests kernel and reports result in stdout */
4 /* */
5 /* Rev 0.0.1 */
6 /* */
7 /* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ */
8 /* */
9 /* */
10 /* Redistribution and use in source and binary forms, with or without */
11 /* modification, are permitted provided that the following conditions */
12 /* are met: */
13 /* */
14 /* Redistributions of source code must retain the above copyright */
15 /* notice, this list of conditions and the following disclaimer. */
16 /* */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in the */
19 /* documentation and/or other materials provided with the */
20 /* distribution. */
21 /* */
22 /* Neither the name of Texas Instruments Incorporated nor the names of */
23 /* its contributors may be used to endorse or promote products derived */
24 /* from this software without specific prior written permission. */
25 /* */
26 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
27 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
28 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
29 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
30 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
31 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
32 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
33 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
34 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
35 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
36 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37 /* */
38 /* ======================================================================= */
40 #include <stdio.h>
41 #include <time.h>
42 #include <stdlib.h>
43 #include <limits.h>
44 #include <c6x.h>
46 /* ======================================================================= */
47 /* Interface header files for the natural C and optimized C code */
48 /* ======================================================================= */
49 #include "DSPF_sp_fircirc_cn.h"
50 #include "DSPF_sp_fircirc.h"
52 /* Defines */
53 #if defined(__TI_EABI__)
54 #define kernel_size _kernel_size
55 #endif
57 extern char kernel_size;
58 #define FLT_THRES 1E-20
59 #define FORMULA_SIZE 4
60 #define FORMULA_DEVIDE 4
61 #define CYCLE_FORMULA_NY_PT1 32
62 #define CYCLE_FORMULA_NY_PT2 28
63 #define CYCLE_FORMULA_NH_PT1 16
64 #define CYCLE_FORMULA_NH_PT2 12
66 /* inverse of [32*16 32 16 1] */
67 /* [32*12 32 12 1] */
68 /* [28*16 28 16 1] */
69 /* [28*12 28 12 1] */
71 float form_inv[FORMULA_SIZE][FORMULA_SIZE] =
72 {{ 0.0625, -0.0625, -0.0625, 0.0625},
73 {-0.7500, 1.0000, 0.7500, -1.0000},
74 {-1.7500, 1.7500, 2.0000, -2.0000},
75 {21.0000, -28.0000, -24.0000, 32.0000}
76 };
78 float form_temp [FORMULA_SIZE];
79 int form_cycle [FORMULA_SIZE];
80 int form_result[FORMULA_SIZE];
81 /* ======================================================================= */
82 /* Tell compiler arrays are double word alligned */
83 /* ======================================================================= */
84 #pragma DATA_ALIGN(ptr_y_i, 8);
85 #pragma DATA_ALIGN(ptr_y_cn, 8);
86 #pragma DATA_ALIGN(ptr_h, 8);
87 #pragma DATA_ALIGN(ptr_x, 16); // generally: align to 1 << (NC + 1)
89 /* ======================================================================= */
90 /* Parameters of fixed dataset */
91 /* ======================================================================= */
92 #define NY (32)
93 #define NH (16)
94 #define NC (3)
96 float ptr_y_i[NY];
97 float ptr_y_cn[NY];
98 float ptr_x[1 << (NC + 1)];
99 float ptr_h[NH];
101 /* ======================================================================= */
102 /* Prototypes for timing functions */
103 /* ======================================================================= */
104 clock_t time_i(int nh, int ny);
105 clock_t time_cn(int nh, int ny);
107 /* ======================================================================= */
108 /* Prototypes for utility functions */
109 /* ======================================================================= */
110 void UTIL_fillRandSP(float *ptr_x, int N, float factor);
111 void UTIL_fillRandFilterSP(float *ptr_h, int N);
113 /* ======================================================================= */
114 /* Main -- Top level driver for testing the algorithm */
115 /* ======================================================================= */
116 void main()
117 {
118 clock_t t_overhead, t_start, t_stop, t_opt, t_cn;
119 int i, j, k = 1, ny, nh;
120 int form_error = 0;
121 float pct_diff, max_pct_diff = 0;
123 /* ------------------------------------------------------------------- */
124 /* Compute the overhead of calling clock twice to get timing info */
125 /* ------------------------------------------------------------------- */
126 /* Initialize timer for clock */
127 TSCL= 0,TSCH=0;
128 t_start = _itoll(TSCH, TSCL);
129 t_stop = _itoll(TSCH, TSCL);
130 t_overhead = t_stop - t_start;
132 /* ------------------------------------------------------------------- */
133 /* Generate random input (with zero padding) and MA filter. */
134 /* ------------------------------------------------------------------- */
135 UTIL_fillRandSP(ptr_x, 1 << (NC + 1), 10.0);
136 UTIL_fillRandFilterSP(ptr_h, NH);
138 for(ny = 8; ny <= NY; ny += 4) {
139 for(nh = 4; nh <= NH; nh += 4) {
140 /* --------------------------------------------------------------- */
141 /* Clear state/output buffers with fixed values. */
142 /* --------------------------------------------------------------- */
143 memset(ptr_y_i, 0, sizeof(ptr_y_i));
144 memset(ptr_y_cn, 0, sizeof(ptr_y_cn));
146 /* --------------------------------------------------------------- */
147 /* Call the individual timing routines */
148 /* --------------------------------------------------------------- */
149 t_opt = time_i(nh, ny) - t_overhead;
150 t_cn = time_cn(nh, ny) - t_overhead;
152 printf("DSPF_sp_fircirc\tIter#: %d\t", k++);
154 /* --------------------------------------------------------------- */
155 /* compute percent difference and track max difference */
156 /* --------------------------------------------------------------- */
157 for(i=0; i< ny; i++) {
158 pct_diff = 0;
159 if ((abs(ptr_y_i[i]) > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES))
160 pct_diff = (ptr_y_cn[i] - ptr_y_i[i]) / ptr_y_cn[i] * 100.0;
161 if (pct_diff < 0) pct_diff *= -1;
162 if (pct_diff > max_pct_diff) max_pct_diff = pct_diff;
163 }
164 if (max_pct_diff > 0.05)
165 printf("Result Failure, max_pct_diff = %f", max_pct_diff);
166 else
167 printf("Result Successful");
169 /* --------------------------------------------------------------- */
170 /* Print timing results */
171 /* --------------------------------------------------------------- */
172 printf("\tNX = %d\tNH = %d\tnatC: %d\toptC: %d\n", ny, nh, t_cn, t_opt);
174 if (ny == CYCLE_FORMULA_NY_PT1 && nh == CYCLE_FORMULA_NH_PT1)
175 form_cycle[0] = t_opt;
176 if (ny == CYCLE_FORMULA_NY_PT1 && nh == CYCLE_FORMULA_NH_PT2)
177 form_cycle[1] = t_opt;
178 if (ny == CYCLE_FORMULA_NY_PT2 && nh == CYCLE_FORMULA_NH_PT1)
179 form_cycle[2] = t_opt;
180 if (ny == CYCLE_FORMULA_NY_PT2 && nh == CYCLE_FORMULA_NH_PT2)
181 form_cycle[3] = t_opt;
182 }
183 }
184 /* Provide memory information */
185 #ifdef __TI_COMPILER_VERSION__ // for TI compiler only
186 printf("Memory: %d bytes\n", &kernel_size);
187 #endif
189 /* Provide profiling information */
190 for (i = 0; i < FORMULA_SIZE; i++) {
191 form_temp[i] = 0;
192 for (j = 0; j < FORMULA_SIZE; j++) {
193 form_temp[i] += form_inv[i][j] * form_cycle[j];
194 }
195 if (i != (FORMULA_SIZE-1)) {
196 form_result[i] = (int) (form_temp[i] * FORMULA_DEVIDE + 0.5);
197 if ((form_result[i] - form_temp[i] * FORMULA_DEVIDE) > 0.1 ||
198 (form_result[i] - form_temp[i] * FORMULA_DEVIDE) < -0.1) {
199 form_error = 1;
200 }
201 }
202 else {
203 form_result[i] = (int) (form_temp[i] + 0.5);
204 }
205 }
207 if (!form_error) {
208 printf("Cycles: ");
209 if (form_result[0])
210 printf("%d/%d*Ny*Nh + ", form_result[0], FORMULA_DEVIDE);
211 if (form_result[1])
212 printf("%d/%d*Ny + ", form_result[1], FORMULA_DEVIDE);
213 if (form_result[2])
214 printf("%d/%d*Nh + ", form_result[2], FORMULA_DEVIDE);
215 if (form_result[3])
216 printf("%d\n", form_result[3]);
217 }
218 else
219 printf("Cycles Formula Not Available\n");
221 }
223 /* ======================================================================= */
224 /* Prototypes for timing functions */
225 /* ======================================================================= */
226 clock_t time_cn(int nh, int ny)
227 {
228 clock_t t_start, t_stop;
230 /* ------------------------------------------------------------------- */
231 /* Measure the cycle count */
232 /* ------------------------------------------------------------------- */
233 t_start = _itoll(TSCH, TSCL);
234 DSPF_sp_fircirc_cn(ptr_x, ptr_h, ptr_y_cn, 0, NC, nh, ny);
235 t_stop = _itoll(TSCH, TSCL);
237 return t_stop - t_start;
238 }
240 clock_t time_i(int nh, int ny)
241 {
242 clock_t t_start, t_stop;
244 /* ------------------------------------------------------------------- */
245 /* Measure the cycle count */
246 /* ------------------------------------------------------------------- */
247 t_start = _itoll(TSCH, TSCL);
248 DSPF_sp_fircirc(ptr_x, ptr_h, ptr_y_i, 0, NC, nh, ny);
249 t_stop = _itoll(TSCH, TSCL);
251 return t_stop - t_start;
252 }
254 void UTIL_fillRandSP(float *ptr_x, int N, float factor)
255 {
256 float rand_midpoint = RAND_MAX / 2.0;
257 int i;
259 // fill array with floats in the range (-factor, factor)
260 for (i = 0; i < N; i++)
261 ptr_x[i] = ((rand() - rand_midpoint) / rand_midpoint) * factor;
262 }
264 void UTIL_fillRandFilterSP(float *ptr_h, int N)
265 {
266 float frand_max = RAND_MAX, pair_sum = 2.0 / N;
267 int i;
269 // create a moving average filter of length N
270 // filter taps must be non-negative and sum to 1
271 // N must be an even number
272 for (i = 0; i < N / 2; i++)
273 {
274 ptr_h[i] = (rand() / frand_max) * pair_sum;
275 ptr_h[N - 1 - i] = pair_sum - ptr_h[i];
276 }
277 }
278 /* ======================================================================= */
279 /* End of file: DSPF_sp_fircirc_d.c */
280 /* ----------------------------------------------------------------------- */
281 /* Copyright (c) 2011 Texas Instruments, Incorporated. */
282 /* All Rights Reserved. */
283 /* ======================================================================= */