I have written a FPGA updater to write to CFM0 using a state machine and the On-Chip Flash Intel FPGA IP. This works well for the the 10M02SC part. However we have moved to the 10M04SA part and the design fails to erase the CFM0 flash. I have checked the address ranges and unlock and erase control register settings bits and I believe these are correct.
--! CFM0 base address 0x00027000 / 4 = 0x9C00 (17 bits)
--! CFM0 top address 0x00049FFF / 4 = 0x127FF (17bits)
constant flash_base_address :std_logic_vector(16 downto 0) := b"0" & x"9C00";
constant flash_top_address :std_logic_vector(16 downto 0) := b"1" & x"27FF";
--! data for flash unlock & erase codes for sector 4
constant data_flash_unlock :std_logic_vector(31 downto 0) := x"FBFFFFFF";
constant data_flash_erase :std_logic_vector(31 downto 0) := x"FBCFFFFF";
I have noticed in simulation a difference between the 10M02 and 10M04 behaviour. The 10M04 has an extra clock cycle latency between issuing the erase command and the status register showing BUSY_ERASE. I have corrected for this but status register busy field returns to IDLE early and erase successful is never set.
I have attached the fpga_updater source and simulation files, and I would appreciate any help to solve this issue.
I'm using a record defined in the device_pkg.vhd to represent the Avalon-MM bus. If you look in the test bench tb_fpga_updater.vhd you can see how the record is used to connect the FLAH_BUS port on the instance of the state machine fpga_updater_1, and the On-Chip Flash Intel FPGA IP instance flash_controller.
The state machine in the file fpga_updater.vhd is based on the state machine in the file MAX10_FLASH_INTERFACE.v associated with the application note "I2C Remote System Upgrade Example (Max 10)". the state machine is using the sector erase mechanism and works fine on a 10M02SC device using the appropriate control interface settings for the On-Chip Flash Intel FPGA IP control register. The settings I used for the 10M02 device can be seen commented out in the file device_pkg.vhd.
However having modified the On-Chip Flash Intel FPGA IP control register settings as shown in my previous post the sector erase is not working on the 10M04SA device.
I have generated the IP component along with its simulation model for both the 10M02 and the 10M04SA using platform designer. The test bench requires a slight modification to instance the correct flash model, and to reduce the address bus width connected to the flash component for the 10M02SC. The correct flash unlock and flash erase control register values, along with the appropriate CFM0 address ranges need to be uncommented in the device_pkg.vhdl file.
I have attached zip files of the IP I have generated in platform designer (int_flash_ctl_10M02.zip & int_flash_ctl_10M04.zip). I believe the configuration is defined by the generic map values of the onchip_flash_0 instance in the file int_flash_ctl_10M04\int_flash_ctl_10M04\simulation\int_flash_ctl_10M04.vhd, and the equivalent file in the 10M02 IP.
I have also checked the protection bits read back from the status register. They are correct to allow read and write access to the CFM0 sector. Sector 3 for the 10M02 part and Sector 4 for the 10M04 part.
I have tested the appropriate code on both the 10M02 and 10M04 hardware with the same result. On the 10M02 device I can erase and reprogram the CFM0 flash, but on the 10M04 it fails to erase the CFM0 flash.
Thanks for the file. After further investigation, I observed that you do not write "cfm_csr_wen" to 0 after you performed ERASE_UNLOCK. Could you performed this step before proceeding with erase. I would recommend that you can try to check if the ERASE Unlock is completed and back to IDLE state before you performed ERASE.
I have modified the state machine as you have suggested to add the following states:
ERASE_UNLOCK_WAIT - Do nothing "csr_wen" and "csr_ren" both low
ERASE_UNLOCK_READ - Read the status register "cfm_csr_wen" low, "csr_ren" and "csr_addr" high
ERASE_UNLOCK_CHECK - Status register read value is valid on "csr_rdata"
I have attached the updated fpga_updater.vhd file along with some jpegs of the simulation results. Although this hasn't resolved the problem, it is interesting that the read of the status register returned the correct write protect bits cleared but with bits 31 to 28 set to 0, see file "Erase Status Reg Read 10M04.JPG". From the "Intel MAX 10 User Flash Memory User Guide" page 24 I would have expected these bits to be returned as '1'.
You can see in the file "Erase Fail 10M04.JPG" that the flash busy signal (bits 0-1 of the csr_rdata bus) transitions to BUSY_ERASE with bit 0 set on the third clock cycle in state ERASE_WAIT_3, after the state ERASE_START has programmed the control register with the sector erase. You can see the erase fail after five clock cycles when the flash_busy signal transitions back to IDLE (0).
For comparison I ran the simulation with the 10M02 model. You can see in the file "Erase Status Reg Read 10M02.JPG" that the behavior of the control register read back is the same as in the 10M04, with bits 31 to 28 set to 0. however the read then goes on to be successful, taking arround 2.5ms as can be seen in the file "Erase Full 10M02.JPG".
File "Erase Successful 10M02.JPG" shows the end of the successful erase cycle with erase successful transitions high at the first marker followed by the flash_busy signal changing from BUSY_ERASE (1) to IDLE (0) five clock cycles later at the second marker.
Thank you for your continued support,
I have managed to successfully erase and program CFM0 on the 10M04SA device.
I modified the value written to the flash control register so that all sectors are unlocked. I then send the command to erase sector 4. I updated the file device_pkd.vhd with the code snippet below showing the relevant values.
--! Unlock all sectors & erase sector 4
constant data_flash_unlock :std_logic_vector(31 downto 0) := x"F07FFFFF";
constant data_flash_erase :std_logic_vector(31 downto 0) := x"F04FFFFF";
The erase failed in the same way when the status register transitions from BUSY_ERASE to IDLE early. File "Unlock all sectors 10M04.JPG" shows the flash unlock write and read back from the control register. File "Unlock all sectors erase fail 10M04.JPG" shows the erase failing early.
I then thought I would try this change on the hardware. Again the erase and program failed. However I altered my firmware to stop after the erase so that I could check if the erase had occurred using a Terasic USB Blaster. To my surprise I found that the erase had been successful. I believe this was because my state machine did not go on to program the flash and the erase had time to complete.
After some thought I remembered I had a similar problem with programming on the 10M02. Although the busy field in the status register was retuning to idle the write successful field was never set. For this reason I used only the avmm_data_waitrequest (cfm_dat_wait) to terminate the program cycle.
I wondered if although I was able to use the status register busy and erase successful fields to terminate the erase on the 10M02, maybe they were not working in the same way in the 10M04.
Instead of waiting for the status register busy and erase successful fields I just implemented a timer to wait 400ms. This is comfortably longer than the maximum erase time stated on page 15 of the Intel Max 10 User Flash Memory User Guide, which is 350ms.
Using the timed erase was successful in the hardware and I was able to then reliably program the configuration data into CFM0 of the 10M04SA device. However the simulation was less happy and was giving the following ERROR messages on every write during the programming phase:
tb_fpga_updater.flash_controller.onchip_flash_0.altera_onchip_flash_block.inst.<protected>.<protected>.<protected>.<protected>.<protected>.<protected>: ERROR: 400127500.00ns, Illegal YADR/ DIN Toggle or 'X' ERROR during prog operation
# tb_fpga_updater.flash_controller.onchip_flash_0.altera_onchip_flash_block.inst.<protected>.<protected>.<protected>.<protected>.<protected>.<protected>.<protected>: ERROR: 400145206.75ns, An extra program pulse is required for smart-program before regular read cycle
I do not see these messages in the 10M02 simulation. I'm happy the timed erase and program seems to be reliable on the hardware, but it would be nice to have an explanation why the simulation is generating the errors. See files "10M04 Error 0114.JPG" and "10M04 Error 0196.JPG" for the first occurrence of these errors in the simulation.
I removed all the additional states I had added to the state machine and have attached the final working version in file "fpga_updater.vhd". The erase timer is in the attached file "flash_erase_timer.vhd". I added a timer to time out a program operation after 1ms, see file "flash_program_timer.vhd".
I am not sure why it is showing error. The other reason of the timing take longer is that you are using Serial Interface where it might be taking longer time. You could try to use Parallel Interface setting in your On Chip Flash IP.