Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21604 Discussions

Binary format for Stratix IV Image in a NOR CFI Flash?

Altera_Forum
Honored Contributor II
1,803 Views

My application requires that a host system can write a new FPGA image into an on board Nor Flash (CFI intel P30 style 16 bit flash).  

Without using a JTAG pod, or Quartus Programmer.  

 

Instead, the flash becomes memory mapped to a host CPU PCI Express address space. The question is how to format the data correctly from the system host? 

 

The board uses Altera's Parallel Flash Loader in a MAXII CPLD to configure the FPGA from NOR flash in Fast Passive Parallel Mode.  

 

I can program the flash successfully using the Quartus programming JTAG tools, and the FPGA loads those designs up correctly.  

 

When I examine the flash contents, I see a 4 byte preamble at the start of the memory partition, that is not included in a Raw Binary File (.rbf) when I use the Quartus "Convert Programming File" tools.  

 

It looks like this:  

 

0x0000 

0x042D 

 

Then the data following that preamble matches the .rbf contents (except for byte swapping). 

 

Is this preamble documented anywhere? Is there more at the back end as well? 

 

I have been unable to find any documentation on this preamble..
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
1,047 Views

The details seem to be hiding in the "sof2flash" command line utility. 

 

Note this page as well, if using the PFL in a CPLD: 

 

http://www.altera.com/support/kdb/solutions/rd08102010_306.html
0 Kudos
Altera_Forum
Honored Contributor II
1,047 Views

Replying to this post since it does quite well on Google, and I spent a lot of time tracking down the details. 

 

The 0x04 is a version number of the pof header. The PFL Parallel Flash Loader IP inside the configuration CPLD expects to find this, if your bitstream binary header (0xffff, repeating) is found in it's place, the PFL configuration fails. You can inspect generated VHDL code for the PFL flash to determine the format but it is not fun. The .pof headers also include 13-15 bits of length/checksum information, depending on version. Once that many bytes are read, another pof header is expected. 

 

I found this Altera ticket helpful to generate a binary file with PFL headers: http://www.altera.co.uk/support/kdb/solutions/rd08082012_952.html 

 

Briefly: 

1) Generate .sof files during Quartus compilation. 

 

2) Use 'Convert Programming File' tool to lay out multiple bitstreams in the same file, in expected locations, and write header bits, giving .pof file. 

Page0 - not present 

Page 1 @ 0x00040000 

Page 2 @ 0x02140000 

 

3) Use quartus_cpf to get a .hexout file. This contains the bitstreams with PFL/.pof packetisation, but is in a 7-bit ascii/Intel HEX .hexout representation. 

$ quartus_cpf -c c:\\workspace\\flash_topboot.pof c:\\workspace\\flash_topboot.hexout 

 

4) use nios2-elf-objcopy to convert .hexout to .rbf 

$ nios2-elf-objcopy.exe -I ihex -O binary c:\\workspace\\flash_topboot.hexout c:\\workspace\\flash.rbf 

 

5) check format with od 

 

$ od -A x -t x4 /cygdrive/c/workspace/flash.rbf 

000000 ffffffff 20860040 41862140 ffffffff <- PFL options block (no Page0, defined Page1 and Page2) as documented in PFL docs 

000010 ffffffff ffffffff ffffffff ffffffff 

000080 ffffff03 ffffffff ffffffff ffffffff 

000090 ffffffff ffffffff ffffffff ffffffff 

040000 05fc0401 ffffffff ffffffff ffffffff <- start of first bitstream, POF Version x04 for block 1 

040010 ffffffff ffffffff ffffffff ffffffff 

040080 ffffffff 6a6a6a6a fffff236 fffffa77 

040090 fffff1b6 fffff03d fffff7f6 fffff477 

0400a0 fffff9b3 fffff8ba fffff35a fffff27a 

0400b0 fffff61b fffff759 fffff87a fffff959 

0400c0 fffff418 fffff6bc fffff07d fffff698 

0400d0 fffff47d fffff63f fffff27a fffff19c 

0400e0 fffff118 fffff1fd fffff7fd fffff519 

0400f0 fffff059 fffff019 fffff2d9 fffff019 

040100 fffff29d fffff15d fffff71c fffff75d 

040110 fffff30b fffff75f fffff49a fffff46a 

040120 fffff19a fffff96a 551b0000 ffffffff 

040130 ffffffff ffffffff ffffffff ffffffff 

040600 05940401 00000000 00000000 00000000 <- repeat of POF Header for block two, 600 bytes after 

040610 00000000 00000000 00000000 00000000 

040620 00000000 00000000 00000000 48004800 

040630 48004800 00000000 00000000 48004800 

040640 00000000 00000000 00000000 00000000 

040790 00000000 40000000 00000000 00000000 

0407a0 00000000 00000000 00000000 00000000 

0407b0 40000000 00000000 00000000 00000000 

0407d0 00000000 00000000 00000000 00000000 

0408b0 00000000 00000000 00000000 48004800 

0408c0 00000000 00000000 00000000 00000000 

0408e0 00000000 00000000 48004800 00000000 

0408f0 00000000 48004800 00000000 48004800 

040900 48004800 00000000 00000000 00000000 

040910 00000000 00000000 00000000 00000000 

040940 00000000 00000000 40000000 00000000 

040950 40000000 00000000 40000000 00000000 

040960 40000000 40000000 00000000 00000000 

040970 40000000 40000000 40000000 40000000 

