- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]);
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Avalon masters use byte addressing so the address has to be incremented by 4 each time for 32 bit data.
The endian swap is required for the bitstream data put into the CFM. See app note 741 for details:
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/an/an741.pdf
#iwork4intel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you are refering to Avalon-MM Slave then it is addition by 1 on each avmm_data_addr or avmm_csr_addr.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page