FFTLIB User Guide
FFTLIB_fft1d_i32f_c32fc_o32fc_ci.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 **+--------------------------------------------------------------------------+**
3 **| **** |**
4 **| **** |**
5 **| ******o*** |**
6 **| ********_///_**** |**
7 **| ***** /_//_/ **** |**
8 **| ** ** (__/ **** |**
9 **| ********* |**
10 **| **** |**
11 **| *** |**
12 **| |**
13 **| Copyright (c) 2017 Texas Instruments Incorporated |**
14 **| ALL RIGHTS RESERVED |**
15 **| |**
16 **| Permission to use, copy, modify, or distribute this software, |**
17 **| whether in part or in whole, for any purpose is forbidden without |**
18 **| a signed licensing agreement and NDA from Texas Instruments |**
19 **| Incorporated (TI). |**
20 **| |**
21 **| TI makes no representation or warranties with respect to the |**
22 **| performance of this computer program, and specifically disclaims |**
23 **| any responsibility for any damages, special or consequential, |**
24 **| connected with the use of this program. |**
25 **| |**
26 **+--------------------------------------------------------------------------+**
27 *******************************************************************************/
28 
29 #include "../../../common/c71/FFTLIB_debug.h"
30 #include "../../FFTLIB_fft1dBatched_i32fc_c32fc_o32fc/FFTLIB_fft1dBatched_i32fc_c32fc_o32fc.h"
31 #include "../../FFTLIB_fft1d_i32fc_c32fc_o32fc/FFTLIB_fft1d_i32fc_c32fc_o32fc.h"
32 #include "../FFTLIB_fft1d_i32f_c32fc_o32fc.h"
33 
34 #define SE_PARAM_BASE (0x0000)
35 #define SE0_PARAM_OFFSET (SE_PARAM_BASE)
36 #define SE1_PARAM_OFFSET (SE0_PARAM_OFFSET + SE_PARAM_SIZE)
37 #define SE1_PARAM_OFFSET_LAST (SE1_PARAM_OFFSET + SE_PARAM_SIZE)
38 #define SA0_PARAM_OFFSET (SE1_PARAM_OFFSET_LAST + SE_PARAM_SIZE)
39 #define SA1_PARAM_OFFSET (SA0_PARAM_OFFSET + SE_PARAM_SIZE)
40 
41 typedef typename c7x::cfloat_vec CV;
42 typedef typename c7x::float_vec V;
43 
46  FFTLIB_bufParams1D_t *bufParamsX,
47  FFTLIB_F32 *pW,
48  FFTLIB_bufParams1D_t *bufParamsW,
49  FFTLIB_F32 *pXFFT,
50  FFTLIB_bufParams1D_t *bufParamsXFFT,
51  FFTLIB_F32 *pSf,
52  FFTLIB_bufParams1D_t *bufParamsSf,
53  FFTLIB_F32 *pY,
54  FFTLIB_bufParams1D_t *bufParamsY,
55  void *pBlock)
56 {
58 
59  /* #if defined(FFTLIB_CHECK_PARAMS) || \ */
60  /* defined(FFTLIB_FFT1D_I32FC_C32FC_O32FC_CHECK_PARAMS) */
61  /* status = FFTLIB_fft1d_i32f_c32fc_o32fc_checkParams ( */
62  /* pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pBlock); */
63  /* if (status == FFTLIB_SUCCESS) */
64  /* #endif */
65  {
66 
67  uint32_t numPoints;
68  __SE_TEMPLATE_v1 se0_param = __gen_SE_TEMPLATE_v1 ();
69  __SE_TEMPLATE_v1 se1_param = __gen_SE_TEMPLATE_v1 ();
70  __SA_TEMPLATE_v1 sa0_param = __gen_SA_TEMPLATE_v1 ();
71  __SA_TEMPLATE_v1 sa1_param = __gen_SA_TEMPLATE_v1 ();
72 
73  // se1 params for last loop
74  __SE_TEMPLATE_v1 se1_param_last = __gen_SE_TEMPLATE_v1 ();
75  FFTLIB_bufParams1D_t bufParamsX_FFT;
76 
77  numPoints = bufParamsX->dim_x;
78 
79  bufParamsX_FFT.dim_x = numPoints;
80 
82  (FFTLIB_F32 *) pX, &bufParamsX_FFT, (FFTLIB_F32 *) pW,
83  &bufParamsX_FFT, (FFTLIB_F32 *) pXFFT, &bufParamsX_FFT,
84  (numPoints >> 1), 1, &((uint8_t *) pBlock)[5 * SE_PARAM_SIZE]);
85 
86  uint32_t elementCount = c7x::element_count_of<CV>::value;
87  uint32_t SEBlocks = (numPoints >> 1) / elementCount;
88  uint32_t offset = (((uint64_t) pSf - (uint64_t) pXFFT)) / sizeof (cfloat);
89 
90  se0_param.ICNT0 = elementCount;
91  se0_param.ICNT1 = 2;
92  se0_param.DIM1 = offset;
93  se0_param.ICNT2 = SEBlocks;
94  se0_param.DIM2 = elementCount;
95 
96  se0_param.ELETYPE = __SE_ELETYPE_32BIT_CMPLX_SWAP;
97  se0_param.VECLEN = c7x::se_veclen<CV>::value;
98  se0_param.DIMFMT = __SE_DIMFMT_3D;
99  *((__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE0_PARAM_OFFSET)) =
100  se0_param;
101 
102  se1_param.ICNT0 = elementCount;
103  se1_param.ICNT1 = 2;
104  se1_param.DIM1 = offset + (numPoints >> 1) - 1;
105  se1_param.ICNT2 = SEBlocks;
106  se1_param.DIM2 = -elementCount;
107 
108  se1_param.DIR = __SE_DIR_DEC;
109  se1_param.ELETYPE = __SE_ELETYPE_32BIT_CMPLX_SWAP;
110  se1_param.VECLEN = c7x::se_veclen<CV>::value;
111  se1_param.DIMFMT = __SE_DIMFMT_3D;
112  *((__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE1_PARAM_OFFSET)) =
113  se1_param;
114 
115  /* sa0_param = (0); */
116  sa0_param.ICNT0 = numPoints >> 1;
117  sa0_param.VECLEN = c7x::sa_veclen<CV>::value;
118  sa0_param.DIMFMT = __SA_DIMFMT_1D;
119  *((__SA_TEMPLATE_v1 *) ((uint8_t *) pBlock + SA0_PARAM_OFFSET)) =
120  sa0_param;
121 
122  se1_param_last.ICNT0 = numPoints >> 1;
123  se1_param_last.DIR = __SE_DIR_DEC;
124  se1_param_last.ELETYPE = __SE_ELETYPE_32BIT_CMPLX_NOSWAP;
125  se1_param_last.VECLEN = c7x::se_veclen<CV>::value;
126  se1_param_last.DIMFMT = __SE_DIMFMT_1D;
127  *((__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE1_PARAM_OFFSET_LAST)) =
128  se1_param_last;
129 
130  sa1_param.ICNT0 = elementCount;
131  sa1_param.ICNT1 = (numPoints >> 1) / (elementCount);
132  sa1_param.DIM1 = -(elementCount);
133  sa1_param.VECLEN = c7x::sa_veclen<CV>::value;
134  sa1_param.DIMFMT = __SA_DIMFMT_2D;
135  *((__SA_TEMPLATE_v1 *) ((uint8_t *) pBlock + SA1_PARAM_OFFSET)) =
136  sa1_param;
137  }
138  return (status);
139 }
140 
143  FFTLIB_bufParams1D_t *bufParamsX,
144  FFTLIB_F32 *restrict pW,
145  FFTLIB_bufParams1D_t *bufParamsW,
146  FFTLIB_F32 *restrict pXFFT,
147  FFTLIB_bufParams1D_t *bufParamsXFFT,
148  FFTLIB_F32 *restrict pSf,
149  FFTLIB_bufParams1D_t *bufParamsSf,
150  FFTLIB_F32 *restrict pY,
151  FFTLIB_bufParams1D_t *bufParamsY,
152  void *pBlock)
153 {
154 
155  FFTLIB_STATUS status = FFTLIB_SUCCESS;
156 
157  uint32_t numPoints;
158  FFTLIB_bufParams1D_t bufParamsX_FFT;
159 
160  numPoints = bufParamsX->dim_x;
161  bufParamsX_FFT.dim_x = numPoints;
162 
163  /* typedef typename c7x::cfloat_vec CV; */
164  /* typedef typename c7x::float_vec V; */
165 
167  (FFTLIB_F32 *) pX, &bufParamsX_FFT, (FFTLIB_F32 *) pW, &bufParamsX_FFT,
168  (FFTLIB_F32 *) pXFFT, &bufParamsX_FFT, (numPoints >> 1), 1,
169  &((uint8_t *) pBlock)[5 * SE_PARAM_SIZE]);
170 
171  FFTLIB_asm (" MARK 6");
172 
173  __SE_TEMPLATE_v1 se0Params = __gen_SE_TEMPLATE_v1 (); // SE parameter vector
174  __SE_TEMPLATE_v1 se1Params = __gen_SE_TEMPLATE_v1 (); // SE parameter vector
175 
176  /* __SE_TEMPLATE_v1 se1ParamsLast = __gen_SE_TEMPLATE_v1 (); */
177  __SA_TEMPLATE_v1 sa0Params = __gen_SA_TEMPLATE_v1 ();
178  __SA_TEMPLATE_v1 sa1Params = __gen_SA_TEMPLATE_v1 ();
179 
180  se0Params = *(__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE0_PARAM_OFFSET);
181  se1Params = *(__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE1_PARAM_OFFSET);
182  sa0Params = *(__SA_TEMPLATE_v1 *) ((uint8_t *) pBlock + SA0_PARAM_OFFSET);
183  sa1Params = *(__SA_TEMPLATE_v1 *) ((uint8_t *) pBlock + SA1_PARAM_OFFSET);
184 
185  /* se1ParamsLast = */
186  /* *(__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE1_PARAM_OFFSET_LAST); */
187 
188  __SE0_OPEN (&(pXFFT[0]), se0Params);
189  __SE1_OPEN (&(pXFFT[numPoints + 2]), se1Params);
190  __SA0_OPEN (sa0Params);
191  __SA1_OPEN (sa1Params);
192 
193  CV var0, var1;
194  CV temp0, temp1;
195  CV sFA, sFB;
196  CV regStore0, regStore1;
197 
198  __vpred tmp;
199  CV *addr;
200 
201 #if defined(_HOST_BUILD)
202  c7x::ulong_vec xorVec = (c7x::ulong_vec) (0x0000000080000000);
203 
204 #else
205  c7x::ulong_vec xorVec = (0x0000000080000000);
206 #endif
207 
208  uint32_t i = 0;
209  uint32_t elementCount = c7x::element_count_of<CV>::value;
210 
211  /* printf ("\npXFFT Opt below:\n\n"); */
212  /* for (i = 0; i < numPoints; i++) { */
213  /* printf ("%.2f, ", pXFFT[i]); */
214  /* } */
215  /* printf ("\n\n"); */
216 
217  /* printf ("\npXFFT:%p, pSf:%p, pSf- pXFFT:%d\n", pXFFT, pSf, */
218  /* ((uint64_t) pSf - (uint64_t) pXFFT)); */
219 
220  FFTLIB_asm (" MARK 8");
221 
222 #pragma MUST_ITERATE(8, , 8)
223 #pragma UNROLL(8)
224  for (i = 0; i < (numPoints >> 1) / (elementCount); i++) {
225  var0 = c7x::strm_eng<0, CV>::get_adv ();
226  var1 = c7x::strm_eng<1, CV>::get_adv ();
227 
228  sFA = c7x::strm_eng<0, CV>::get_adv ();
229  sFB = c7x::strm_eng<1, CV>::get_adv ();
230 
231  temp0 = (__complex_multiply (var0, c7x::as_cfloat_vec (sFA)));
232  temp1 = (__complex_conjugate_multiply (var1, c7x::as_cfloat_vec (sFB)));
233 
234  regStore0 = temp0 + temp1;
235  tmp = c7x::strm_agen<0, CV>::get_vpred ();
236  addr = c7x::strm_agen<0, CV>::get_adv (&pY[0]);
237  __vstore_pred (tmp, addr, regStore0);
238 
239  regStore1 =
240  c7x::as_cfloat_vec ((c7x::as_ulong_vec (regStore0)) ^ (xorVec));
241 
242  tmp = c7x::strm_agen<1, CV>::get_vpred ();
243  addr = c7x::strm_agen<1, CV>::get_adv (
244  &pY[2 * numPoints + 2 - (elementCount << 1)]);
245  __vstore_pred (tmp, addr, (__reverse (regStore1)));
246  }
247  FFTLIB_asm (" MARK 9");
248 
249  __SA0_CLOSE ();
250  __SA1_CLOSE ();
251  /* __SA2_CLOSE (); */
252  __SE0_CLOSE ();
253  __SE1_CLOSE ();
254 
255  /* __SE1_OPEN (&(pY[numPoints]), se1ParamsLast); */
256  /* __SA0_OPEN (sa0Params); */
257 
258  /* FFTLIB_asm (" MARK 10"); */
259  /* FFTLIB_UNROLL (2) */
260  /* for (i = 0; i < (numPoints >> 1) / (elementCount); i++) { */
261  /* var1 = c7x::strm_eng<1, CV>::get_adv (); */
262  /* var1 = c7x::as_cfloat_vec ((c7x::as_ulong_vec (var1)) ^ (xorVec)); */
263 
264  /* tmp = c7x::strm_agen<0, V>::get_vpred (); */
265  /* addr = c7x::strm_agen<0, V>::get_adv (&pY[2 + numPoints]); */
266 
267  /* __vstore_pred (tmp, addr, c7x::as_float_vec (var1)); */
268  /* } */
269  /* FFTLIB_asm (" MARK 11"); */
270 
271  /* __SE1_CLOSE (); */
272  /* __SA0_CLOSE (); */
273 
274  /*********************************/
275  /* Write pY[0] and pY[numPoints] */
276  /*********************************/
277 
278  cfloat var2, temp2, temp3;
279 
280  // pY[0]
281  var2 = ((cfloat *) pXFFT)[0];
282 
283  temp2 = __complex_multiply (var2, (((cfloat *) pSf)[0]));
284  temp3 =
285  __complex_conjugate_multiply (var2, (((cfloat *) pSf)[numPoints - 1]));
286 
287  ((cfloat *) pY)[0] = temp2 + temp3;
288  /* printf ("%.2f, %.2f\n", var2.r (), var2.i ()); */
289 
290  // pY[numPoints]
291  pY[numPoints] = pXFFT[0] - pXFFT[1];
292  pY[numPoints + 1] = 0;
293 
294  FFTLIB_asm (" MARK 7");
295 
296  /* printf ("pY Opt below:\n"); */
297  /* for (i = 0; i < 2 * numPoints; i += 2) { */
298  /* printf ("%d: %.2f, %.2f\n", i >> 1, pY[i], pY[i + 1]); */
299  /* } */
300  /* printf ("\n\n"); */
301 
302  return status;
303 }
304 
307  FFTLIB_bufParams1D_t *bufParamsX,
308  FFTLIB_F32 *pW,
309  FFTLIB_bufParams1D_t *bufParamsW,
310  FFTLIB_F32 *pY,
311  FFTLIB_bufParams1D_t *bufParamsY,
312  void *pBlock)
313 {
314  FFTLIB_STATUS status = FFTLIB_SUCCESS;
315 
316  if ((pX == NULL) || (pW == NULL) || (pY == NULL)) {
317  status = FFTLIB_ERR_NULL_POINTER;
318  }
319  else if (bufParamsX->dim_x != bufParamsW->dim_x ||
320  bufParamsX->dim_x != bufParamsY->dim_x) {
322  }
323  else if (bufParamsX->dim_x < 64 * 2) { /* Minimum number of points is 64
324  */
326  }
327  else if ((bufParamsX->data_type != FFTLIB_FLOAT32) ||
328  (bufParamsW->data_type != FFTLIB_FLOAT32) ||
329  (bufParamsY->data_type != FFTLIB_FLOAT32)) {
330  status = FFTLIB_ERR_INVALID_TYPE;
331  }
332  else if (((uint64_t) pX) & 0xFu) { /* pX must be 16-byte aligned for a
333  */
334  status = FFTLIB_ERR_NOT_ALIGNED_PTRS_STRIDES; /* streaming engine
335  configuration */
336  }
337  else {
338  /* Check if number of pts is a power of 2 */
339  uint32_t k = 0;
340  while (k < 32) {
341  if (bufParamsX->dim_x & (1u << k)) {
342  break;
343  }
344  k++;
345  }
346  if ((1u << k) != bufParamsX->dim_x) {
348  }
349  }
350  return (status);
351 }
@ FFTLIB_FLOAT32
c7x::cfloat_vec CV
#define SE1_PARAM_OFFSET_LAST
c7x::float_vec V
FFTLIB_STATUS_NAME
The enumeration of all status codes.
Definition: FFTLIB_types.h:172
@ FFTLIB_ERR_INVALID_TYPE
Definition: FFTLIB_types.h:176
@ FFTLIB_ERR_NULL_POINTER
Definition: FFTLIB_types.h:178
@ FFTLIB_ERR_INVALID_DIMENSION
Definition: FFTLIB_types.h:177
@ FFTLIB_SUCCESS
Definition: FFTLIB_types.h:173
@ FFTLIB_ERR_NOT_ALIGNED_PTRS_STRIDES
Definition: FFTLIB_types.h:181
float FFTLIB_F32
Single precision floating point.
Definition: FFTLIB_types.h:169
FFTLIB_STATUS FFTLIB_fft1dBatched_i32fc_c32fc_o32fc_init(FFTLIB_F32 *pX, FFTLIB_bufParams1D_t *bufParamsX, FFTLIB_F32 *pW, FFTLIB_bufParams1D_t *bufParamsW, FFTLIB_F32 *pY, FFTLIB_bufParams1D_t *bufParamsY, uint32_t numPoints, uint32_t numChannels, void *pBlock)
This function should be called before the FFTLIB_fft1dBatched_i32fc_c32fc_o32fc_kernel function is ca...
FFTLIB_STATUS FFTLIB_fft1dBatched_i32fc_c32fc_o32fc_kernel(FFTLIB_F32 *pX, FFTLIB_bufParams1D_t *bufParamsX, FFTLIB_F32 *pW, FFTLIB_bufParams1D_t *bufParamsW, FFTLIB_F32 *pY, FFTLIB_bufParams1D_t *bufParamsY, uint32_t numPoints, uint32_t numChannels, void *pBlock)
This function is the main kernel compute function.
FFTLIB_STATUS FFTLIB_fft1d_i32f_c32fc_o32fc_init(FFTLIB_F32 *pX, FFTLIB_bufParams1D_t *bufParamsX, FFTLIB_F32 *pW, FFTLIB_bufParams1D_t *bufParamsW, FFTLIB_F32 *pXFFT, FFTLIB_bufParams1D_t *bufParamsXFFT, FFTLIB_F32 *pSf, FFTLIB_bufParams1D_t *bufParamsSf, FFTLIB_F32 *pY, FFTLIB_bufParams1D_t *bufParamsY, void *pBlock)
This function should be called before the FFTLIB_fft1d_i32f_c32fc_o32fc_kernel function is called....
FFTLIB_STATUS FFTLIB_fft1d_i32f_c32fc_o32fc_kernel(FFTLIB_F32 *restrict pX, FFTLIB_bufParams1D_t *bufParamsX, FFTLIB_F32 *restrict pW, FFTLIB_bufParams1D_t *bufParamsW, FFTLIB_F32 *restrict pXFFT, FFTLIB_bufParams1D_t *bufParamsXFFT, FFTLIB_F32 *restrict pSf, FFTLIB_bufParams1D_t *bufParamsSf, FFTLIB_F32 *restrict pY, FFTLIB_bufParams1D_t *bufParamsY, void *pBlock)
This function is the main kernel compute function.
FFTLIB_STATUS FFTLIB_fft1d_i32f_c32fc_o32fc_checkParams(FFTLIB_F32 *pX, FFTLIB_bufParams1D_t *bufParamsX, FFTLIB_F32 *pW, FFTLIB_bufParams1D_t *bufParamsW, FFTLIB_F32 *pY, FFTLIB_bufParams1D_t *bufParamsY, void *pBlock)
This function checks the validity of the parameters passed to FFTLIB_fft1d_i32f_c32fc_o32fc_init and ...
A structure for a 1 dimensional buffer descriptor.
uint32_t data_type
Values are of type FFTLIB_data_type_e.
uint32_t dim_x
Width of buffer in X dimension in elements.