Search code examples
fpgaxilinxvivadozynq

Vitis: Store 16 byte variable into 4 32-bit registers


I have a const unsigned char input, 16 byte. And I need to store it into 4 32-bit registers. Vitis allows to store 32 bit variable to 32 bit register using Xil_Out32. But I do not know how can I separate a 16 byte input to 4 pieces.

#define MY_REGISTER  XPAR_AES_ENCDEC_0_S00_AXI_BASEADDR /*Get the register address*/
#define MY_REGISTER_1  MY_REGISTER + 0
#define MY_REGISTER_2  MY_REGISTER + 4
#define MY_REGISTER_3  MY_REGISTER + 8
#define MY_REGISTER_4  MY_REGISTER + 12

void key_init(const unsigned char key[]);
     Xil_Out32(MY_REGISTER, /*4 byte key*/);

This is the key I will receive. Input testbench from VHDL code:

key <= x"00112233445566778899aabbccddeeff";

And I want to put it into 4 register. I already got the register base address: 00112233 to MY_REGISTER_1, 44556677 to MY_REGISTER_2, 8899aabb to MY_REGISTER_3, ccddeeff to MY_REGISTER_4.


Solution

  • You can cast the pointer to the bytes into a pointer to 32-bit values, and use this to read the values for the registers.

    void key_init(const unsigned char key[]) {
        const u32* pointer = (const u32*)key;
        Xil_Out32(MY_REGISTER_1, pointer[0]);
        Xil_Out32(MY_REGISTER_2, pointer[1]);
        Xil_Out32(MY_REGISTER_3, pointer[2]);
        Xil_Out32(MY_REGISTER_4, pointer[3]);
    }
    

    Notes:

    An array given as a function parameter is converted to a pointer.

    Accessing pointer[index] is equivalent to *(pointer + index).

    Please consider endianness, you might need to use Xil_Out32BE() or Xil_Out32LE() or change the sequence of indexes to pointer.

    Your byte array needs to be aligned on a u32 boundary, if your processor needs this. Anyway, if the byte address is not convertible to a u32 pointer because of alignment, this is Undefined Behavior. It might work, but only for your specific target.