040980 00000000 00000000 40000000 00000000 

040990 40000000 00000000 40000000 00000000 

0409a0 40000000 00000000 00000000 40000001 

0409b0 40000001 00000001 40000001 00000001 

0409c0 00000001 40000001 00000001 00000001 

0409d0 00000001 00000001 40000001 40000001 

0409e0 00000001 40000001 00000001 00000001 

0409f0 00000001 40000001 01000001 40000000 

040a00 00000000 00000000 00000000 00000000 

040a10 40000000 00000000 00000000 40000000 

040a20 00000000 00000000 00000000 00000000 

040a30 00000000 00000000 00000000 41020000 

040a40 00000000 00000000 01020000 41020000 

040a50 01020000 01020000 00000000 00000000 

040a70 01020000 00000000 40000000 40000000 

040a80 00020000 01020000 00000000 00000000 

040a90 00020000 00000000 01020000 00000000 

040aa0 00020000 00000000 00020000 00000000 

040ab0 00020000 00000000 01000000 00000000 

040ac0 00000000 00000000 00000000 00000000 

040ae0 00000000 00000000 00000000 00020000 

040af0 00000000 00000000 00000000 00000001 

040b00 00000001 00020001 00000001 41020001 

040b10 41020001 41000000 41000001 00000001 

040b20 40000001 00000001 40000001 00000001 

040b30 40000000 01020000 00000000 01020000 

040b40 40000000 00020000 00020000 01020000 

040b50 00020000 410000c0 00020000 000000c0 

040b60 000000c0 00000000 00020000 00000000 

040b70 00020000 41020000 00020000 01000000 

040b80 00020000 00000000 00020000 00000000 

040b90 40000000 21530000 05940401 00000000 <- repeat of POF Header for block three 

040ba0 01020000 00000000 01020000 00000000 

040bb0 00000000 000000c0 010200c0 000000c0 

040bc0 000000c0 00ec002f 00000000 01020000 

040bd0 00000000 01020000 00000000 00000000 

040be0 00000000 01020000 00000000 01020000 

040bf0 00000000 00000000 00000000 01020000 

040c00 00000000 01020000 00ec00ef 00000000 

040c10 00000000 00ec002f 01ee002f 00ec00ef 

040c20 01ee002f 00000000 00000000 41ee002f 

 

 

6) If you want to flash specific regions of this file, use $dd to cut out byte ranges and use your flash programming routines to write them.
0 Kudos
Altera_Forum
Honored Contributor II
1,047 Views

Awesome! Thanks shuckc, exactly what I needed. 

 

I spent some time trying to figure out why when I convert a sof to rbf directly using the quartus_cpf command 

 

i.e. quartus_cpf -c <input_sof_file> <output_rbf_file> 

 

the rbf file would not match what I saw in the flash (i.e. it lacks the "PFL/.pof packetisation" headers you mentioned). 

However, your method of sof->pof->hexout->rbf matches what I see in the flash. 

 

It is unfortunate that Altera provides different ways to generate a rbf file from an sof, each with different results. 

I wish Altera would make these things more obvious instead of searching through forum posts and knowledgebase tickets for obscure details.
0 Kudos
Altera_Forum
Honored Contributor II
1,047 Views

Great information. I have the same configuration. Flash connected to cpld and uses the PFL to configure the fpga at power up. In the fpga code I've added the ability to connect the fpga IO lines to the flash (of course disconnect from cpld) and have memory mapped the flash into my pcie memory space. I used the tristate controller and tristate bridge to connect the Avalon bus to the flash IO pins. (BAR2 starting address 0x0) I have some questions. 

 

When you use od to dump the rbf file I'm assuming the * are gaps in the file? 

 

So after I erase the entire flash, do I program the flash by writing the rbf file starting at flash address 0x0 and increment the address every write cycle? (Assuming I'm using the slow write one word at a time method for my question.)
0 Kudos
Altera_Forum
Honored Contributor II
1,047 Views

Answered my question about OD, so the * are just covering redundant information, the -v option displays all. 

So I'm assuming if I erase the entire flash just to write the data starting at address 0x0?
0 Kudos
Altera_Forum
Honored Contributor II
1,047 Views

That's correct, "*" in OD simply hides addresses that duplicate the previous row in the memory dump. The PFL options block should lie at physical address zero within the flash space. You can do a partial erase on most flash chips, check the flash chip command set for details. Once I have the options block programmed and working I leave it protected and just erase/unlock the sectors required to write the flash image, e.g. 0x040000- above.  

 

On my board the CPLD and FPGA arbitrate tri-state access to the flash with a simple request/grant protocol on 2 separate pins. Since both chips have the configuration clock used during configuration it's easy to arbitrate within the same clock domain. I have my own QSYS module that wraps up the indirect read/write/erase of the flash chips which is then mapped into PCIe space BAR0 (any BAR will do). I prefer *indirect* access for this type of thing as you don't want an errant process invalidating the bitstream configuration, and the flash controllers usually require some slow command protocol for programming that is better left to software rather then fully implementing in hw to get a writeable flash space. Plus you don't really need the 32mb or so directly exposed to the host anyway. 

 

The configuration mode I use is 32bit fast parallel, so I use 2x 16-wide flash chips to supply this. The PFL loader is fine driving both in read mode (during configuration) since the address bits are common. For programming you need to take care of duplicating the commands on both of the 16bit data bus to make sure you keep both flash command state machines in the same state.
0 Kudos
Reply