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.

TDA4VM: How to run an FFT algorithm on C7X with FFTlib

Part Number: TDA4VM
Other Parts Discussed in Thread: FFTLIB

Tool/software:

Hi TI, 

I would like to implement an FFT algorithm on the C7x DSP using CCS. To do so, I am using code from the FFTlib provided by TI. However, I am encountering issues determining which code I could use to run an FFT algorithm. In my understanding, most of the code is only for configuring the kernel for an FFT algorithm, but it doesn't contain the FFT algorithm itself.

Could someone tell me which file(s) I could use from TI to meet my needs?

Regards, 

Mélanie

  • Hi,

    I will check this and update the details in this thread.

    Regards,
    Sivadeep

  • Hi Melanie,



    These are the different kernels supported in FFTLIB. The library includes kernels for both integer and floating-point data types, supporting both complex and real-valued 1-D inputs.
    These implementations are available within the Processor SDK. For a detailed description of each kernel and the associated APIs, you can refer to the user guide at:
    " https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-j722s/10_01_00_04/exports/docs/fftlib/docs/user_guide/group__FFTLIB__fft1dBatched__i16sc__c16sc__o16sc.html "

    For example, consider the kernel: FFTLIB_fft1d_i16sc_c16sc_o16sc 
    The corresponding execute function is: FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel()
    This function is located in: ti-processor-sdk-rtos-j784s4-evm-10_01_00_04/fftlib/src/fft_c7x/FFTLIB_fft1d_i16sc_c16sc_o16sc/c71/FFTLIB_fft1d_i16sc_c16sc_o16sc_ci
    For reference of  FFT algorithm implementation you can check the natural C at : ti-processor-sdk-rtos-j784s4-evm-10_01_00_04/ fftlib/src/fft_c7x/FFTLIB_fft1d_i16sc_c16sc_o16sc/ FFTLIB_fft1d_i16sc_c16sc_o16sc_cn.c

    Regards,
    Shabary S Sundar

  • Hi Sharaby, 

    I have several questions about the use of those functions. 
    Firstly, do we agree that in order to execute an FFT algorithm on CCS, I have to call in this order the following functions on a main.cpp file :

    FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams()

    FFTLIB_fft1d_i16sc_c16sc_o16sc_init() 

    FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() 

    Secondly, I don't understand the meaning behind the pShift parameters (Pointer to buffer with shift value at every stage of FFT) ? What does it represent ? What's its purpose in the FFT algorithm ? 

    Finally, is the FFTLIB_fft1d_i16sc_c16sc_o16sc_ci file providing optimized functions version of the functions from  FFTLIB_fft1d_i16sc_c16sc_o16sc_cn.c  file ? 

    Regards, 

    Mélanie 

  • Hi Melanie,

    Firstly, do we agree that in order to execute an FFT algorithm on CCS, I have to call in this order the following functions on a main.cpp file :

    Yes, FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams() function checks the validity of the parameters passed to init and kernel functions.
             - FFTLIB_fft1d_i16sc_c16sc_o16sc_init()  function setting up the configuration for the streaming engine.
             - FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() This function is the main kernel compute function.

    Secondly, I don't understand the meaning behind the pShift parameters (Pointer to buffer with shift value at every stage of FFT) ? What does it represent ? What's its purpose in the FFT algorithm ? 

    In fixed-point arithmetic, the results at each stage of the FFT can grow in magnitude, causing overflow. To prevent this, scaling is applied to the intermediate results using the pshift parameter.

    Finally, is the FFTLIB_fft1d_i16sc_c16sc_o16sc_ci file providing optimized functions version of the functions from  FFTLIB_fft1d_i16sc_c16sc_o16sc_cn.c  file ? 

    Yes, FFTLIB_fft1d_i16sc_c16sc_o16sc_ci is the optimized version of the functions from  FFTLIB_fft1d_i16sc_c16sc_o16sc_cn.c  file.

    Regards,
    Shabary S Sundar.

  • Hi Sharaby, 

    Thank you for your answer 

    However, I'm still encountering issues while trying to use those functions. I do not understand what to provide for the input data pX and pW. Do you have any files that contain this data?

    I only found some arrays nammed staticRefOutput, staticRefInput5, shiftVector4 in FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c, but nothing about twiddle factors data

  • Hi Melanie,

    However, I'm still encountering issues while trying to use those functions

    Please share the screenshot of the error. Were you able to run the fftlib inside the SDK without any issues? Just wanted to confirm.

    I do not understand what to provide for the input data pX and pW. Do you have any files that contain this data?

    I only found some arrays nammed staticRefOutput, staticRefInput5, shiftVector4 in FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c, but nothing about twiddle factors data

    pX represents the input data, while pW refers to the twiddle factors generated by the tw_gen function defined in the d.c file. The input test data is provided in the idat.c file.

    Regards,

    Betsy Varughese

  • Hi Betsy, 

    Okay, so I have to use the void tw_gen (int16_t *pW, uint32_t numPoints) function. However, when I try to use it in my code, I get this error : 

    "../main.cpp", line 31: error #20: identifier "tw_gen" is undefined

    I believe, it means that the compiler doesn't find the file which contains the declaration of tw_gen. In this case, I do not understand why this error occurs since I put those paths in the include options : 

    Could someone help me solve this issue? 

    Regards, 

    Mélanie

  • Hi Melanie,

    Were you able to run the fftlib inside the SDK without any issues? Just wanted to confirm.

    If yes, then the issue might be with your code. Have you added the library path ? 

    Could you please share the test code so that we can check it from our end.

    Regards,

    Betsy Varughese 

  • Hi Betsy, 

    I think we didn't understand each other correctly. When I compile a source file only containing a basic main() function, everything works fine. And yes I added the library path as you can see  :


    What I meant by : "However, I'm still encountering issues while trying to use those functions" is that I'm not familiar with the objects used as function input parameters. 

    Currently, I'm just trying to generate the Twiddle factors by using tw_gen() function. Here is my code : 

    #include <fftlib.h>
    #include <c7x.h>
    #include "common/FFTLIB_bufParams.h"        //utilisation type FFTLIB_bufParams1D_t
    #include "common/FFTLIB_types.h"            //utilisation FFTLIB_32
    #include <cmath>
    #include <math.h>                           //fonction pow()
    
    
    using namespace std;
    
    
    // utilisation des fonctions FFTLIB_fft1d_i16sc_c16sc_o16sc.h
    
    
    int main(void){
    
    
            /* --- PARAMETRES D ENTREES --- */
    
            /* --- BUFFER D ENTREE X --- */
        // Generation d une entree correspondant à un signal sinusoidale
    
    
    
            /* --- BUFFER DE TWIDDLE FACTORS W --- */
        // pW pointe vers un tableau contenant les twiddle factors
        // les twiddle factors peuvent etre generes par la fonction tw_gen dans le dc file du folder test
        int16_t *pW;
        uint32_t numPoints = pow(2,13);        // a voir, j'ai mis pareil que code
        //tw_gen (pW, numPoints);
    
            /* --- OBTENTION BUFFER DE SPLIT FACTORS --- */
        // utiliser split_factor_gen_r2c
    
    
        // Ordre des fonctions à utiliser
        /*
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams() : function checks the validity of the parameters passed to init and kernel functions
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_init(): function setting up the configuration for the streaming engine
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() This function is the main kernel compute function
         *
         */
    
    
    	return 0;
    }

    When I compile it that way, I always get the same message : 

    **** Build of configuration Release for project Algo FFT TI ****
    
    "C:\\APP\\Atgl\\ti\\ccs1260\\ccs\\utils\\bin\\gmake" -k -j 16 all -O 
     
    Building file: "../main.cpp"
    Invoking: C7000 Compiler
    "C:/Users/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/bin/cl7x" -mv7100 -O2 --include_path="C:/Users/T0314534/MyApp/depots/stage_jacinto7/Algo FFT TI" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/test" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/src" --include_path="C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/include" --diag_warning=225 --diag_wrap=off --display_error_number --preproc_with_compile --preproc_dependency="main.d_raw"  "../main.cpp"
     
    >> Compilation failure
    subdir_rules.mk:9: recipe for target 'main.obj' failed
    "../main.cpp", line 30: error #20: identifier "tw_gen" is undefined
    1 error detected in the compilation of "../main.cpp".
    gmake: *** [main.obj] Error 1
    gmake: Target 'all' not remade because of errors.
    
    **** Build Finished ****
    

    Do I have to put the content of the tw_gen() function in my code to be able to use it?

    Regards, 

    Mélanie ESTEVES 

  • Hi Melanie,

    I understand your question. I will try using the test code from my end to reproduce the issue. So far, we haven’t tested with any standalone code, which is why I asked if you were able to run the code provided in the SDK without any issues, just to confirm whether the issue is limited to the standalone code.

    Regards,

    Betsy Varughese

  • Hi Melanie,

    Do I have to put the content of the tw_gen() function in my code to be able to use it?

    Yes, of course. You can use it that way as well. Including the function definition directly within the code is perfectly fine.

    Regards,

    Betsy Varughese

  • Hi Melanie,

    Great , you've already added the include and library paths.

    Here is my code :

    tw_gen() is defined in a .c file and is you're calling it from a .cpp file. So , you must declare the tw_gen() in your main.cpp file as follows,

    // Add this before calling main()
    // Declare external C function from the .c file
    extern "C" {
        void tw_gen((int16_t *pW, uint32_t numPoints);
    }

    Regards,

    Betsy Varughese

  • I feel like there might be a conversion to be made so that they can be used later in FFT functions ?

    Yes.

  • Okay, so if I understood properly, in order to use for instance the FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() function, before giving the *pW parameter obtained with tw_gen(), I have to do convert pW values so that they will be between -1 and 1? 

    Also, for the pS paramater, I'm trying to use the array shiftVector4[] of the FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file. To do so, I included the FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file in my project and declared this variable that way in my main.cpp : 

    extern "C" {
        static uint32_t shiftVector4;
    }
    

    However, I got several error messages : 

    **** Build of configuration Release for project Algo FFT TI ****
    
    "C:\\APP\\Atgl\\ti\\ccs1260\\ccs\\utils\\bin\\gmake" -k -j 16 all -O 
     
    Building file: "../FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c"
    Invoking: C7000 Compiler
    "C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/bin/cl7x" -mv7100 -O2 --include_path="C:/Users/T0314534/MyApp/depots/stage_jacinto7/Algo FFT TI" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/test" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/src" --include_path="C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/include" --advice:performance=all --define=_INLINE --define=ALL_TEST_CASES --diag_warning=225 --diag_wrap=off --display_error_number --preproc_with_compile --preproc_dependency="FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.d_raw"  "../FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c"
     
    >> Compilation failure
    subdir_rules.mk:9: recipe for target 'FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.obj' failed
    "../FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c", line 28: fatal error #1965: cannot open source file "FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.h"
    1 catastrophic error detected in the compilation of "../FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c".
    Compilation terminated.
    gmake: *** [FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.obj] Error 1
    gmake: Target 'all' not remade because of errors.

    Firstly, I don't understand why the compiler doesn't find the header since I've put the correct paths. Also, I tried to fix it manually by adding a #include, but then I got new error because the compiler coudln't find again another header file....

    Finally, what is the reasoning behind the choice of the number of shifts?

    Thank for your help, 

    Mélanie

  • HI Besty!

    While waiting for your response, I tried to fix the issue by myself. I just want to check with you if it seems correct to you. 
    I created inside the project a source file named tw_gen.cpp. Inside it, I put the following code : 

    /*
     * tw_gen.cpp
     *
     *  Created on: 9 juil. 2025
     *      
     */
    
    //Fichier permettant d'utiliser la fonction déclarée dans le fichier :
    
    #include <tw_gen.h>
    
    static int16_t float2short (FFTLIB_D64 x){
    
       x = floor (0.5 + x); // Explicit rounding to integer //
       if (x >= 32767.0)
          return 32767;
       if (x <= -32768.0)
          return -32768;
       return (int16_t) x;
    }
    
    
    /* --- Fonction generant les twiddle factors */
    void tw_gen (int16_t *pW, uint32_t numPoints){
    
       int32_t          i, j, k, t;
       const FFTLIB_D64 PI   = 3.141592654;
       FFTLIB_D64 twF2sScale = 32767.5; /* Scale twiddle factors (max abs value of 1) to use full capacity of int16_t */
       t = numPoints >> 2;
    
       for (j = 1, k = 0; j <= numPoints >> 2; j = j << 2) {
    
          for (i = 0; i < numPoints >> 2; i += j) {
    
    
             pW[k]     = float2short (twF2sScale * cos (2 * PI * i / numPoints));
             pW[k + 1] = float2short (twF2sScale * (-sin (2 * PI * i / numPoints)));
             pW[k + 2 * t] =
                 float2short (twF2sScale * cos (4 * PI * i / numPoints));
             pW[k + 2 * t + 1] =
                 float2short (twF2sScale * (-sin (4 * PI * i / numPoints)));
             pW[k + 4 * t] =
                 float2short (twF2sScale * cos (6 * PI * i / numPoints));
             pW[k + 4 * t + 1] =
                 float2short (twF2sScale * (-sin (6 * PI * i / numPoints)));
             k += 2;
          }
          k += (t) *4;
          t = t >> 2;
       }
    }
    


    Then, I defined the tw_gen() function in my main.cpp file that way : 
    extern void tw_gen (int16_t *pW, uint32_t numPoints);


    That way, I was able to compile whithout getting the previous error message 

  • Now, I'm having trouble understanding how to initialize the pW parameter. 
    I saw inside the FFTLIB_fft1d_i16sc_c16sc_o16sc_d.c file, that this parameters is initialized that way : 

      pX = (int16_t *) TI_memalign (
              64,                                /* pX is required to be*/
              numPoints * 2 * sizeof (int16_t)); /* 16-byte aligned for
                                                  * streaming engine use
                                                  * in kernel  


    Is it the only of initializing it ? If so, what is the role of the TI_memalign() function ? And how are supposed to chose the size put as one of the parameters ?

    Regards, 

    Mélanie

  • Hi again, 

    I tried your solution, but it didn't work. 
    I get the following issue while compiling : 

    **** Build of configuration Release for project Algo FFT TI ****
    
    "C:\\APP\\Atgl\\ti\\ccs1260\\ccs\\utils\\bin\\gmake" -k -j 16 all -O 
     
    Building file: "../main.cpp"
    Invoking: C7000 Compiler
    "C:/Users/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/bin/cl7x" -mv7100 -O2 --include_path="C:/Users/T0314534/MyApp/depots/stage_jacinto7/Algo FFT TI" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/test" --include_path="T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/src" --include_path="C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/include" --advice:performance=all --diag_warning=225 --diag_wrap=off --display_error_number --preproc_with_compile --preproc_dependency="main.d_raw"  "../main.cpp"
    Finished building: "../main.cpp"
     
    Building target: "Algo FFT TI.out"
    Invoking: C7000 Linker
    "C:/Users/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/bin/cl7x" -mv7100 -O2 --advice:performance=all --diag_warning=225 --diag_wrap=off --display_error_number -z -m"Algo FFT TI.map" -i"C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/lib" -i"T:/Packages/ti-processor-sdk-rtos-j721e-evm-10_01_00_04/fftlib/lib/Release" -i"C:/Users/T0314534/MyApp/Packages/ti-cgt-c7000_4.1.0.LTS/include" --reread_libs --diag_wrap=off --display_error_number --warn_sections --xml_link_info="Algo FFT TI_linkInfo.xml" --rom_model -o "Algo FFT TI.out" "./main.obj" "../lnk.cmd"  -llibc.a -lFFTLIB_C7100.lib -lFFTLIB_common_C7100.lib -lFFTLIB_test_common_C7100.lib 
    <Linking>
     
     undefined first referenced
      symbol       in file     
     --------- ----------------
     tw_gen    ./main.obj      
     
    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "Algo FFT TI.out" not built
     
    >> Compilation failure
    makefile:138: recipe for target 'Algo FFT TI.out' failed
    gmake[1]: *** [Algo FFT TI.out] Error 1
    makefile:134: recipe for target 'all' failed
    gmake: *** [all] Error 2
    
    **** Build Finished ****
    

  • Hi Melanie,

    I tried your solution, but it didn't work. 
    I get the following issue while compiling : 

    you have to include the .c file, otherwise it won't compile or  linked. The reason for the error encountered.

    Regards,

    Betsy Varughese

  • Hi Melanie, 

    I just want to check with you if it seems correct to you

    yes, that's also fine.

    Regards,

    Betsy Varughese

  • Hi Melanie,

    Yes, Correct. Please  initialize in the following way:-

    pW = (int16_t *) TI_memalign (64, numPoints * 2 * sizeof (int16_t));"

    what is the role of the TI_memalign() function ?

    TI_memalign() allocates memory with a given alignment, using L2SRAM on the target or memalign() on the host.(see TI_memory.c )

    Regards,

    Betsy Varughese

  • Okay, I did it that way. 

    However, is that normal that the tw_gen() doesn't generate values between -1 and 1 ?
    I feel like there might be a conversion to be made so that they can be used later in FFT functions ?

    regards

  • is that normal that the tw_gen() doesn't generate values between -1 and 1 ?

    Yes, for fixed point cases.

  • Hi Melanie,

    pS paramater
    You mean , pShift parameter?
    Also, for the pS paramater, I'm trying to use the array shiftVector4[] of the FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file. To do so, I included the FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file in my project and declared this variable that way in my main.cpp : 

    In the idat.c file, it is declared as static, which makes it private to that file. Declaring it this way won't work if you need to access it from other files.

    Can you try the following:

    //idat.c
    uint32_t shiftVector4[]  = {0, 0, 0};
    
    // main.cpp
    extern "C" {
        extern uint32_t shiftVector4[];
    }
    

    what is the reasoning behind the choice of the number of shifts?

    The parameter tell us how much to scale/right shift the data at each FFT stage to avoid overflow and perserve numerical percision. 

    Regards,

    Betsy Varugese

  • Hi Betsy, 

    Yes sorry, by pS I meant pShift parameter. 

    I indeed deleted the static type in order to be able to use it in another source file. Then I added exactly the code lines you gave me. Then I added the FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file in my project. However, I got the issue I mentionned on the previous message. 
    However, I managed to use those data on my own way.

    Now, what remains for me to do, is initialzing the pBlock paramater. I have several questions: 

    • What is the purpose of this parameter in the algorithm? What is its role?
    • How do I know how to initialize it?

     Regards, 

    Mélanie

  • I got the issue I mentionned on the previous message. 
    However, I managed to use those data on my own way.

    Did you add this directly into the main.cpp file?

    Regards,

    Betsy Varughese

  • However, I got the issue I mentionned on the previous message. 

    Okay. Do you mean the compiler is unable to fiind the .h file?

    I hope you have included the path in the CCS  "include path".

    Regards,

    Betsy Varughese

  • What is the purpose of this parameter in the algorithm? What is its role?

    Regards,

    Betsy Varughese

  • How do I know how to initialize it?

    It depends on how many times SE/SA parameters need to be used within the code.

     Regards,

    Betsy Varughese

  • Okay, inside the TI functions, I saw those lines :

       __SE_TEMPLATE_v1 se0_param = __gen_SE_TEMPLATE_v1 ();
          __SE_TEMPLATE_v1 se1_param = __gen_SE_TEMPLATE_v1 ();
          __SA_TEMPLATE_v1 sa0_param = __gen_SA_TEMPLATE_v1 ();

    So, that means that there are 3 SE/SA parameters used ? Do I have to use the TI_memalign() function to do the allocation ?

  • Please refer "/ti-processor-sdk-rtos-j784s4-evm-10_01_00_04/fftlib/src/fft_c7x/FFTLIB_fft1d_i16sc_c16sc_o16sc/FFTLIB_fft1d_i16sc_c16sc_o16sc.h"

    /* PBLOCK has to accommodate certain number of SE/SA configurations */
    #define FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE (9 * SE_PARAM_SIZE)

    and check corresponding "d.c file" for the usuage.

    uint8_t FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock
        [FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE];

    Regards,

    Betsy Varughese

  • Yes, that's what I meant 

    Yes, I showed you previously my include paths, and everything seemed good to you

    Regards, 

    Mélanie

  • Okay. Thanks for the update.

    Regards,

    Betsy Varughese

  • I have those lines 
    I used your iinformation to initialize pBlock that way, is that correct ?: 

    extern "C" {
        uint8_t FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock[FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE];
    }
    
    

    And then inside the main function : 
        uint8_t *pBlock;
        pBlock = FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock;

  • Yes I understand that, but my question is how do I know "how many times SE/SA parameters need to be used within the code"? 
    I'm using the functions from the FFTLIB_fft1d_i16sc_c16sc_o16sc_ci.cpp file 

    And here is my code, but the initialization of pBlock is missing

    #include <fftlib.h>
    #include <c7x.h>
    #include "common/FFTLIB_bufParams.h"        //utilisation type FFTLIB_bufParams1D_t
    #include "common/FFTLIB_types.h"            //utilisation FFTLIB_32
    #include <cmath>
    #include <math.h>                           //fonction pow()
    #include "common/TI_memory.h"               // fonction TI_memalign()
    #include <iostream>
    #include <cstring>  //pour utilisation memcmp()
    
    
    
    /*
     * Utilisation des fonctions FFTLIB_fft1d_i16sc_c16sc_o16sc.h
     */
    
    
    using namespace std;
    
    
    // Ici j'indique au compilateur que le contenu de cette fonction se trouve dans un autre fichier source
    // ici comme je suis dans un fichier C++, ca implique qu elle se trouve ailleurs mais dans un autre fichier C++ aussi
    extern void tw_gen (int16_t *pW, uint32_t numPoints);
    
    
    // Piste abandonnee a cause d erreurs successives d acces a des headers
    // Utilisation du tableau de shift d'un autre fichier source C : idat.c
    // => Necessite d'utiliser mot clef "extern" pour que le compilateur trouve la def de la variable
    // + "C" parce que la def se trouve dans un fichier.c et que nous on code dans un fichier C++
    //extern "C" {
    //    static uint32_t shiftVector4;
    //}
    
    
    // Declaration en variable globale des data d entree TI
    int16_t staticRefInput4[] = {
        -108, -126, 109,  86,   56,  62,   -46, 8,    -88, -101, -78, -127, 67,   -33, -12, 97,  117, 109,  32,   91,  -44, -118, 117,  72,  20,  -43,
        -66,  -77,  82,   19,   31,  -84,  -22, -115, -46, -114, -30, -73,  -115, 25,  118, 25,  -18, 92,   61,   90,  67,  -39,  -21,  88,  11,  85,
        -72,  86,   34,   -107, -11, -113, -54, 125,  -37, 3,    86,  38,   -124, 89,  12,  90,  9,   -13,  -12,  22,  14,  17,   -109, 84,  22,  -16,
        2,    -79,  128,  76,   52,  -53,  -38, -105, 113, 106,  63,  -110, -85,  -68, -50, -82, 71,  -124, 93,   -16, 42,  -122, 78,   -70, -64, -45,
        -118, 57,   -127, 124,  -17, -65,  117, -40,  12,  68,   -70, -76,  6,    -18, -96, -3,  -70, -113, -111, 51,  92,  -8,   104,  -108};
    
    uint32_t shiftVector4[]     = {0, 0, 0};
    
    
    int main(void){
    
    
            /* --- PARAMETRES D ENTREES --- */
    
        //Pas utilisable car aucun tableau d entree de TI contient 2^13 valeurs
        //uint32_t numPoints = pow(2,13);        // a voir, j'ai mis pareil que code
        // je mets un nbr de points me permettant d utiliser les tableaux du idat.c
        uint32_t numPoints = sizeof(staticRefInput4) / sizeof(staticRefInput4[0]);
        cout << " Le nombre de points de la FFT est : " << numPoints << endl;
        uint32_t numShifts = 3;                // voir rep TI pour raisonnement derriere le choix de cette valeur, j ai mis le meme nombre que dans shiftVector4
    
    
    
            /* --- BUFFER D ENTREE X --- */
    
        /* --- Creation de pX --- */
        // D apres FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file, on doit aligner le buffer d entree sur 16 bytes
        int16_t *pX = (int16_t *) TI_memalign (64, numPoints * sizeof (int16_t));   //placement pour respect contrainte
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pX,staticRefInput4, sizeof(staticRefInput4));
    
    //     Verification des copies de staticRefInput4 dans pX         STATUT : OK !
    //    for(int k=0; k<numPoints; k++){
    //
    //        cout << " La " << k << "ème valeur vaut " << pX[k] << endl;
    //    }
    
        /* --- Creation de bufParamsX --- */
        FFTLIB_bufParams1D_t *bufParamsX;
        bufParamsX -> data_type = FFTLIB_INT16;
        bufParamsX -> dim_x = numPoints;        //nombre d elements du buffer dans la direction X (donc ici en 1 dimension)
    
    
            /* --- BUFFER DE TWIDDLE FACTORS W --- */
    
        /* --- Creation de pW --- */
        // pW pointe vers un tableau contenant les twiddle factors
        // les twiddle factors peuvent etre generes par la fonction tw_gen dans le dc file du folder test
        // Pour initialisation @ pW : utilisation de la fonction TI_memalign() du header TI_memory.h
        // Analyse : j ai l impression que c est une forme d allocation memoire "optimisee" a verifier
    
        int16_t *pW = (int16_t *) TI_memalign ( 64, numPoints * 2 * sizeof (int16_t));  //allocation memoire pour stocker les twiddle factors
        tw_gen (pW, numPoints); //generation des twiddle factors
    
        // Je verifie qu on a bien genere les facteurs
        int pw_nb = numPoints * 2;
    //    cout << " Le nombre de twiddle factors est de : " << pw_nb << endl;
    
    //    for(int i=0; i< pw_nb; i+=2){       //pas de 2 pour l'incrementateur pour lire d'un coup partieR et I
    //
    //        cout << "La partieR du twiddle est :" << pW[i] << endl;
    //        cout << "La partieI du twiddle est :" << pW[i+1] << endl;
    //    }
        // Res : on obtient des valeurs correspondants a des entiers 16 bits Q15
        // De ce que je vois, pas besoin de conv de sorte a avoir des valeurs entre -1 et 1 pour utiliser les fonctions pour le FFT
    
        /* --- Creation de bufParamsW --- */
        FFTLIB_bufParams1D_t *bufParamsW;
        bufParamsW -> data_type = FFTLIB_INT16;
        bufParamsW -> dim_x = numPoints * 2;
    
    
            /* --- OBTENTION BUFFER DE SPLIT FACTORS --- */
    
        /* --- Creation de pShift --- */
        // methode 1 : utilisation TI_memalign()
        uint32_t *pShift = (uint32_t *) TI_memalign (64, numShifts * sizeof (uint32_t));
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pShift,shiftVector4, sizeof(shiftVector4));
    
        // Verification des copies
    //    for(int n=0; n<numShifts; n++){
    //
    //            cout << " La " << n << " ème valeur vaut " << pShift[n] << endl;
    //    }
    
        /* --- Creation de bufParamsShift --- */
        FFTLIB_bufParams1D_t *bufParamsShift;
        bufParamsShift -> data_type = FFTLIB_INT32;
        bufParamsShift -> dim_x = numShifts;
    
        // Pour le moment methode abandonnee
        // methode 2 : utilisation de tableau de split factors fournis par TI dans file : FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c
        // => Implique l'ajout du predefined symbol ALL_TEST_CASES pour y avoir acces
        //uint32_t *pShift;
        //pShift = shiftVector4;   //on recupere les donnees du fichier idat.c
    
        // methode 3 : utilisation de la fonction split_factor_gen_r2c()
    
    
    
            /* --- OBTENTION BUFFER DE SORTIE Y --- */
    
        /* --- Creation de pY --- */
        // Pour moi, faut juste allouer de l espace memoire pour stocker les res de la FFT => fait via TI_memalign()
        int16_t  *pY = (int16_t *) TI_memalign (64, numPoints * sizeof (int16_t));
    
        /* --- Creation de bufParamsY --- */
        FFTLIB_bufParams1D_t *bufParamsY;
        bufParamsY -> data_type = FFTLIB_INT16;
        bufParamsY -> dim_x = numPoints;
    
    
            /* --- OBTENTION BUFFER PBLOCK --- */
        // role de pBlock : j ai l impression que c est un buffer utilise par les streaming engines
        // OUI : doit pouvoir stocker les parametres des streaming engines
        void *pBlock;
    
    
    
    
    
    
            /****** DEBUT IMPLEMENTATION ALGO FFT ******/
    
    
        // Ordre des fonctions à utiliser
        /*
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams() : function checks the validity of the parameters passed to init and kernel functions
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_init(): function setting up the configuration for the streaming engine
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() This function is the main kernel compute function
         *
         */
    
        // Indicateur etat apres chaque passage dans fonctions TI
        FFTLIB_STATUS status = FFTLIB_SUCCESS;  //initialise a l etat de succes
    
        /* --- CHECK DE LA VALIDITE DES PARAMATRES POUR INIT() ET KERNEL() FUNCTIONS --- */
        if(status == FFTLIB_SUCCESS){
    
            FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
        }
    
        else{
    
            cout << "Des paramètres d'entrée ne sont pas valides" << endl;
            exit(EXIT_FAILURE);
        }
    
        /* --- INITIALISATION --- */
        FFTLIB_fft1d_i16sc_c16sc_o16sc_init (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
    
    
    
    	return 0;
    }

  • Hi Melanie,

    I used your iinformation to initialize pBlock that way, is that correct ?: 

    From which file have you declared the variable — is it from a file within your current CCS project or from d.c? 

    Or you can directly add all those lines into main.cpp. (Refer to the example in d.c to see how the functions are being called there.).

     uint8_t FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock
        [FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE]; // Directly use the same name or replace it with your preference
     
     //Example funtion call - init()
     status_opt = FFTLIB_fft1d_i16sc_c16sc_o16sc_init (
                 (int16_t *) pX, &bufParamsData, (int16_t *) pW, &bufParamsData,
                 (int16_t *) pY, &bufParamsData, (uint32_t *) pShift,
                 &bufParamsShift, FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock);
     // Kernel
     status_opt = FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel (
                 (int16_t *) pX, &bufParamsData, (int16_t *) pW, &bufParamsData,
                 (int16_t *) pY, &bufParamsData, (uint32_t *) pShift,
                 &bufParamsShift, FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock);

    Please let me know if you're still facing any issues.

    Regard,

    Betsy Varughese

  • Hi Betsy,

    I've declared this variable in my current CCS project (more specifically inside my main.cpp file), not in the d.c file
    Here is my code, maybe it'll be easier for you to identify some errors : 

    #include <fftlib.h>
    #include <c7x.h>
    #include "common/FFTLIB_bufParams.h"        //utilisation type FFTLIB_bufParams1D_t
    #include "common/FFTLIB_types.h"            //utilisation FFTLIB_32
    #include <cmath>
    #include <math.h>                           //fonction pow()
    #include "common/TI_memory.h"               // fonction TI_memalign()
    #include <iostream>
    #include <cstring>  //pour utilisation memcmp()
    
    
    
    /*
     * Utilisation des fonctions FFTLIB_fft1d_i16sc_c16sc_o16sc.h
     */
    
    
    using namespace std;
    
    
    // Ici j'indique au compilateur que le contenu de cette fonction se trouve dans un autre fichier source
    // ici comme je suis dans un fichier C++, ca implique qu elle se trouve ailleurs mais dans un autre fichier C++ aussi
    extern void tw_gen (int16_t *pW, uint32_t numPoints);
    
    
    // Piste abandonnee a cause d erreurs successives d acces a des headers
    // Utilisation du tableau de shift d'un autre fichier source C : idat.c
    // => Necessite d'utiliser mot clef "extern" pour que le compilateur trouve la def de la variable
    // + "C" parce que la def se trouve dans un fichier.c et que nous on code dans un fichier C++
    //extern "C" {
    //    static uint32_t shiftVector4;
    //}
    
    
    // Pour initialisation de pBlock
    // L'utilisation du tableau def dans le d.c ne marche pas meme avec extern "C"
    uint8_t FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock[FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE];
    
    
    // Declaration en variable globale des data d entree TI
    int16_t staticRefInput4[] = {
        -108, -126, 109,  86,   56,  62,   -46, 8,    -88, -101, -78, -127, 67,   -33, -12, 97,  117, 109,  32,   91,  -44, -118, 117,  72,  20,  -43,
        -66,  -77,  82,   19,   31,  -84,  -22, -115, -46, -114, -30, -73,  -115, 25,  118, 25,  -18, 92,   61,   90,  67,  -39,  -21,  88,  11,  85,
        -72,  86,   34,   -107, -11, -113, -54, 125,  -37, 3,    86,  38,   -124, 89,  12,  90,  9,   -13,  -12,  22,  14,  17,   -109, 84,  22,  -16,
        2,    -79,  128,  76,   52,  -53,  -38, -105, 113, 106,  63,  -110, -85,  -68, -50, -82, 71,  -124, 93,   -16, 42,  -122, 78,   -70, -64, -45,
        -118, 57,   -127, 124,  -17, -65,  117, -40,  12,  68,   -70, -76,  6,    -18, -96, -3,  -70, -113, -111, 51,  92,  -8,   104,  -108};
    
    uint32_t shiftVector4[]     = {0, 0, 0};
    
    
    int main(void){
    
    
            /* --- PARAMETRES D ENTREES --- */
    
        //Pas utilisable car aucun tableau d entree de TI contient 2^13 valeurs
        //uint32_t numPoints = pow(2,13);        // a voir, j'ai mis pareil que code 
        // je mets un nbr de points me permettant d utiliser les tableaux du idat.c
        uint32_t numPoints = sizeof(staticRefInput4) / sizeof(staticRefInput4[0]);
        cout << " Le nombre de points de la FFT est : " << numPoints << endl;
        uint32_t numShifts = 3;                // voir rep TI pour raisonnement derriere le choix de cette valeur, j ai mis le meme nombre que dans shiftVector4
    
    
    
            /* --- BUFFER D ENTREE X --- */
    
        /* --- Creation de pX --- */
        // D apres FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file, on doit aligner le buffer d entree sur 16 bytes
        int16_t *pX = (int16_t *) TI_memalign (64, numPoints * sizeof (int16_t));   //placement pour respect contrainte
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pX,staticRefInput4, sizeof(staticRefInput4));
    
    //     Verification des copies de staticRefInput4 dans pX         STATUT : OK !
    //    for(int k=0; k<numPoints; k++){
    //
    //        cout << " La " << k << "ème valeur vaut " << pX[k] << endl;
    //    }
    
        /* --- Creation de bufParamsX --- */
        FFTLIB_bufParams1D_t *bufParamsX;
        bufParamsX -> data_type = FFTLIB_INT16;
        bufParamsX -> dim_x = numPoints;        //nombre d elements du buffer dans la direction X (donc ici en 1 dimension)
    
    
            /* --- BUFFER DE TWIDDLE FACTORS W --- */
    
        /* --- Creation de pW --- */
        // pW pointe vers un tableau contenant les twiddle factors
        // les twiddle factors peuvent etre generes par la fonction tw_gen dans le dc file du folder test
        // Pour initialisation @ pW : utilisation de la fonction TI_memalign() du header TI_memory.h
        // Analyse : j ai l impression que c est une forme d allocation memoire "optimisee" a verifier
    
        int16_t *pW = (int16_t *) TI_memalign ( 64, numPoints * 2 * sizeof (int16_t));  //allocation memoire pour stocker les twiddle factors
        tw_gen (pW, numPoints); //generation des twiddle factors
    
        // Je verifie qu on a bien genere les facteurs
        int pw_nb = numPoints * 2;
    //    cout << " Le nombre de twiddle factors est de : " << pw_nb << endl;
    
    //    for(int i=0; i< pw_nb; i+=2){       //pas de 2 pour l'incrementateur pour lire d'un coup partieR et I
    //
    //        cout << "La partieR du twiddle est :" << pW[i] << endl;
    //        cout << "La partieI du twiddle est :" << pW[i+1] << endl;
    //    }
        // Res : on obtient des valeurs correspondants a des entiers 16 bits Q15
        // De ce que je vois, pas besoin de conv de sorte a avoir des valeurs entre -1 et 1 pour utiliser les fonctions pour le FFT
    
        /* --- Creation de bufParamsW --- */
        FFTLIB_bufParams1D_t *bufParamsW;
        bufParamsW -> data_type = FFTLIB_INT16;
        bufParamsW -> dim_x = numPoints * 2;
    
    
            /* --- OBTENTION BUFFER DE SPLIT FACTORS --- */
    
        /* --- Creation de pShift --- */
        // methode 1 : utilisation TI_memalign()
        uint32_t *pShift = (uint32_t *) TI_memalign (64, numShifts * sizeof (uint32_t));
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pShift,shiftVector4, sizeof(shiftVector4));
    
        // Verification des copies
    //    for(int n=0; n<numShifts; n++){
    //
    //            cout << " La " << n << " ème valeur vaut " << pShift[n] << endl;
    //    }
    
        /* --- Creation de bufParamsShift --- */
        FFTLIB_bufParams1D_t *bufParamsShift;
        bufParamsShift -> data_type = FFTLIB_INT32;
        bufParamsShift -> dim_x = numShifts;
    
        // Pour le moment methode abandonnee
        // methode 2 : utilisation de tableau de split factors fournis par TI dans file : FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c
        // => Implique l'ajout du predefined symbol ALL_TEST_CASES pour y avoir acces
        //uint32_t *pShift;
        //pShift = shiftVector4;   //on recupere les donnees du fichier idat.c
    
        // methode 3 : utilisation de la fonction split_factor_gen_r2c()
    
    
    
            /* --- OBTENTION BUFFER DE SORTIE Y --- */
    
        /* --- Creation de pY --- */
        // Pour moi, faut juste allouer de l espace memoire pour stocker les res de la FFT => fait via TI_memalign()
        int16_t  *pY = (int16_t *) TI_memalign (64, numPoints * sizeof (int16_t));
    
        /* --- Creation de bufParamsY --- */
        FFTLIB_bufParams1D_t *bufParamsY;
        bufParamsY -> data_type = FFTLIB_INT16;
        bufParamsY -> dim_x = numPoints;
    
    
            /* --- OBTENTION BUFFER PBLOCK --- */
        // role de pBlock : j ai l impression que c est un buffer utilise par les streaming engines
        // OUI : doit pouvoir stocker les parametres des streaming engines
    
        // Log de debug
        cout << " Début création du pointeur pBlock " << endl;
        // Initialisation du pointeur via mot clef NULL
        uint8_t* pBlock;
        pBlock = &FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock[0];   // on peut pas mettre &FFTLIB_fft1d_i16sc_c16sc_o16sc_pBloc sinon je fais pointer un pointeur simple vers pointeur d'un tableau de 576 val
        // Log de debug
        cout << " Fin création du pointeur pBlock " << endl;
    
    
            /****** DEBUT IMPLEMENTATION ALGO FFT ******/
    
    
        // Ordre des fonctions à utiliser
        /*
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams() : function checks the validity of the parameters passed to init and kernel functions
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_init(): function setting up the configuration for the streaming engine
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() This function is the main kernel compute function
         *
         */
    
        // Indicateur etat apres chaque passage dans fonctions TI
        FFTLIB_STATUS status = FFTLIB_SUCCESS;  //initialise a l etat de succes
    
        /* --- CHECK DE LA VALIDITE DES PARAMETRES POUR INIT() ET KERNEL() FUNCTIONS --- */
        FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
    
        if(status == FFTLIB_SUCCESS){
    
            cout << "Les parametres d'entrée sont valides" << endl;
        }
    
        else{
    
            cout << "Des paramètres d'entrée ne sont pas valides" << endl;
            exit(EXIT_FAILURE);
        }
    
    
    
        /* --- INITIALISATION --- */
        // fonction prend en charge des "one-time operations", comme la config des streaming engine
    
        if(status == FFTLIB_SUCCESS){
    
            FFTLIB_fft1d_i16sc_c16sc_o16sc_init (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
        }
    
        else{
    
              cout << "Un problème s'est produit lors de l'initialisation" << endl;
              exit(EXIT_FAILURE);
        }
    
    
    
    	return 0;
    }


    However, whenever I try to run the code (in Release mode), the code runs in a loop without stopping.... I added some log, and I saw that the creation of pBlock is done successfully. I don't even understand why but it seems there are some issues now while using FFTLIB functions..

    I tried to declared the FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock array inside the main function as you suggested, but it didn't change anything 

    Regards, 

    Mélanie

  • Hi Betsy,

    I'm trying to step over each line of the code while running the code to idenify the issue.
    Here are some of the information I got : 

    In Release mode : 

    No source available for "TI_memalign() at C:\Users\MyApp\depots\stage_jacinto7\Algo FFT TI\Release\Algo FFT TI.out:{3} 0x70037f80{4}" 


    In debug mode : 
    C71X_0: Trouble Reading Memory Block at 0x2200150a2afa9596 on Page 0 of Length 0x8: (Error -1344 - (0:0:0)) Register or Memory request has failed due to a Transaction Error.  This may be the result of reading from a write only register, writing to a read only register, or accessing a memory location that is not assigned. No user action required. (Emulation package 12.6.0.00029) 
    C71X_0: Trouble Reading Memory Block at 0x70045b28 on Page 0 of Length 0x8: (Error -1351 - (0:0:0)) Register or Memory request has timed out.  The CPU is executing a High Priority Interrupt, this is typically due to a Double Page Fault. Choose 'Force' to force the CPU into a state that allows debug of why the HPI is active. (Emulation package 12.6.0.00029) 
    

    At first, I suspect an issue with the size of certain memory areas in relation to initialized variables. However, when after checking it, I found out that the creation of variables does not exceed the allocated sizes for the different sections. SO I have no idea where the issue is coming from :( 

  • Hi Melanie,

    Sure. Our team is trying to reproduce the issue from our end and let you know.

    Regards,

    Betsy Varughese

  • Okay, 

    Thank you Betsy, 

    Here are some more details

  • Hi Melanie,

    Could you please update the following in your code and try?

    "1" We should capture the return value of  FFTLIB_fft1d_i16sc_c16sc_o16sc_init() in status, Try using, 

    status = FFTLIB_fft1d_i16sc_c16sc_o16sc_init (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);

    "2" Comment the "FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams()" and try (see d.c , its not calling the checkparams() and is guarded under 

    FFTLIB_CHECK_PARAMS || 
    FFTLIB_FFT1D_I16SC_C16SC_O16SC_CHECK_PARAMS
    "3" Cross check the following (see corresponding d.c file)
    pX = (int16_t *) TI_memalign (
              64,                                /* pX is required to be*/
              numPoints * 2 * sizeof (int16_t)); /* 16-byte aligned for
                                                  * streaming engine use
                                                  * in kernel           */
    pY     = (int16_t *) TI_memalign (64, numPoints * 2 * sizeof (int16_t));
    pW     = (int16_t *) TI_memalign (64, numPoints * 2 * sizeof (int16_t));
    pShift = (uint32_t *) TI_memalign (64, numShifts * sizeof (uint32_t));
    
    bufParamsData.dim_x     = numPoints * 2;
    bufParamsData.data_type = FFTLIB_INT16;
    
    bufParamsShift.dim_x     = numShifts;
    bufParamsShift.data_type = FFTLIB_UINT32;
    
     
     
    Regards,
    Betsy Varughese
  • Hi Betsy !

    Okay, so I followed the first two instructions : I commented the checkParams() function and put the return value if the init() function inside the status variable. By doing that, the issue indeed disappeared, and the status was FFTLIB_SUCCESS.

    However, I quite disagree with you on that quote " see d.c , its not calling the checkparams() and is guarded under FFTLIB_CHECK_PARAMS || FFTLIB_FFT1D_I16SC_C16SC_O16SC_CHECK_PARAMS....". When I look at the body function FFTLIB_fft1d_i16sc_c16sc_o16sc_d(), I can see that they do check the parameters by calling fft1d_i16sc_c16sc_o16sc_getTestParams()

    Also, could you explain why the use of the FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams function leads to an a code running in loop ? 

    Regards

  • Hi Melanie, 

    Apologies for the confusion - I was referring to the below API, Which is inside ci.cpp.

    #if defined(FFTLIB_CHECK_PARAMS) ||                                            \
        defined(FFTLIB_FFT1D_I16SC_C16SC_O16SC_CHECK_PARAMS)
       status = FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams (
           pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift,
           pBlock);
       if (status == FFTLIB_SUCCESS)
    #endif

    Regards,

    Betsy Varughese

  • Hi Betsy, 

    Tell me if I'm wrong, but if the code run in loop so far, it was because the compiler didn't have the definition of the FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams function since none of the following predefined symbol were declared : FFTLIB_CHECK_PARAMS ||FFTLIB_FFT1D_I16SC_C16SC_O16SC_CHECK_PARAMS

    As a result, I tried to add one of them : 

    Then, I uncommented the use of FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams in the main() function. However, I got the previous issue again, could you explain why ? 

    Regards

  • Hi Betsy, 

    I'm coming back to you because I'm facing the same previous issue while trying to use the FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() function. Obviously, I commented back the FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams function before doing that.

    Here is my entire code :

    #include <fftlib.h>
    #include <c7x.h>
    #include "common/FFTLIB_bufParams.h"        //utilisation type FFTLIB_bufParams1D_t
    #include "common/FFTLIB_types.h"            //utilisation FFTLIB_32
    #include <cmath>
    #include <math.h>                           //fonction pow()
    #include "common/TI_memory.h"               // fonction TI_memalign()
    #include <iostream>
    #include <cstring>  //pour utilisation memcmp()
    
    
    
    /*
     * Utilisation des fonctions FFTLIB_fft1d_i16sc_c16sc_o16sc.h
     */
    
    
    using namespace std;
    
    
    // Ici j'indique au compilateur que le contenu de cette fonction se trouve dans un autre fichier source
    // ici comme je suis dans un fichier C++, ca implique qu elle se trouve ailleurs mais dans un autre fichier C++ aussi
    extern void tw_gen (int16_t *pW, uint32_t numPoints);
    
    
    // Piste abandonnee a cause d erreurs successives d acces a des headers
    // Utilisation du tableau de shift d'un autre fichier source C : idat.c
    // => Necessite d'utiliser mot clef "extern" pour que le compilateur trouve la def de la variable
    // + "C" parce que la def se trouve dans un fichier.c et que nous on code dans un fichier C++
    //extern "C" {
    //    static uint32_t shiftVector4;
    //}
    
    
    // Pour initialisation de pBlock
    // L'utilisation du tableau def dans le d.c ne marche pas meme avec extern "C"
    uint8_t FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock[FFTLIB_FFT1D_I16SC_C16SC_O16SC_PBLOCK_SIZE];
    
    
    // Declaration en variable globale des data d entree TI
    int16_t staticRefInput4[] = {
        -108, -126, 109,  86,   56,  62,   -46, 8,    -88, -101, -78, -127, 67,   -33, -12, 97,  117, 109,  32,   91,  -44, -118, 117,  72,  20,  -43,
        -66,  -77,  82,   19,   31,  -84,  -22, -115, -46, -114, -30, -73,  -115, 25,  118, 25,  -18, 92,   61,   90,  67,  -39,  -21,  88,  11,  85,
        -72,  86,   34,   -107, -11, -113, -54, 125,  -37, 3,    86,  38,   -124, 89,  12,  90,  9,   -13,  -12,  22,  14,  17,   -109, 84,  22,  -16,
        2,    -79,  128,  76,   52,  -53,  -38, -105, 113, 106,  63,  -110, -85,  -68, -50, -82, 71,  -124, 93,   -16, 42,  -122, 78,   -70, -64, -45,
        -118, 57,   -127, 124,  -17, -65,  117, -40,  12,  68,   -70, -76,  6,    -18, -96, -3,  -70, -113, -111, 51,  92,  -8,   104,  -108};
    
    uint32_t shiftVector4[]     = {0, 0, 0};
    
    
    int main(void){
    
    
            /* --- PARAMETRES D ENTREES --- */
    
        //Pas utilisable car aucun tableau d entree de TI contient 2^13 valeurs
        //uint32_t numPoints = pow(2,13);        // a voir, j'ai mis pareil que code PRESTO
        // je mets un nbr de points me permettant d utiliser les tableaux du idat.c
        uint32_t numPoints = sizeof(staticRefInput4) / sizeof(staticRefInput4[0]);
        cout << " Le nombre de points de la FFT est : " << numPoints << endl;
        uint32_t numShifts = 3;                // voir rep TI pour raisonnement derriere le choix de cette valeur, j ai mis le meme nombre que dans shiftVector4
    
    
    
            /* --- BUFFER D ENTREE X --- */
    
        /* --- Creation de pX --- */
        // D apres FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c file, on doit aligner le buffer d entree sur 16 bytes
    //    int16_t *pX = (int16_t *) TI_memalign (64, numPoints * 2 * sizeof (int16_t));   //placement pour respect contrainte
        int16_t *pX = (int16_t *) TI_memalign (64, sizeof(staticRefInput4));
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pX,staticRefInput4, sizeof(staticRefInput4));
    
    //     Verification des copies de staticRefInput4 dans pX         STATUT : OK !
    //    for(int k=0; k<numPoints; k++){
    //
    //        cout << " La " << k << "ème valeur vaut " << pX[k] << endl;
    //    }
    
        /* --- Creation de bufParamsX --- */
        FFTLIB_bufParams1D_t *bufParamsX;
        bufParamsX -> data_type = FFTLIB_INT16;
        bufParamsX -> dim_x = numPoints;        //nombre d elements du buffer dans la direction X (donc ici en 1 dimension)
    
    
    
            /* --- BUFFER DE TWIDDLE FACTORS W --- */
    
        /* --- Creation de pW --- */
        // pW pointe vers un tableau contenant les twiddle factors
        // les twiddle factors peuvent etre generes par la fonction tw_gen dans le dc file du folder test
        // Pour initialisation @ pW : utilisation de la fonction TI_memalign() du header TI_memory.h
        // Analyse : j ai l impression que c est une forme d allocation memoire "optimisee" a verifier
    
        int16_t *pW = (int16_t *) TI_memalign ( 64, numPoints * 2 * sizeof (int16_t));  //allocation memoire pour stocker les twiddle factors
        tw_gen (pW, numPoints); //generation des twiddle factors
    
        // Je verifie qu on a bien genere les facteurs
        int pw_nb = numPoints * 2;
    //    cout << " Le nombre de twiddle factors est de : " << pw_nb << endl;
    
    //    for(int i=0; i< pw_nb; i+=2){       //pas de 2 pour l'incrementateur pour lire d'un coup partieR et I
    //
    //        cout << "La partieR du twiddle est :" << pW[i] << endl;
    //        cout << "La partieI du twiddle est :" << pW[i+1] << endl;
    //    }
        // Res : on obtient des valeurs correspondants a des entiers 16 bits Q15
        // De ce que je vois, pas besoin de conv de sorte a avoir des valeurs entre -1 et 1 pour utiliser les fonctions pour le FFT
    
        /* --- Creation de bufParamsW --- */
        FFTLIB_bufParams1D_t *bufParamsW;
        bufParamsW -> data_type = FFTLIB_INT16;
        bufParamsW -> dim_x = numPoints * 2;
    
    
            /* --- OBTENTION BUFFER DE SPLIT FACTORS --- */
    
        /* --- Creation de pShift --- */
        // methode 1 : utilisation TI_memalign()
        uint32_t *pShift = (uint32_t *) TI_memalign (64, numShifts * sizeof (uint32_t));
    
        //utilisation d'un memcpy pour recup les valeurs de data de TI
        memcpy(pShift,shiftVector4, sizeof(shiftVector4));
    
        // Verification des copies
    //    for(int n=0; n<numShifts; n++){
    //
    //            cout << " La " << n << " ème valeur vaut " << pShift[n] << endl;
    //    }
    
        /* --- Creation de bufParamsShift --- */
        FFTLIB_bufParams1D_t *bufParamsShift;
        bufParamsShift -> data_type = FFTLIB_INT32;
        bufParamsShift -> dim_x = numShifts;
    
        // Pour le moment methode abandonnee
        // methode 2 : utilisation de tableau de split factors fournis par TI dans file : FFTLIB_fft1d_i16sc_c16sc_o16sc_idat.c
        // => Implique l'ajout du predefined symbol ALL_TEST_CASES pour y avoir acces
        //uint32_t *pShift;
        //pShift = shiftVector4;   //on recupere les donnees du fichier idat.c
    
        // methode 3 : utilisation de la fonction split_factor_gen_r2c()
    
    
    
            /* --- OBTENTION BUFFER DE SORTIE Y --- */
    
        /* --- Creation de pY --- */
        // Pour moi, faut juste allouer de l espace memoire pour stocker les res de la FFT => fait via TI_memalign()
        int16_t  *pY = (int16_t *) TI_memalign (64, numPoints * 2 * sizeof (int16_t));
    
        /* --- Creation de bufParamsY --- */
        FFTLIB_bufParams1D_t *bufParamsY;
        bufParamsY -> data_type = FFTLIB_INT16;
        bufParamsY -> dim_x = numPoints;
    
    
            /* --- OBTENTION BUFFER PBLOCK --- */
        // role de pBlock : j ai l impression que c est un buffer utilise par les streaming engines
        // OUI : doit pouvoir stocker les parametres des streaming engines
    
        // Log de debug
        cout << " Début création du pointeur pBlock " << endl;
        // Initialisation du pointeur via mot clef NULL
        uint8_t* pBlock;
        pBlock = &FFTLIB_fft1d_i16sc_c16sc_o16sc_pBlock[0];   // on peut pas mettre &FFTLIB_fft1d_i16sc_c16sc_o16sc_pBloc sinon je fais pointer un pointeur simple vers pointeur d'un tableau de 576 val
        // Log de debug
        cout << " Fin création du pointeur pBlock " << endl;
    
    
            /****** DEBUT IMPLEMENTATION ALGO FFT ******/
    
    
        // Ordre des fonctions à utiliser
        /*
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams() : function checks the validity of the parameters passed to init and kernel functions
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_init(): function setting up the configuration for the streaming engine
         * FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() This function is the main kernel compute function
         *
         */
    
        // Indicateur etat apres chaque passage dans fonctions TI
        FFTLIB_STATUS status = FFTLIB_SUCCESS;  //initialise a l etat de succes
    
    //    /* --- CHECK DE LA VALIDITE DES PARAMETRES POUR INIT() ET KERNEL() FUNCTIONS --- */
    //    // Attention : pour que le compilateur connaisse la def de la fonction, on doit ajouter FFTLIB_CHECK_PARAMS en predefined symbol
    //    status = FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
    //
    //    if(status == FFTLIB_SUCCESS){
    //
    //        cout << "Les parametres d'entrée sont valides" << endl;
    //    }
    //
    //    else{
    //
    //        cout << "Des paramètres d'entrée ne sont pas valides" << endl;
    //        exit(EXIT_FAILURE);
    //    }
    
    
    
        /* --- INITIALISATION --- */
        // fonction prend en charge des "one-time operations", comme la config des streaming engine
        status = FFTLIB_fft1d_i16sc_c16sc_o16sc_init (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
    
    
        if(status == FFTLIB_SUCCESS){
    
            cout << " L'initialisation s'est faite correctement " << endl;
        }
    
        else{
    
              cout << " Un problème s'est produit lors de l'initialisation" << endl;
              exit(EXIT_FAILURE);
        }
    
    
    
        /* --- EXECUTION DE L ALGORITHME FFT --- */
        status = FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel (pX, bufParamsX, pW, bufParamsW, pY, bufParamsY, pShift, bufParamsShift, pBlock);
    
        if(status == FFTLIB_SUCCESS){
    
            cout << " L'exécution de l'algo FFT s'est bien passée" << endl;
        }
    
        else{
    
              cout << " Un problème s'est produit lors de l'exécution de l'algo FFT " << endl;
              exit(EXIT_FAILURE);
        }
    
    
    	return 0;
    }
    


    Regards, 

    Mélanie

  • Hi Melanie,
    Could you please confirm whether the twiddle factor and input values are generated before the  FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel()  is called.

    Regards,
    Shabary S Sundar.

  • Just read my previous message, the answer is there

  • Hi Melanie,
    Could you please try to generate the twiddle factors separately and initialize the pW array with those values and then execute the FFT kernel function using the generated pW and input signal px to compute the FFT output.

    Regards,
    Shabary S Sundar

  • Hi Betsy, 

    Any news about the issue I'm facing with the use of the kernel function ?

    Thanks for your time and help

    Mélanie ESTEVES 

  • Hi Sharaby, 

    Why do you believe this change is linked to the issue of the kernel function ?

    Regards, 

    Mélanie

  • Hi Melanie,

    Thanks for the details.

    I'm coming back to you because I'm facing the same previous issue while trying to use the FFTLIB_fft1d_i16sc_c16sc_o16sc_kernel() function. Obviously, I commented back the FFTLIB_fft1d_i16sc_c16sc_o16sc_checkParams function before doing that

    Are you encountering the same issue after enabling the kernel? Could you please verify whether the input and twiddle factor values are being generated correctly?

    Could you please let me know the value of numPoints?

    I will check the code and get back to you.

    Regards,

    Betsy Varughese