This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320C6678: Using "DSPF_dp_fftDPxDP( )" of DSPLIB

Part Number: TMS320C6678

Tool/software: Code Composer Studio

Dear Sir,

I'm trying to call DSP_dp_fftDPxDP() function of DSPLIB to implement fft process.

But the result of fft seems to be different from the result I calculate on Matlab.

So I call another function of dsplib  --  DSP_sp_fftSPxSP() to make a comparison. And the this time the result exactly matches with the result on Matlab.

I would like to know where I did wrong on calling DSP_dp_fftDPxDP().

Thanks a lot!~

Tim

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <c6x.h>
#include <string.h>

#include "dsplib.h"
#include "C:\\ti\\dsplib_c66x_3_4_0_0\\packages\\ti\\dsplib\\src\\DSPF_dp_fftDPxDP\\c66\\DSPF_dp_fftDPxDP_cn.h"
//#include "C:\\ti\\dsplib_c66x_3_4_0_0\\packages\\ti\\dsplib\\src\\DSPF_sp_fftSPxSP\\c66\\DSPF_sp_fftSPxSP_cn.h"


void tw_gen (double *w, int n);
void tw_gen_sp (float *w, int n);


#pragma DATA_ALIGN(x_i, 8);
#pragma DATA_ALIGN(x_cn, 8);
#pragma DATA_ALIGN(x_si, 8);
#pragma DATA_ALIGN(x_scn, 8);

#pragma DATA_ALIGN(w, 8);
#pragma DATA_ALIGN(ws, 8);

#pragma DATA_ALIGN(y_i, 8);
#pragma DATA_ALIGN(y_cn, 8);
#pragma DATA_ALIGN(y_si, 8);
#pragma DATA_ALIGN(y_scn, 8);


#define N (256)
#define M    (2*N)
#define PAD  (16)



double x_i[M + 2 * PAD];
double x_cn[M + 2 * PAD];
float x_si[M + 2 * PAD];
float x_sopt[M + 2 * PAD];
float x_scn[M + 2 * PAD];

double w[M + 2 * PAD];
float ws[M +2 *PAD];

double y_i[M + 2 * PAD];
double y_cn[M + 2 * PAD];
float y_si[M + 2 * PAD];
float y_sopt[M + 2 * PAD];
float y_scn[M + 2 * PAD];

unsigned char brev[64] = {
    0x0, 0x20, 0x10, 0x30, 0x8, 0x28, 0x18, 0x38,
    0x4, 0x24, 0x14, 0x34, 0xc, 0x2c, 0x1c, 0x3c,
    0x2, 0x22, 0x12, 0x32, 0xa, 0x2a, 0x1a, 0x3a,
    0x6, 0x26, 0x16, 0x36, 0xe, 0x2e, 0x1e, 0x3e,
    0x1, 0x21, 0x11, 0x31, 0x9, 0x29, 0x19, 0x39,
    0x5, 0x25, 0x15, 0x35, 0xd, 0x2d, 0x1d, 0x3d,
    0x3, 0x23, 0x13, 0x33, 0xb, 0x2b, 0x1b, 0x3b,
    0x7, 0x27, 0x17, 0x37, 0xf, 0x2f, 0x1f, 0x3f
};

/* ======================================================================== */
/*  Generate pointers to skip beyond array padding                          */
/* ======================================================================== */
double *const ptr_x_i  = x_i  + PAD;
double *const ptr_x_cn = x_cn + PAD;
float *const ptr_x_si = x_si + PAD;
float *const ptr_x_scn = x_scn + PAD;

double *const ptr_w = w + PAD;
float *const ptr_ws = ws + PAD;

double *const ptr_y_i  = y_i  + PAD;
double *const ptr_y_cn = y_cn + PAD;
float *const ptr_y_si = y_si + PAD;
float *const ptr_y_scn = y_scn + PAD;

/* ======================================================================== */
/*  MAIN -- Top level driver for the test.                                  */
/* ======================================================================== */

