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.

TMS320F28379D: FFT result changes depending on memory allocation

Part Number: TMS320F28379D


Hi,

For some reason, the FFT result depends on the memory allocation of the buffer used for FFT.

Are there any restrictions on memory allocation?

The FFT result is incorrect when the memory allocation of TEST_03.map is used.

The FFT result is correct when the memory allocation of TEST_1315.map is used.

<TEST_03.map>

TEST_03.txt

<TEST_1315.map>

TEST_1315.txt

<F2837xD_FPU_CFFT_lnk.cmd>

//#############################################################################
//
// FILE:    F2837xD_FPU_CFFT_lnk.cmd
//
// TITLE:   Linker Command File for FPU library examples that run 
//          on the 2837x platform
//
//          This file includes all RAM and FLASH blocks present on the
//          2837x and depending on the active build configuration(RAM or FLASH)
//          the appropriate sections will either be loaded into RAM or FLASH 
//          blocks
//
//#############################################################################
// $TI Release: C28x Floating Point Unit Library V2.03.00.00 $
// $Release Date: May 26, 2020 $
// $Copyright: Copyright (C) 2018 Texas Instruments Incorporated -
//             http://www.ti.com/ ALL RIGHTS RESERVED $
//#############################################################################
// NOTES:
// 1. In addition to this memory linker command file, add the header linker 
//    command file directly to the project. The header linker command file is 
//    required to link the peripheral structures to the proper locations within
//    the memory map.
//    
//    The header linker files are found in 
//    c2000\C2000Ware_X_XX_XX_XX\device_support\f2837x(d/s)\headers\cmd
//    
//    For BIOS applications add:      F2837x(D/S)_Headers_BIOS_cpuX.cmd
//    For nonBIOS applications add:   F2837x(D/S)_Headers_nonBIOS_cpuX.cmd
//
// 2. On reset all RAMGSx blocks are under the mastership of CPU1. The user
//     must configure the appropriate control registers to transfer mastership
//     of a RAMGSx block over to CPU2
//
// 3. Memory blocks on F2837x are uniform (ie same physical memory) in both 
//    PAGE 0 and PAGE 1. That is the same memory region should not be defined 
//    for both PAGE 0 and PAGE 1. Doing so will result in corruption of program
//    and/or data.
//    
//    Contiguous SARAM memory blocks can be combined if required to create a 
//    larger memory block.
//
//#############################################################################


// The following definitions will help to align the input buffer.For the complex FFT
// of size N, the input buffer must be aligned to a 4N word boundary. For a real FFT
// of size N, the input buffer must be aligned to a 2N word boundary. The user may define
// the macro either in the linker command file, as shown here, or
// through the project properties under,
// C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
--define CFFT_ALIGNMENT=512
#if !defined(CFFT_ALIGNMENT)
#error define CFFT_ALIGNMENT under C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
#endif

MEMORY
{
PAGE 0 :
   /* BEGIN is used for the "boot to SARAM" bootloader mode   */
#if defined(RAM)
   BEGIN           : origin = 0x000000, length = 0x000002
#elif defined(FLASH)
   BEGIN           : origin = 0x080000, length = 0x000002
#endif 
   RAMM0           : origin = 0x000122, length = 0x0002DE
   RAMM1           : origin = 0x000400, length = 0x000400
   
   RAMD0		   : origin = 0x00B000, length = 0x000800
   RAMD1		   : origin = 0x00B800, length = 0x000800
   
   RAMLS0123	    : origin = 0x008000, length = 0x002000
   
   RESET            : origin = 0x3FFFC0, length = 0x000002
   
   FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
   FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
   FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
   FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
   FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
   FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
   FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
   FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
   FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
   FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
   FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
   FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
   FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */   


PAGE 1 :
   BOOT_RSVD       : origin = 0x000002, length = 0x000120     /* Part of M0, BOOT rom will use this for stack */

   RAMLS4          : origin = 0x00A000, length = 0x000800
   RAMLS5          : origin = 0x00A800, length = 0x000800
   
   RAMGS03         : origin = 0x00C000, length = 0x004000
   RAMGS46		   : origin = 0x010000, length = 0x003000
   RAMGS79		   : origin = 0x013000, length = 0x003000
   RAMGS1012	   : origin = 0x016000, length = 0x003000
   RAMGS1315       : origin = 0x019000, length = 0x003000

   FLASHB          : origin = 0x082000, length = 0x002000	/* on-chip Flash */
}
 
