AUDIO-AM275-EVM: Why does FFTLIB require `.pinit` section for pBlock, while DSPLIB like FIR allows malloc-based pBlock?

Part Number: AUDIO-AM275-EVM
Other Parts Discussed in Thread: FFTLIB

Tool/software:

Hello TI team,

I am working with both FFTLIB and DSPLIB kernels on C7x and I noticed a difference in how the parameter blocks (`pBlock`) are handled:

* In DSPLIB FIR kernels (e.g. `DSPLIB_fir_ci.cpp`), the `InitArgs` struct contains the `pBlock`, and memory for it is allocated dynamically (via `getSize()` + `malloc`). This works fine and the kernel executes without issues.
* In FFTLIB, however, the examples always declare the `pBlock` in the `.pinit` section, e.g.:

```c
#pragma DATA_SECTION(FFTLIB_fft1d_i32f_c32fc_o32fc_pBlock, ".pinit")
uint8_t FFTLIB_fft1d_i32f_c32fc_o32fc_pBlock[FFTLIB_FFT1D_I32F_C32FC_O32FC_PBLOCK_SIZE];
```

If I try to allocate the `pBlock` dynamically using `malloc` (with 128B alignment, same L2SRAM region), the kernel either freezes or crashes. Only the `.pinit` placement works.

---

My questions:

1. Why does FFTLIB require the `pBlock` to be placed in `.pinit` specifically?
2. Is this due to a hardware Streaming Engine (SE/SA) requirement, or a convention enforced by the FFTLIB kernel implementation?
3. Is there any safe way to manage multiple FFT instances (each with its own pBlock) using malloc-allocated buffers, or is `.pinit` mandatory?

Understanding this difference will help us design our memory allocation strategy (we plan to manage multiple FFT/IFFT channels, potentially by copying local pBlocks into a shared global `.pinit` block before execution).

Regards,
Hendry Newman

  • Hi Hendry,

    The only difference I see between the malloc-ed and statically allocated memory is the initial values in the memory. Malloc-ed memory may not be initialized to zero, while the statically allocated memory is set to zero initially. Can you try to set the malloc-ed memory to zero and try again?

    Best regards,

    Ming 

  • I tried that by memset to zero as well. It didnt work. 

  • Hi Hendry,

    Can you share the code segment of malloc-ing, initializing and using of the pBlock in your example? Please also include your linker.cmd, the syscfg and the MAP files for both static and dynamic cases.

    Best regards,

    Ming

  • 1526.ti-fft-expt4.zip

    The above zip file contains the test_fft project and you can try building and running the project with just enabling/disabling the below snippet in my_fft.c:

        //me->fft_pblock     = (uint8_t *) memalign(FFTLIB_BUFFER_ALIGNMENT_REQ, FFT_PBLOCK_SIZE);
        //memset((void *)me->fft_pblock, 0, FFT_PBLOCK_SIZE);
        //me->ifft_pblock    = (uint8_t *) memalign(FFTLIB_BUFFER_ALIGNMENT_REQ, IFFT_PBLOCK_SIZE);
        //memset((void *)me->ifft_pblock, 0, IFFT_PBLOCK_SIZE);

        me->fft_pblock = g_my_fft_pblock;
        me->ifft_pblock = g_my_ifft_pblock;
  • Hi Hendry,

    When I use the malloc to allocate the me->fft_pblock and me->ifft_pblock. The FFT and IFFT run OK and return successfully, but the result is incorrect (test_assert_real_array_within return errors)

    Before process_forward(), the fft_data.fft_inst and ifft_data.fft_inst looked normal:

    After process_forward(), the ifft_data.fft_inst looked wrong:

    You need to check your program closely.

    I also noticed your my_fft_destroy() does not free the fft_pblock or ifft_pblock in the malloc case.

    Best regards,

    Ming

  • my_fft_destroy() does not free the fft_pblock or ifft_pblock in the malloc case --> Yes, I missed it.
    But as I mentioned, while allocating the pblock in .pinit section this issue is not observed at all. 

    Regarding the corruption after fft    could answer better.

  • Hi Hendry,

    I think the issue is with the following code:

    FFTLIB_fft1dBatched_i32fc_c32fc_o32fc_init (
       (FFTLIB_F32 *) pX, &bufParamsX_FFT, (FFTLIB_F32 *) pW,
       &bufParamsX_FFT, (FFTLIB_F32 *) pXFFT, &bufParamsX_FFT,
       (numPoints >> 1), 1, &((uint8_t *) pBlock)[5 * SE_PARAM_SIZE]);

    The pBlock for FFT instance is 14*64, but inside FFTLIB_fft1dBatched_i32fc_c32fc_o32fc_init(), 13*64 have been used (see SA_LOOP6_PARAM_OFFSET). Plus the 5*64 used in FFTLIB_fft_real_forward_init(). There should be at least 18*64 for the FFT instance pBlock.

    Once I changed:

    me->fft_pblock = (uint8_t *) memalign(FFTLIB_BUFFER_ALIGNMENT_REQ, FFT_PBLOCK_SIZE);
    memset((void *)me->fft_pblock, 0, FFT_PBLOCK_SIZE);

    TO

    me->fft_pblock = (uint8_t *) memalign(FFTLIB_BUFFER_ALIGNMENT_REQ, IFFT_PBLOCK_SIZE);
    memset((void *)me->fft_pblock, 0, IFFT_PBLOCK_SIZE);

    The program works as expected.

    Best regards,

    Ming

  • Hi Hendry,

    I talked to the FFTLIB development team. They told me that the functions defined in FFTLIB_fft1d_i32f_c32fc_o32fc.h are obsolete. They will remove the functions defined in FFTLIB_fft1d_i32f_c32fc_o32fc.h in next release. Before that happens, please use the functions defined in FFTLIB_fft1dBatched_i32f_c32fc_o32fc.h instead.

    Best regards,

    Ming 

  • Hi Ming,

    Thanks for your support. I see that the test cases are passing with 18 * SE_PARAM_SIZE (i.e., 18 * 64).
    From your earlier comment, I understood that we should be using:

    #define FFTLIB_FFT1DBATCHED_I32F_C32FC_O32FC_PBLOCK_SIZE (25 * SE_PARAM_SIZE)  //(25*64) 

    Could you please confirm if my understanding is correct? Or do you want us to completely avoid using `
    FFTLIB_fft1d_i32f_c32fc_o32fc` functions?
    Do you see any other issues with using `FFTLIB_fft1d_i32f_c32fc_o32fc`? 

    Does that apply for iift routine as well `FFTLIB_ifft1d_i32fc_c32fc_o32fc`?
  • Hi Hendry,

    Yes. Please use the batched version for FFT and IFFT.

    Best regards,

    Ming

  • Thanks for you support.