int main ()
{
    int i;

//	memset (x_i,  0x55, sizeof (x_i));
//	memset (x_cn, 0x55, sizeof (x_cn));

	/* ---------------------------------------------------------------- */
	/* Initialize input vector temporarily.                             */
	/* ---------------------------------------------------------------- */
	for (i = 0; i < N; i++)
	{
		x_cn[PAD + 2 * i]     = sin (2 * 3.1415 *  50 * i / (double) N);
		x_cn[PAD + 2 * i + 1] = sin (2 * 3.1415 * 100 * i / (double) N);
		x_i[PAD + 2 * i]      = x_cn[PAD + 2 * i];
		x_i[PAD + 2 * i + 1]  = x_cn[PAD + 2 * i + 1];
		x_si[PAD + 2 * i]     = x_cn[PAD + 2 * i];
		x_si[PAD + 2 * i + 1]  = x_cn[PAD + 2 * i + 1];
		x_scn[PAD + 2 * i]      = x_cn[PAD + 2 * i];
		x_scn[PAD + 2 * i + 1]  = x_cn[PAD + 2 * i + 1];
	}

	/* ---------------------------------------------------------------- */
	/* Force uninitialized arrays to fixed values.                      */
	/* ---------------------------------------------------------------- */
//	memset (y_i,  0xA5, sizeof (y_i) );
//	memset (y_cn, 0xA5, sizeof (y_cn));


	tw_gen (ptr_w, N);
	tw_gen_sp(ptr_ws, N);

	DSPF_dp_fftDPxDP_cn (N, &ptr_x_cn[0], &ptr_w[0], ptr_y_cn, 2, 0, N);
	DSPF_dp_fftDPxDP (N, &ptr_x_i[0], &ptr_w[0], ptr_y_i, 2, 0, N);
	DSPF_sp_fftSPxSP (N, &ptr_x_si[0], &ptr_ws[0], ptr_y_si, brev, 2, 0, N);
//	DSPF_sp_fftSPxSP_cn (N, &ptr_x_scn[0], &ptr_ws[0], ptr_y_scn, brev, 2, 0, N);


}

/* Function for generating Specialized sequence of twiddle factors */
void tw_gen (double *w, int n)
{
    int i, j, k;
    const double PI = 3.141592654;

    for (j = 1, k = 0; j <= n >> 2; j = j << 2)
    {
        for (i = 0; i < n >> 2; i += j)
        {
            w[k]     = cos (2 * PI * i / n);
            w[k + 1] = sin (2 * PI * i / n);
            w[k + 2] = cos (4 * PI * i / n);
            w[k + 3] = sin (4 * PI * i / n);
            w[k + 4] = cos (6 * PI * i / n);
            w[k + 5] = sin (6 * PI * i / n);
            k += 6;
        }
    }
}


void tw_gen_sp (float *w, int n)
{
    int i, j, k;
    const double PI = 3.141592654;

    for (j = 1, k = 0; j <= n >> 2; j = j << 2)
    {
        for (i = 0; i < n >> 2; i += j)
        {
#ifdef _LITTLE_ENDIAN
            w[k]     = (float) sin (2 * PI * i / n);
            w[k + 1] = (float) cos (2 * PI * i / n);
            w[k + 2] = (float) sin (4 * PI * i / n);
            w[k + 3] = (float) cos (4 * PI * i / n);
            w[k + 4] = (float) sin (6 * PI * i / n);
            w[k + 5] = (float) cos (6 * PI * i / n);
#else
            w[k]     = (float)  cos (2 * PI * i / n);
            w[k + 1] = (float) -sin (2 * PI * i / n);
            w[k + 2] = (float)  cos (4 * PI * i / n);
            w[k + 3] = (float) -sin (4 * PI * i / n);
            w[k + 4] = (float)  cos (6 * PI * i / n);
            w[k + 5] = (float) -sin (6 * PI * i / n);
#endif
            k += 6;
        }
    }
}

  • The sw team is notified. Please state the RTOS SDK version you are using.

    Best Regards,
    Yordan
  • Tim,

    In matlab, are you using single precision float or double precision float ? Have you checked the _x_cn and the x_scn to check to see if the input data is in complex format such that the real part is occupying first 32 bits for the x_scn and 64 bit in x_cn. Make sure that you are type casting the variables in your test code correctly and not ignoring compiler data type warnings when compiling with O3 settings.

    The only other difference between the two implementations that I can see is that the single precision kernel explicitly requires users to provide a bit reversal look up table.

    Regards,
    Rahul