SECTIONS
{
   codestart        : > BEGIN,        PAGE = 0
#if defined(RAM)
   .TI.ramfunc      : > RAMLS0123,    PAGE = 0
   .text            :>> RAMM1 | RAMD0 | RAMD1 | RAMLS0123,  PAGE = 0
   .cinit           : > RAMLS0123,    PAGE = 0
   
   .pinit           : > RAMLS0123,    PAGE = 0
   .switch          : > RAMLS0123,    PAGE = 0
   .econst          : > RAMLS4,       PAGE = 1

   //FFT Table
   FPUfftTables     : > RAMLS5, PAGE = 1

#elif defined(FLASH)
   .TI.ramfunc      :
                    {
                       *(.TI.ramfunc)
                       c28x_fpu_dsp_library_coff.lib<CFFT_f32t.obj>(.text)	//coff�̃��C�u������I����Ȃ��Ə������x���x��
                    }
                       LOAD = FLASHC,
                       RUN = RAMLS0123,
                       RUN_START(_RamfuncsRunStart),
                       LOAD_START(_RamfuncsLoadStart),
                       LOAD_SIZE(_RamfuncsLoadSize),
                       PAGE = 0

   .text            : > FLASHA,    PAGE = 0
   .cinit           : > FLASHC,    PAGE = 0

   .pinit           : > FLASHC,    PAGE = 0
   .switch          : > FLASHC,    PAGE = 0
   .econst          : > FLASHB,    PAGE = 1

   //FFT Table
   FPUfftTables     : LOAD = FLASHB,
                      RUN  = RAMLS5,
                      RUN_START(_FFTTwiddlesRunStart),
                      LOAD_START(_FFTTwiddlesLoadStart),
                      LOAD_SIZE(_FFTTwiddlesLoadSize),
                      PAGE = 1,
  {
     --library=c28x_fpu_dsp_library_coff.lib<CFFT_f32_twiddleFactors.obj> (FPUfftTables)
  }

#else
#error Add either "RAM" or "FLASH" to C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
#endif //RAM

   ramgs03            : > RAMGS03,   PAGE = 1

   //FFT
   CFFT_In_data       : > RAMGS1315,    PAGE = 1, ALIGN = CFFT_ALIGNMENT
   CFFT_Out_data      : > RAMGS03,    PAGE = 1
   CFFT_Mag_data      : > RAMGS46,   PAGE = 1
   CFFT_Phase_data    : > RAMGS46,   PAGE = 1
   D_CFFT_In_data     : > RAMGS79,   PAGE = 1, ALIGN = CFFT_ALIGNMENT
   D_CFFT_Out_data    : > RAMGS1012, PAGE = 1

   //TEST Data
   CFFT_Test_data     : > RAMGS1315, PAGE = 1, ALIGN = CFFT_ALIGNMENT

   FPUmathTables      : > RAMGS03,   PAGE = 1
   
   .reset             : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   .cio               : > RAMLS4,    PAGE = 1
   .sysmem            : > RAMLS4,    PAGE = 1

   .stack             : > RAMLS4,    PAGE = 1
   .ebss              : > RAMGS03,   PAGE = 1
   .esysmem           : > RAMLS4,    PAGE = 1
     
}
/*
//===========================================================================
// End of file.
//===========================================================================
*/

<FFT_Result of TEST_03.map>

<FFT Result of TEST_1315.map>

