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.

TMS320C6678: Problem EMIF16 interface with FPGA

Part Number: TMS320C6678


Hello,

c6678 is connected to DPRAM of FPGA over EMIF16 interface. I am sure that the hardware connection is correct. EMIFA23 is connected to A0 of DPRAM  as mentioned in EMIF16 user guide.

The problem is that when c6678 write odd word length data, the first word is not properly saved to DPRAM. 

Please let me know how to resolve this problem.

I captured test code. Just memcpy array to DPRAM.

When writing 16 word, the first word was sent correctly - value is 0xcfae to address 0x78500000.

When writing 17 word, the first word was sent twice(high byte, low byte separately) to same address 0x78500000. Consequently DPRAM has only low byte - 0x00ae.

  • Hi,

    I've notified the RTOS team. They will post their feedback directly here.

    Can you elaborate which Processor SDK RTOS version are you using?

    Best Regards,
    Yordan
  • Hello!
    As a matter of experiment, could you try 16-bit stores in for loop instead of memcpy()?
  • Dear Yordan,

    I installed "ti-processor-sdk-rtos-c667x-evm-04.01.00.06-Windows-x86-Install.exe".

    The version of SYS/BIOS installed is 6.46.5.55

    Best Regards.

  • Hi,

    Can you clarify what code you used for EMIF16 interface setup from ti-processor-sdk-rtos-c667x-evm-04.01.00.06?

    Regards, Eric
  • Hello,
    I tried 16-bit stores in for loop instead of memcpy().
    Every word transferred correctly to DPRAM.

    The difference from memcpy() was that CS signal was asserted at every time WE signal was asserted.
  • Dear Eric,

    There is no EMIF16 setup function in my code.
    I am testing at debug mode(no boot).
    When connecting target, evmc6678l.gel is loading for initialization.

    Should I modify gel file?
  • Hi,

    Great to know you have this working using 16-bit stores in for loop! In DSP no boot mode, the GEL does the SOC initialization, this includes PLL setup, PSC domain turn on and DDR3 setup, You can look at the GEL at ccs_base\emulation\boards\evmc6678l\gel, starting function OnTargetConnect() to determine if any setup is needed for your EMIF case.

    Regards, Eric
  • Dear Eric,

    The only function related EMIF16 in gel file is "Setup_Memory_Map( )".  Do I need to change below code?

    GEL_MapAddStr( 0x78000000, 0, 0x04000000, "R|W|AS4", 0 ); // EMIF16 CS4 NOR

    Anyhow, can you let me know why odd words memcpy() does wrong operation? 

    I need to explain my customer engineer.

    Best Regards,

  • Hi,

    The GEL_MapAddStr( 0x78000000, 0, 0x04000000, "R|W|AS4", 0 ); // EMIF16 CS4 NOR =====> This is setup the memory attribute from CCS point of view, it is not really code.

    For the memcpy(), you may refer to: e2e.ti.com/.../166642

    Regards, Eric
  • Hello!

    In the starting post of the topic the most notable difference was in behaviour of CS vs WE signals. That's just the sign something was different in access.

    As loop with 16-bit writes was fine, I think the true reason might be in implementation of memcpy() function. I found something I think might be relevant at TI\ccsv8\tools\compiler\c6000_7.4.24\lib\src\memcpy64.asm :

    ;*****************************************************************************/
    ;*
    ;* void *memcpy(void *restrict dst, const void *restrict src, unsigned int len)
    ;* {
    ;*   char *restrict s_p  = (char *)src;
    ;*   char *restrict d_p  = (char *)dst;
    ;*   int   loop          = len >> 3;
    ;*   int   i;
    ;*
    ;*   if (len & 1)      *d_p++ = *s_p++;
    ;*   if (len & 2)    { *d_p++ = *s_p++; *d_p++ = *s_p++; }
    ;*   if (len & 4)    { _mem4(d_p)  = _mem4(s_p);  d_p += 4; s_p += 4; }  
    ;*   if (loop == 1)   _memd8(d_p) = _memd8(s_p);   
    ;*
    ;*   if (loop >= 2)
    ;*       for (i = 0; i < loop; i++, d_p += 8, s_p += 8)
    ;*          _memd8(d_p) = _memd8(s_p);
    ;*
    ;*   return dst;
    ;* }
    ;*
    ;*****************************************************************************
    

    If I got it right, they try to copy 1, then 2, then 4 bytes until remaining count gets multiple of 8 and then proceed with 8 byte copying. So I suspect, when your word count is odd, or, equivalently, your byte count is even, then following line is executed:

    if (len & 2)    { *d_p++ = *s_p++; *d_p++ = *s_p++; }

    This makes two byte accesses, which you observe as high and low bytes of the first word were sent separately.

    For me, I am surprised memcpy() implementation attempts to adjust counter at the beginning and proceed with unaligned _memd8 instead of search for aligned boundary. But either way, you'd better keep away of using memcpy() to serve your peripheral.

    In your position I would not disregard for loop in favour of memcpy. With alignment that could probably result in very efficient implementation.

    Hope this helps.