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.

TMS320C6416T: 32 Bit Host Port Interface Endian switching

Part Number: TMS320C6416T

I have a 32bit Host Port Interface between a C6416T Big Endian (CPU) and Altera CycloneV SoC  (host) running embedded linux. The Arm Cores of the SoC access the HPI via the SoC FPGA memory mapped interface.

There seems to be a 4 byte endian switch occurring on data transferred over the interface. i.e uint32 0xAABBCCDD in DSP memory comes out as uint32 0xAABBCCDD in the Arm host without a call to ntohl() or similar byte swapping function, in essence it seems an endian swap has occured across the bus. This is causing issues when writing structures containing uint16 or similar data.

A struct defined in the DSP as:

struct

{

uint16 A = 75;

uint16 B = 42;

}

Is coming over to the arm memory as 

struct

{

uint16 A = 42;

uint16 B = 75;

}

We have to perform a 32bit byte swap to return the data to big endian, before using the ntohs() function to swap back to little endian on a 2 byte basis.

Is this expected behaviour for the HPI in 32 bit mode (that the data is endian swapped on a 4 byte alignment)? The only references I could find for endianess in the documentation were with regards to 16bit operation HWOB etc.

Due to legacy code support and shared code with C55x series chips it is not possible to run the DSP as little endian.

Thanks in advance

  • Hi,

    Can you share which RTOS version are you running on the device? Where are these code samples taken from?

    Best Regards,
    Yordan
  • Hi,

    This is using DSP/Bios v5.42.1.09.

    These are just example structures I wrote in to this post to demonstrate the issue, with possible values to show how the 16 bit values are swapped from DSP to the ARM and vice-versa, but the values are valid IE 75(0x004B) does not become 19200 (0x4B00) even though the endianess of the system has changed . The actual code is a much larger structure containing many data types, one of which is two uint16's in consecutive memory, this is where we first noticed the ordering issue.

    Thanks,
    Matt
  • Is the ARM core big endian or little endian?

  • If you define a struct similar to what you mentioned:

    uint16_t A = 0xAABB;
    uint16_t B = 0xCCDD;

    My expectation on the 6416T side is that:

    1. In memory (for big endian configuration) this appears as : 0xAA 0xBB 0xCC 0xDD.
    2. On the HPI bus this should appear at 0xAABBCCDD (i.e. 0xAA in the MSB and 0xDD in the LSB).

    Can you confirm both of those are true? If so, your issue is on the FPGA side.
  • Matt Thorne53 said:
    These are just example structures I wrote in to this post to demonstrate the issue, with possible values to show how the 16 bit values are swapped from DSP to the ARM and vice-versa, but the values are valid IE 75(0x004B) does not become 19200 (0x4B00) even though the endianess of the system has changed . The actual code is a much larger structure containing many data types, one of which is two uint16's in consecutive memory, this is where we first noticed the ordering issue.

    The behavior you have described is exactly what I would expect if there is a little endian device on the other end of the device.  Here's what I mentioned previously:

    1. In memory (for big endian configuration) this appears as : 0xAA 0xBB 0xCC 0xDD.
    2. On the HPI bus this should appear at 0xAABBCCDD (i.e. 0xAA in the MSB and 0xDD in the LSB).

    Now, in addition to this, the other wrinkle (besides endianness) is the access size.  Is the FPGA treating this as a 32-bit value?  That would make sense since it is a 32-bit bus and in general it would not know whether a given 32-bit word was actually one 32-bit word or two 16-bit words.  So that being the case, here's how the accesses would look on the FPGA side:

    3. The 32-bit data would be written to memory in little endian order as: 0xDD 0xCC 0xBB 0xAA
    4. When your software later performs two 16-bit reads (little endian) it sees 0xCCDD 0xAABB.

    So in general this sounds like the expected behavior to me, assuming that are performing 32-bit little endian reads on the FPGA side.  In general, I think it's the 16-bit accesses that are going to cause the issues, but that's unrelated to the HPI. That's 100% a consequence of using mixed-accesses (32-bit and 16-bit) on a little endian.

    One solution is simply to use all 32-bit elements within your shared structure.  That would avoid these issues.  Alternatively, I think you need some #ifdefs to flip-flop the positions of the 16-bit words if you stay with that.

  • Hi Brad,

    Thanks for the info, it is good to get a clearer idea of the expected operation when talking between a big endian and a little endian system.

    Unfortunately changing the structure format is not possible due to the size impact of changing 16 bit values to 32bit. We will have to look in to other options, either in the FPGA or as #defines as you say.

    Thanks,
    Matt