Thank you in advance.

  • Hello,

    As mentioned, " The following definitions will help to align the input buffer.For the complex FFT of size N, the input buffer must be aligned to a 4N word boundary. For a real FFT of size N, the input buffer must be aligned to a 2N word boundary."

    If you don't explicitly state the alignment for the buffer, it will fail. Apart from that, it should not make much of a difference. 

    Hope this helped.

    -Shantanu

  • Thank you for your reply.

    Isn't placing the FFT_Input buffer at 0x0000E400 meant to be aligned on a 4N word boundary?

    The memory is set as follows in the linker command file.
    The value is incorrect only when the FFT_Input buffer is placed in RAMGS03.

    <F2837xD_FPU_CFFT_lnk.cmd>
    --define CFFT_ALIGNMENT = 512
    CFFT_In_data:> RAMGS1315, PAGE = 1, ALIGN = CFFT_ALIGNMENT

    ramgs03:> RAMGS03, PAGE = 1

    RAMGS03: origin = 0x00C000, length = 0x004000
    RAMGS46: origin = 0x010000, length = 0x003000
    RAMGS79: origin = 0x013000, length = 0x003000
    RAMGS1012: origin = 0x016000, length = 0x003000
    RAMGS1315: origin = 0x019000, length = 0x003000

    Thanks in advance.

  • HI,

    user6228344 said:

    CFFT_In_data:> RAMGS1315, PAGE = 1, ALIGN = CFFT_ALIGNMENT

    Isn't there a mismatch in the alignment? You have aligned for 1315 here while placing the buffer in GS03.

    Also, from your screenshot, it appears that the values themselves have changed. Have you investigated why that may be?

    Please try to stick to the template in the example linker cmd files as far as possible.

    Thanks,

    Shanty

  • Thank you for your reply.

    Since the following is defined, I think that there is no problem with alignment.

    --define CFFT_ALIGNMENT=512

    The reason the value has changed is because I used CFFT_f32t.

    My understand is that CFFT_f32t use the buffers which set in InPtr and OutPtr as ping-pong buffers in the calculation process.

    If the FFT stage is odd, the FFT result output to the buffer set to CurrentInPtr.


    Therefore, FFT_input is changed the value.

    I set the FFT_input buffer to InPtr and CurrentInPtr.

    Thanks in advance.

  • Apologies for the late reply:

    user6228344 said:

    Since the following is defined, I think that there is no problem with alignment.

    --define CFFT_ALIGNMENT=512

    Yes but I dont see this alignment being stated explicitly for RAMGS03. You have set that alignment for RAMGS1315.

  • I'm sorry I didn't have enough information.

    The linker command file when an error occurs is the attached file.

    The difference from the linker command file attached at the beginning is that CFFT_In_data is now RAMGS03.

    I couldn't attach the map file, so I made it a txt file.

    //#############################################################################
    //
    // FILE:    F2837xD_FPU_CFFT_lnk.cmd
    //
    // TITLE:   Linker Command File for FPU library examples that run 
    //          on the 2837x platform
    //
    //          This file includes all RAM and FLASH blocks present on the
    //          2837x and depending on the active build configuration(RAM or FLASH)
    //          the appropriate sections will either be loaded into RAM or FLASH 
    //          blocks
    //
    //#############################################################################
    // $TI Release: C28x Floating Point Unit Library V2.03.00.00 $
    // $Release Date: May 26, 2020 $
    // $Copyright: Copyright (C) 2018 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //#############################################################################
    // NOTES:
    // 1. In addition to this memory linker command file, add the header linker 
    //    command file directly to the project. The header linker command file is 
    //    required to link the peripheral structures to the proper locations within
    //    the memory map.
    //    
    //    The header linker files are found in 
    //    c2000\C2000Ware_X_XX_XX_XX\device_support\f2837x(d/s)\headers\cmd
    //    
    //    For BIOS applications add:      F2837x(D/S)_Headers_BIOS_cpuX.cmd
    //    For nonBIOS applications add:   F2837x(D/S)_Headers_nonBIOS_cpuX.cmd
    //
    // 2. On reset all RAMGSx blocks are under the mastership of CPU1. The user
    //     must configure the appropriate control registers to transfer mastership
    //     of a RAMGSx block over to CPU2
    //
    // 3. Memory blocks on F2837x are uniform (ie same physical memory) in both 
    //    PAGE 0 and PAGE 1. That is the same memory region should not be defined 
    //    for both PAGE 0 and PAGE 1. Doing so will result in corruption of program
    //    and/or data.
    //    
    //    Contiguous SARAM memory blocks can be combined if required to create a 
    //    larger memory block.
    //
    //#############################################################################
    
    
    // The following definitions will help to align the input buffer.For the complex FFT
    // of size N, the input buffer must be aligned to a 4N word boundary. For a real FFT
    // of size N, the input buffer must be aligned to a 2N word boundary. The user may define
    // the macro either in the linker command file, as shown here, or
    // through the project properties under,
    // C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
    --define CFFT_ALIGNMENT=512
    #if !defined(CFFT_ALIGNMENT)
    #error define CFFT_ALIGNMENT under C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
    #endif
    
    MEMORY
    {
    PAGE 0 :
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */
    #if defined(RAM)
       BEGIN           : origin = 0x000000, length = 0x000002
    #elif defined(FLASH)
       BEGIN           : origin = 0x080000, length = 0x000002
    #endif 
       RAMM0           : origin = 0x000122, length = 0x0002DE
       RAMM1           : origin = 0x000400, length = 0x000400
       
       RAMD0		   : origin = 0x00B000, length = 0x000800
       RAMD1		   : origin = 0x00B800, length = 0x000800
       
       RAMLS0123	    : origin = 0x008000, length = 0x002000
       
       RESET            : origin = 0x3FFFC0, length = 0x000002
       
       FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
       FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
       FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
       FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
       FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
       FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
       FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
       FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
       FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
       FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
       FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
       FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
       FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */   
    
    
    PAGE 1 :
       BOOT_RSVD       : origin = 0x000002, length = 0x000120     /* Part of M0, BOOT rom will use this for stack */
    
       RAMLS4          : origin = 0x00A000, length = 0x000800
       RAMLS5          : origin = 0x00A800, length = 0x000800
       
       RAMGS03         : origin = 0x00C000, length = 0x004000
       RAMGS46		   : origin = 0x010000, length = 0x003000
       RAMGS79		   : origin = 0x013000, length = 0x003000
       RAMGS1012	   : origin = 0x016000, length = 0x003000
       RAMGS1315       : origin = 0x019000, length = 0x003000
    
       FLASHB          : origin = 0x082000, length = 0x002000	/* on-chip Flash */
    }
     
    SECTIONS
    {
       codestart        : > BEGIN,        PAGE = 0
    #if defined(RAM)
       .TI.ramfunc      : > RAMLS0123,    PAGE = 0
       .text            :>> RAMM1 | RAMD0 | RAMD1 | RAMLS0123,  PAGE = 0
       .cinit           : > RAMLS0123,    PAGE = 0
       
       .pinit           : > RAMLS0123,    PAGE = 0
       .switch          : > RAMLS0123,    PAGE = 0
       .econst          : > RAMLS4,       PAGE = 1
    
       //FFT Table
       FPUfftTables     : > RAMLS5, PAGE = 1
    
    #elif defined(FLASH)
       .TI.ramfunc      :
                        {
                           *(.TI.ramfunc)
                           c28x_fpu_dsp_library_coff.lib<CFFT_f32t.obj>(.text)	//coff�̃��C�u������I����Ȃ��Ə������x���x��
                        }
                           LOAD = FLASHC,
                           RUN = RAMLS0123,
                           RUN_START(_RamfuncsRunStart),
                           LOAD_START(_RamfuncsLoadStart),
                           LOAD_SIZE(_RamfuncsLoadSize),
                           PAGE = 0
    
       .text            : > FLASHA,    PAGE = 0
       .cinit           : > FLASHC,    PAGE = 0
    
       .pinit           : > FLASHC,    PAGE = 0
       .switch          : > FLASHC,    PAGE = 0
       .econst          : > FLASHB,    PAGE = 1
    
       //FFT Table
       FPUfftTables     : LOAD = FLASHB,
                          RUN  = RAMLS5,
                          RUN_START(_FFTTwiddlesRunStart),
                          LOAD_START(_FFTTwiddlesLoadStart),
                          LOAD_SIZE(_FFTTwiddlesLoadSize),
                          PAGE = 1,
      {
         --library=c28x_fpu_dsp_library_coff.lib<CFFT_f32_twiddleFactors.obj> (FPUfftTables)
      }
    
    #else
    #error Add either "RAM" or "FLASH" to C2000 Linker -> Advanced Options -> Command File Preprocessing -> --define
    #endif //RAM
    
       ramgs03            : > RAMGS03,   PAGE = 1
    
       //FFT
       CFFT_In_data       : > RAMGS03,    PAGE = 1, ALIGN = CFFT_ALIGNMENT
       CFFT_Out_data      : > RAMGS03,    PAGE = 1
       CFFT_Mag_data      : > RAMGS46,   PAGE = 1
       CFFT_Phase_data    : > RAMGS46,   PAGE = 1
       D_CFFT_In_data     : > RAMGS79,   PAGE = 1, ALIGN = CFFT_ALIGNMENT
       D_CFFT_Out_data    : > RAMGS1012, PAGE = 1
    
       //TEST Data
       CFFT_Test_data     : > RAMGS1315, PAGE = 1, ALIGN = CFFT_ALIGNMENT
    
       FPUmathTables      : > RAMGS03,   PAGE = 1
       
       .reset             : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
    
       .cio               : > RAMLS4,    PAGE = 1
       .sysmem            : > RAMLS4,    PAGE = 1
    
       .stack             : > RAMLS4,    PAGE = 1
       .ebss              : > RAMGS03,   PAGE = 1
       .esysmem           : > RAMLS4,    PAGE = 1
         
    }
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    

  • Can you tell me what the exact error is?

  • Thank you for your reply.

    The content of the error is that the FFT result changes depending on the memory allocation.


    The image is attached in the top post, but the upper image is when there is an error and the lower image is when it is normal.


    When normal, it is the same as the FFT calculation result of Matlab.


    At the time of error, it is very different from the FFT calculation result of Matlab.

    I attach the result of my temporary analyss.

    FFT_Result_Error.xlsx