Forum Discussion

EEren's avatar
EEren
Icon for Occasional Contributor rankOccasional Contributor
6 years ago

MAX10 RSU Project

I'm looking at MAX10 RSU Project - an example how to download a binary image file to CFM1/2.

There is following lines

case 9:	/*State 9: Start write into CFM1 with new image*/
for(address=CFM1StartAddress; address<=CFM1EndAddress; address=address+4)
{
     scanf("%2x%2x%2x%2x",&receivedHex[0],&receivedHex[1],&receivedHex[2],&receivedHex[3]); /*Get 4 bytes from UART Terminal*/
    for(byte=0; byte<4; byte++)
   {
		receivedHex[byte] = (((receivedHex[byte] & 0xaa)>>1)|((receivedHex[byte] & 0x55)<<1));		/*Swap LSB with MSB before write into CFM*/
		receivedHex[byte] = (((receivedHex[byte] & 0xcc)>>2)|((receivedHex[byte] & 0x33)<<2));
		receivedHex[byte] = (((receivedHex[byte] & 0xf0)>>4)|((receivedHex[byte] & 0x0f)<<4));
	}
 
	word = (receivedHex[0]<<24)|(receivedHex[1]<<16)|(receivedHex[2]<<8)|(receivedHex[3]);					/*Combine 4 bytes to become 1 word before write operation*/
	IOWR_32DIRECT(ONCHIP_FLASH_0_DATA_BASE, address, word);					/*Command to write into On-Chip Flash IP*/
 
and so on...

The first question - why the address incremented by 4 - for(address=CFM1StartAddress; address<=CFM1EndAddress; address=address+4) - every address holds 32 bits.

The second one - we get bytes from rpd file but lsb byte goes as msb byte in the address? word = (receivedHex[0]<<24)|(receivedHex[1]<<16)|(receivedHex[2]<<8)|(receivedHex[3]);

5 Replies

  • JohnT_Altera's avatar
    JohnT_Altera
    Icon for Regular Contributor rankRegular Contributor

    Hi,

    Avalon Master is using byte addressing so that it can handle different data width from 8bit to 64bit data.

    The default rpd file generated is in little endian format while the On Chip Memory need Big Endian format. So if you are using little endian format rpd file then you will need to performed endian swap.

  • EEren's avatar
    EEren
    Icon for Occasional Contributor rankOccasional Contributor

    Why byte addressing? It says we writes words in ug-m10-ufm-16.0.pdf, so we create a word word = (receivedHex[0]<<24)|(receivedHex[1]<<16)|(receivedHex[2]<<8)|(receivedHex[3]); then write it to a specific address and then what? skip 4 addresses?

    When I generate FLASH UPDATE IP in QSYS

    component flash_update is

    port (

    clock : in std_logic := '0'; -- clk.clk

    avmm_csr_addr : in std_logic := '0'; -- csr.address

    avmm_csr_read : in std_logic := '0'; -- .read

    avmm_csr_writedata : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata

    avmm_csr_write : in std_logic := '0'; -- .write

    avmm_csr_readdata : out std_logic_vector(31 downto 0); -- .readdata

    avmm_data_addr : in std_logic_vector(18 downto 0) := (others => '0'); -- data.address

    avmm_data_read : in std_logic := '0'; -- .read

    avmm_data_writedata : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata

    avmm_data_write : in std_logic := '0'; -- .write

    avmm_data_readdata : out std_logic_vector(31 downto 0); -- .readdata

    avmm_data_waitrequest : out std_logic; -- .waitrequest

    avmm_data_readdatavalid : out std_logic; -- .readdatavalid

    avmm_data_burstcount : in std_logic_vector(3 downto 0) := (others => '0'); -- .burstcount

    reset_n : in std_logic := '0' -- nreset.reset_n

    );

    end component;

    as we can see data bus 32-bit and on every write I should increment avmm_data_addr by one as I understand.

    When I create Altera On-Chip Flash IP I get the following addresses

    sector 3 - 0x10000 - 0x6FFFF

    sector 4 - 0x70000 - 0xB7FFF

    sector 5 - 0xB8000 - 0x15FFFF

    But when I Generate HDL

    SECTOR3_START_ADDR => 16384,

    SECTOR3_END_ADDR => 114687,

    SECTOR4_START_ADDR => 114688,

    SECTOR4_END_ADDR => 188415,

    SECTOR5_START_ADDR => 188416,

    SECTOR5_END_ADDR => 360447,

    So it's already divided by 4. Isn't it?

  • JohnT_Altera's avatar
    JohnT_Altera
    Icon for Regular Contributor rankRegular Contributor

    Hi,

    If you are refering to Avalon-MM Slave then it is addition by 1 on each avmm_data_addr or avmm_csr_addr.

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    As mentioned, Avalon masters use byte addressing and Avalon slaves use word addressing. The word size is typically the data width (32 in this case). So Avalon masters access the registers/memory locations for a slave at addresses 0x0, 0x4, 0x8, etc. For a 16 bit slave, the master would access the slave at 0x0, 0x2, 0x4, etc., though if the master itself is 32-bit, it would only need to access at 0x0, 0x4, etc. and could use byte enables for the appropriate bytes/words. See the Avalon spec for details:

    https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/mnl_avalon_spec.pdf

    Also check out online training:

    https://www.intel.com/content/www/us/en/programmable/support/training/course/oqsys3000.html

    #iwork4intel