1 /* ======================================================================= */
2 /* DSP_fir_cplx_d.c -- Complex FIR Filter */
3 /* Driver code implementation */
4 /* */
5 /* Rev 0.0.1 */
6 /* */
7 /* */
8 /* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ */
9 /* */
10 /* */
11 /* Redistribution and use in source and binary forms, with or without */
12 /* modification, are permitted provided that the following conditions */
13 /* are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* */
18 /* Redistributions in binary form must reproduce the above copyright */
19 /* notice, this list of conditions and the following disclaimer in the */
20 /* documentation and/or other materials provided with the */
21 /* distribution. */
22 /* */
23 /* Neither the name of Texas Instruments Incorporated nor the names of */
24 /* its contributors may be used to endorse or promote products derived */
25 /* from this software without specific prior written permission. */
26 /* */
27 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
28 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
29 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
30 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
31 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
32 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
33 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
34 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
35 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
36 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
37 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
38 /* */
39 /* ======================================================================= */
41 #include <stdio.h>
42 #include <time.h>
43 #include <stdlib.h>
44 #include <limits.h>
45 #include <c6x.h>
47 /* ======================================================================= */
48 /* Interface header files for the natural C and optimized C code */
49 /* ======================================================================= */
50 #include "DSP_fir_cplx_cn.h"
51 #include "DSP_fir_cplx.h"
53 /* Defines */
54 #if defined(__TI_EABI__)
55 #define kernel_size _kernel_size
56 #endif
58 extern char kernel_size;
60 #define FORMULA_SIZE 4
61 #define FORMULA_DEVIDE 8
62 #define CYCLE_FORMULA_NX_PT1 100
63 #define CYCLE_FORMULA_NX_PT2 92
64 #define CYCLE_FORMULA_NR_PT1 24
65 #define CYCLE_FORMULA_NR_PT2 20
66 /* inverse of [100*24 100 24 1] */
67 /* [100*20 100 20 1] */
68 /* [ 92*24 92 24 1] */
69 /* [ 92*20 92 20 1] */
70 float form_inv[FORMULA_SIZE][FORMULA_SIZE] =
71 {{ 0.0313, -0.0313, -0.0313, 0.0313},
72 {-0.6250, 0.7500, 0.6250, -0.7500},
73 {-2.8750, 2.8750, 3.1250, -3.1250},
74 {57.5000, -69.0000, -62.5000, 75.0000}
75 };
76 float form_temp [FORMULA_SIZE];
77 int form_cycle [FORMULA_SIZE];
78 int form_result[FORMULA_SIZE];
80 /* ======================================================================= */
81 /* Inform the compiler the arrays are double word alligned */
82 /* ======================================================================= */
83 #pragma DATA_ALIGN(x, 4);
84 #pragma DATA_ALIGN(h, 2);
85 #pragma DATA_ALIGN(r_c, 8);
86 #pragma DATA_ALIGN(r_i, 8);
88 /* ======================================================================= */
89 /* Parameters of fixed dataset */
90 /* ======================================================================= */
91 #define NX (256)
92 #define NH (24)
93 #define NR (100)
94 #define PAD (16)
96 /* ======================================================================= */
97 /* Initilized arrays with fixed test data */
98 /* ======================================================================= */
99 const short x[NX + 2*PAD] =
100 {
101 0x76E2, 0x8B0E, 0x4A09, 0xBA35, 0xEB22, 0xE6EB, 0x8CCF, 0xDF71, // Beginning
102 0xAACF, 0x3CE2, 0xADDA, 0x3E77, 0x8CA7, 0x6C43, 0x0F68, 0xCCF6, // PAD
104 0x5A0A, 0xCD7B, 0x8397, 0xA5BC, 0xB196, 0x963C, 0x61C8, 0xE43A,
105 0x1C8B, 0x55F2, 0x32B9, 0xB3DD, 0xE468, 0x64CE, 0x3F29, 0x2815,
106 0x99CB, 0x813E, 0xCAB7, 0xE031, 0xE954, 0x8AF2, 0x9943, 0x2780,
107 0x8DC1, 0x2C18, 0xA0EA, 0x6371, 0x9033, 0x2F1F, 0xF36D, 0xB972,
108 0x5B46, 0x9837, 0x6009, 0x7354, 0x7CBB, 0xCB4E, 0x4D5F, 0x90E4,
109 0x27B1, 0xCBF3, 0xD4CD, 0xCA53, 0xD3A7, 0xDD56, 0xEF72, 0x866E,
110 0x637B, 0x6CE5, 0x084D, 0x3A65, 0xCA8D, 0x45D0, 0x8A5D, 0xB246,
111 0x031B, 0xBC84, 0xB401, 0x9DC2, 0xB285, 0xE273, 0x6C99, 0xE626,
112 0x3D8A, 0x5E49, 0x0742, 0xDAE3, 0x7488, 0x5DF7, 0x36BD, 0xA466,
113 0xBE5F, 0x8DAB, 0x6647, 0xCF7F, 0x8A8D, 0xBFF5, 0x3E81, 0x867D,
114 0x1CD2, 0x1103, 0xF7C9, 0x8B0F, 0xAE8D, 0x03A4, 0x22BE, 0x7CC3,
115 0x739C, 0x9D08, 0xC9DF, 0xB2AA, 0x155F, 0x2D3D, 0x80AC, 0xD731,
116 0x9654, 0x0273, 0x9582, 0x5C69, 0xBC3B, 0xB957, 0x3641, 0x293F,
117 0x3533, 0x94DA, 0x1E69, 0xE5A3, 0xD45A, 0xC82B, 0x8758, 0xFAC3,
118 0x7ED0, 0x3E98, 0x4E2C, 0x3C10, 0xDED3, 0x0110, 0x3666, 0xD178,
119 0x9683, 0xD6E3, 0x3A24, 0x22E9, 0xFC9F, 0xCD7F, 0x3DE5, 0x2133,
120 0x6DE5, 0xD5F3, 0x86A9, 0x8805, 0x8695, 0x54AF, 0xE1AD, 0x5BEE,
121 0x856E, 0x8261, 0x0052, 0xA09D, 0xCBAE, 0x9EF8, 0x01F5, 0x52E1,
122 0xE2D5, 0xC8A4, 0x55F7, 0xB8A8, 0x1121, 0x6813, 0xE576, 0xBCE3,
123 0x1112, 0xB2B4, 0x4070, 0x4C3F, 0x5407, 0xF997, 0x9346, 0xD36C,
124 0xDFDE, 0x428A, 0xB497, 0x7E59, 0x5157, 0x6DBD, 0x20E0, 0x23F5,
125 0x0D70, 0x34BE, 0x8481, 0x744F, 0xD429, 0x4CBC, 0xC51A, 0xBE15,
126 0x9F01, 0xD327, 0x8468, 0xF118, 0x3D36, 0x8B2D, 0xF0EC, 0x4CA5,
127 0xEDE8, 0xCE3D, 0x3A04, 0xF5AC, 0x5EB5, 0x2187, 0x7BCE, 0x077C,
128 0xFCFD, 0xDF80, 0xC98B, 0xE564, 0xE27F, 0xE342, 0xB89A, 0xF7D3,
129 0x4F39, 0xBA12, 0xF418, 0x0337, 0x6F4B, 0x13D7, 0x4B05, 0x54A1,
130 0x2394, 0x5020, 0xFC80, 0x913E, 0x8252, 0x889D, 0x1FE9, 0xEBDE,
131 0x96A4, 0x07DD, 0x959E, 0x80B0, 0x56EB, 0xF72D, 0xA67D, 0xCFC3,
132 0xBD24, 0x437E, 0x08C7, 0xE546, 0xFC8E, 0x7F3E, 0x5B7A, 0x85A7,
133 0x5609, 0xCF9D, 0xFB15, 0x6ED7, 0x9BF4, 0x3289, 0x5037, 0x0443,
134 0x9B2D, 0x1E91, 0x0DE0, 0x60DB, 0xF474, 0xAC45, 0x0A2D, 0xBFCE,
135 0x4848, 0x8093, 0x577F, 0x75CB, 0x2727, 0x898B, 0xF1D3, 0x2781,
137 0xCC91, 0xC1DA, 0x2F0A, 0x933F, 0xE304, 0x8432, 0x7602, 0x4CB3, // Ending
138 0xE3A0, 0xFA3F, 0x73BA, 0x6F6D, 0xB144, 0xAB32, 0x5C31, 0x7D9D // PAD
139 };
141 const short h[2*NH + 2*PAD] =
142 {
143 0x76E2, 0x8B0E, 0x4A09, 0xBA35, 0xEB22, 0xE6EB, 0x8CCF, 0xDF71, // Beginning
144 0xAACF, 0x3CE2, 0xADDA, 0x3E77, 0x8CA7, 0x6C43, 0x0F68, 0xCCF6, // PAD
146 0x5A0A, 0xCD7B, 0x8397, 0xA5BC, 0xB196, 0x963C, 0x61C8, 0xE43A,
147 0x1C8B, 0x55F2, 0x32B9, 0xB3DD, 0xE468, 0x64CE, 0x3F29, 0x2815,
148 0x99CB, 0x813E, 0xCAB7, 0xE031, 0xE954, 0x8AF2, 0x9943, 0x2780,
149 0x8DC1, 0x2C18, 0xA0EA, 0x6371, 0x9033, 0x2F1F, 0xF36D, 0xB972,
150 0x5B46, 0x9837, 0x6009, 0x7354, 0x7CBB, 0xCB4E, 0x4D5F, 0x90E4,
151 0x27B1, 0xCBF3, 0xD4CD, 0xCA53, 0xD3A7, 0xDD56, 0xEF72, 0x866E,
153 0xCC91, 0xC1DA, 0x2F0A, 0x933F, 0xE304, 0x8432, 0x7602, 0x4CB3, // Ending
154 0xE3A0, 0xFA3F, 0x73BA, 0x6F6D, 0xB144, 0xAB32, 0x5C31, 0x7D9D // PAD
155 };
157 short r_c[2*NR + 2*PAD];
158 short r_i[2*NR + 2*PAD];
160 /* ======================================================================= */
161 /* Generate pointers to skip beyond array padding */
162 /* ======================================================================= */
163 const short *const ptr_x = x + 2*(NH-1) + PAD;
164 const short *const ptr_h = h + PAD;
165 short *const ptr_r_c = r_c + PAD;
166 short *const ptr_r_i = r_i + PAD;
168 /* ======================================================================= */
169 /* Prototypes for timing functions */
170 /* ======================================================================= */
171 clock_t time_c(int nh, int nr);
172 clock_t time_i(int nh, int nr);
174 /* ======================================================================= */
175 /* MAIN -- Top level driver for testing the algorithm */
176 /* ======================================================================= */
177 int main()
178 {
179 clock_t t_overhead, t_start, t_stop;
180 clock_t t_c, t_i;
181 int i, j, nh, nr, fail = 0;
182 int form_error = 0;
184 /* =================================================================== */
185 /* Initialize timer for clock */
186 TSCL= 0,TSCH=0;
187 /* Compute overhead of calling _itoll(TSCH, TSCL) twice to get timing info */
188 /* =================================================================== */
189 t_start = _itoll(TSCH, TSCL);
190 t_stop = _itoll(TSCH, TSCL);
191 t_overhead = t_stop - t_start;
193 for(nr = 8, i = 1; nr <= NR; nr += 4) {
194 for(nh = 4; nh <= NH; i++, nh += 2) {
195 /* =================================================================== */
196 /* Force uninitialized arrays to fixed values */
197 /* =================================================================== */
198 memset(r_c, 0x5A, sizeof(r_c));
199 memset(r_i, 0x5A, sizeof(r_i));
201 /* =================================================================== */
202 /* Call the individual timing routines, and subtract off overhead */
203 /* =================================================================== */
204 t_c = time_c(nh, nr) - t_overhead; // Calculate time to run Natural C Algorithm
205 t_i = time_i(nh, nr) - t_overhead; // Calculate time to run Optimized C Algorithm
207 /* =================================================================== */
208 /* Print timing results */
209 /* =================================================================== */
210 printf("DSP_fir_cplx\tIter#: %d\t", i);
212 /* =================================================================== */
213 /* Check the results arrays, and report any failures */
214 /* =================================================================== */
215 if (memcmp(r_i, r_c, sizeof(r_c))) {
216 fail++;
217 printf("Result Failure (r_i)");
218 }
219 else
220 printf("Result Successful (r_i)");
222 printf("\tNR = %d\tNH = %d\tnatC: %d\toptC: %d\n", nr, nh, t_c, t_i);
224 if (nr == CYCLE_FORMULA_NX_PT1 && nh == CYCLE_FORMULA_NR_PT1)
225 form_cycle[0] = t_i;
226 if (nr == CYCLE_FORMULA_NX_PT1 && nh == CYCLE_FORMULA_NR_PT2)
227 form_cycle[1] = t_i;
228 if (nr == CYCLE_FORMULA_NX_PT2 && nh == CYCLE_FORMULA_NR_PT1)
229 form_cycle[2] = t_i;
230 if (nr == CYCLE_FORMULA_NX_PT2 && nh == CYCLE_FORMULA_NR_PT2)
231 form_cycle[3] = t_i;
232 }
233 }
235 /* Provide memory information */
236 #ifdef __TI_COMPILER_VERSION__ // for TI compiler only
237 printf("Memory: %d bytes\n", &kernel_size);
238 #endif
240 /* Provide profiling information */
241 for (i = 0; i < FORMULA_SIZE; i++) {
242 form_temp[i] = 0;
243 for (j = 0; j < FORMULA_SIZE; j++) {
244 form_temp[i] += form_inv[i][j] * form_cycle[j];
245 }
246 if (i != (FORMULA_SIZE-1)) {
247 form_result[i] = (int) (form_temp[i] * FORMULA_DEVIDE + 0.5);
248 if ((form_result[i] - form_temp[i] * FORMULA_DEVIDE) > 0.1 ||
249 (form_result[i] - form_temp[i] * FORMULA_DEVIDE) < -0.1) {
250 form_error = 1;
251 }
252 }
253 else {
254 form_result[i] = (int) (form_temp[i] + 0.5);
255 }
256 }
258 if (!form_error) {
259 printf("Cycles: ");
260 if (form_result[0])
261 printf("%d/%d*Nr*Nh + ", form_result[0], FORMULA_DEVIDE);
262 if (form_result[1])
263 printf("%d/%d*Nr + ", form_result[1], FORMULA_DEVIDE);
264 if (form_result[2])
265 printf("%d/%d*Nh + ", form_result[2], FORMULA_DEVIDE);
266 if (form_result[3])
267 printf("%d\n", form_result[3]);
268 }
269 else
270 printf("Cycles Formula Not Available\n");
272 return(fail);
273 }
275 /* ======================================================================= */
276 /* Prototypes for timing functions */
277 /* ======================================================================= */
278 clock_t time_c(int nh, int nr)
279 {
280 clock_t t_start, t_stop;
282 t_start = _itoll(TSCH, TSCL);
283 DSP_fir_cplx_cn(ptr_x, ptr_h, ptr_r_c, nh, nr);
284 t_stop = _itoll(TSCH, TSCL);
285 return t_stop - t_start;
286 }
288 clock_t time_i(int nh, int nr)
289 {
290 clock_t t_start, t_stop;
292 t_start = _itoll(TSCH, TSCL);
293 DSP_fir_cplx(ptr_x, ptr_h, ptr_r_i, nh, nr);
294 t_stop = _itoll(TSCH, TSCL);
295 return t_stop - t_start;
296 }
298 /* ======================================================================= */
299 /* End of file: DSP_fir_cplx_d.c */
300 /* ----------------------------------------------------------------------- */
301 /* Copyright (c) 2011 Texas Instruments, Incorporated. */
302 /* All Rights Reserved. */
303 /* ======================================================================= */