97537dd13daac3fa58917d92a8de18ead578a36f
[ep-processor-libraries/dsplib.git] / ti / dsplib / src / DSPF_sp_fircirc / c674 / 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        3
61 #define CYCLE_FORMULA_NY_PT1  32
62 #define CYCLE_FORMULA_NY_PT2  20 
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 /*            [20*16 20 16 1] */
69 /*            [20*12 20 12 1] */
71 float form_inv[FORMULA_SIZE][FORMULA_SIZE] = 
72 {{ 0.0208,   -0.0208,   -0.0208,    0.0208},
73  {-0.2500,    0.3333,    0.2500,   -0.3333},
74  {-0.4167,    0.4167,    0.6667,   -0.6667},
75  { 5.0000,   -6.6667,   -8.0000,   10.6667}
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()
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 = 0, max_pct_diff = 0;
122   
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;
131   
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);
137   
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));
145       
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;
151       
152         printf("DSPF_sp_fircirc\tIter#: %d\t", k++);
153       
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);
173       
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
188   
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     }
206   
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");    
220   
223 /* ======================================================================= */
224 /* Prototypes for timing functions                                         */
225 /* ======================================================================= */
226 clock_t time_cn(int nh, int ny)
228     clock_t t_start, t_stop;
229   
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);
236   
237     return t_stop - t_start;
240 clock_t time_i(int nh, int ny)
242     clock_t t_start, t_stop;
243     
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);
250   
251     return t_stop - t_start;
254 void UTIL_fillRandSP(float *ptr_x, int N, float factor)
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;
264 void UTIL_fillRandFilterSP(float *ptr_h, int N)
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     }
278 /* ======================================================================= */
279 /*  End of file:  DSPF_sp_fircirc_d.c                                      */
280 /* ----------------------------------------------------------------------- */
281 /*            Copyright (c) 2011 Texas Instruments, Incorporated.          */
282 /*                           All Rights Reserved.                          */
283 /* ======================================================================= */