09-09-2019 11:47 AM
Our design is based on the Artix-7 'xc7a100tifgg484-1L' FPGA and Cypress 'S29GL128S13FAEV13' BPI FLASH configuration memory clocked via EMCCLK. A MicroBlaze processor (with AXI) will be utilized for executing a software application post configuration. We have a need to dedicate one of the FLASH device sectors for persistent user data storage purposes, but I haven’t been able to locate a definitive resource for implementing this feature. A number of questions have come to mind in this regard:
Is it even possible to access BPI FLASH post configuration via the MicroBlaze with the FPGA that we are using?
Do I need to add an AXI_EMC memory interface to the Block Design and map the pins to the BPI IC?
Are there any specific constraints that we would need to incorporate? STARTUPx directives?
Are there software library routines available for accessing the BPI FLASH device once our MicroBlaze processor is up and running?
Is there a specific tutorial, guide, or app-note describing this implementation available?
Any insights are greatly appreciated.
Again, thank you in advance.
09-09-2019 06:44 PM
Here’s some comments on what we do with SPI-flash - and what I suspect you’ll need to do with BPI-flash.
On a Kintex-7 board using Master-SPIx1 configuration, we write/read parts of the configuration flash that are not used to store the bitstream. The only slightly tricky part of doing this is using the STARUPE2 primitive (see UG953) to get access to the FPGA CCLK pin from the FPGA fabric. The SPI communication protocol is simple enough so that we implemented it ourselves in VHDL. Our communication clock speed, 5MHz, is slow enough so we “bit bang” the clock and data connections in a way that makes the interface pass timing analysis “by design”.
Your Master-BPI flash interface to the Artix-7 is probably described by Fig 2-17 in UG470. I find from Table 1-12 in UG475 that all the FPGA pins used in this interface, except INIT_B, are Multi-function. From Item 15 on page 63 of UG470 (v1.13.1), I understand that the FPGA fabric will have access to all the interface pins except INIT_B after configuration ends. Since, INIT_B connects to the RST pin of the BPI flash, you’ll first need to investigate whether RST must be toggled later when you read/write the flash from the fabric.
Hence, write/read of BPI-flash from the FPGA fabric should be possible if you can solve the INIT_B / RST problem.
Next, you’ll need to learn the asynchronous communication interface with BPI flash (described in the datasheet for your BPI flash). I suspect you’ll find it to be simple and easily added to your MicroBlaze code. If you don’t need a lot of speed, then you can probably “bit bang” the interface and make it pass timing analysis “by design”.
09-12-2019 06:48 AM
I apologize for the delayed response. I got sidetracked for a few days. Thank you very much for the detailed response. I'm beginning to review the suggested documents. Very good information. Some time back, I was able to access the Quad-SPI configuration memory from a ZYNQ. Much of the dialog I have come across regarding BPI is for the Kintex family of devices. I don't believe there has been a specific mention of the capability of accessing BPI from an Artix device. I suppose my main question at this point is, does the Artix family of devices have the same internal logic interface as the Kintex family in regard to the BPI configuration (and access post configuration)? Has anyone ever been able to successfully access the BPI IC using an Artix device. Any foreknowledge on the issue could potentially thwart unnecessary efforts on our part. If access is not possible, we'll need to rethink our implementation as soon as possible.
Again, thank you for your consideration, explanation, and the references.
09-12-2019 04:50 PM
....does the Artix family of devices have the same internal logic interface as the Kintex family in regard to the BPI configuration (and access post configuration)?
If you are referring to the Artix-7 and the Kintex-7 then both have the same interface to BPI flash. That is, Fig 2-17 in UG470 is for all Xilinx 7-Series FPGAs.
09-24-2019 02:06 PM
In my travels of researching post configuration BPI FLASH access, I have located version 4.2 of the ‘xilflash_readwrite_example.c’ program included with the Vivado 2016.4 distribution. It appears to include a section that sets the FLASH IC to ‘Asynchrounous’ mode just prior to ‘XFlash_Initialize()’. It seems that the initialization routine succeeds, but the ‘XFlash_Reset()’ call fails returning a status of ‘XFLASH_BUSY’. I have attempted FLASH access with an EMCCLK as well as the 3MHz internal clocking mechanism. Asynchronous and synchronous modes have also been attempted via constraints. My constraints are currently as follows and my init. code is below. I believe these to be the simplest most straight forward implementation for the KC705. I have been unable to determine the root cause of the inability to gain access to the BPI memory. If anyone notices any missing constraints or blatant mistakes on my part, please let me know. Are there any signals I am neglecting to drive once configuration has completed? Again, any insights are greatly appreciated, and Thank You in advance!
set_property BITSTREAM.CONFIG.BPI_SYNC_MODE DISABLE [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design]
set_property CONFIG_MODE BPI16 [current_design]
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 2.5 [current_design]
#define ASYNC_ADDR 0x17BBE
#define INTEL_CMD_CONFIG_REG_SETUP 0x60606060
#define INTEL_CMD_CONFIG_REG_CONFIRM 0x03030303
#define BPI_FLASH_WIDTH_BYTES 2
WRITE_FLASH_16(XPAR_EMC_0_S_AXI_MEM0_BASEADDR + ASYNC_ADDR, INTEL_CMD_CONFIG_REG_SETUP);
WRITE_FLASH_16(XPAR_EMC_0_S_AXI_MEM0_BASEADDR + ASYNC_ADDR, INTEL_CMD_CONFIG_REG_CONFIRM);
Status = XFlash_Initialize(&BpiFlash, XPAR_EMC_0_S_AXI_MEM0_BASEADDR, BPI_FLASH_WIDTH_BYTES, 0);
if(Status != XST_SUCCESS)
printf("Init failed: %d.\n\r", Status);
Status = XFlash_Reset(&BpiFlash);
if(Status != XST_SUCCESS)
printf("Reset failed: %d.\n\r", Status);