1、概述
根据实际项目需求,设计一个基于SPI总线的Flash驱动控制器,实现FPGA对 Flash存储器(MX25L12833F)的数据写入、数据读取以及块擦除操作,并实际验证。
2、fpga+flash的原理图连接
首先是spi flash的原理图如下,可以看出,该flash芯片是4根线来控制和通信,包含一个cs片选,一个mclk主时钟,两个数据线miso与mosi; 
128M flash图
然后查看四根控制和通信线连接到fpga的bank0上四个pin脚,如下图:

fpga flash引脚图
3、状态机控制
由flash文档可知,一个完整从擦除,写,读操作,都需要按照各自功能中一定的流程来执行,使用状态机实现;在模块内部声明状态机状态变量(state),定义状态机各状态分别为:初始状态(IDLE)、写使能状态(WR_EN)、两指令间等待状态(DELAY)、块擦除状态(BE)、写数据状态(WR_DATA),读取数据状态(RD_DATA);
参考下扇区擦除,绘制的状态波形图如下:

状态机信号波形图
由图中可以看出,要完成一个擦除操作,设计有状态的转变,片选信号状态的由高到低,每个状态的延迟等待时间设计,以及时钟和字节计数器的循环使用,都需要根据文档资料设计好,不谈容易出错;
4、块擦除
块擦除(BE)指令用于将所选块的数据擦除为"1"。该指令用于64K字节的块擦除操作。在发送块擦除(BE)指令之前,必须执行写使能(WREN)指令以设置写使能锁存(WEL)位。块内的任何地址(块表)都是块擦除(BE)指令的有效地址。片选(CS#)必须在字节边界处精确变高(地址字节的最低有效位已锁存);否则,该指令将被拒绝且不执行。

块表
发出BE指令的顺序为:片选(CS#)变低-发送BE指令代码-串行输入(SI)上的3字节地址-片选(CS#)变高。
该指令可接受SPI(8个时钟)和QPI(2个时钟)命令周期。在SPI模式下,串行输入输出[3:1](SIO[3:1])的值无关紧要。

自定时块擦除周期时间(tBE)在片选(CS#)变高时启动。在块擦除周期进行过程中,仍可检查写操作进行(WIP)位。在tBE计时期间,WIP位置位;当块擦除周期完成时,WIP位清零,且写使能锁存(WEL)位复位。如果该块受BP位(WPSEL=0;块锁定(BP)保护模式)或SPB/DPB(WPSEL=1;单独扇区保护模式)保护,则块擦除(BE)指令将不会在该块上执行。
状态机状态跳转流程如下:系统上电后,状态机状态变量state一直处于初始状态(IDLE);当传入的块擦除触发信号key有效时,表示实验工程开始执行对Flash芯片的块擦除操作,状态机跳转到写使能状态(WR_EN),同时片选信号拉低,选中要进行块擦除操作的Flash芯片;状态跳转到写使能状态且片 选信号拉低后,要进行tSLCH≥5ns的等待时间,等待时间过后对主输出从输入信号写入写使能指令,指令写入完成后需要进行tCHSH≥5ns的等待时间,等待时间过后拉高片选信号,取消对Flash芯片的选择,同时状态机跳转到两指令间等待状态(DELAY);在此状态等待时间tSHSL≥ 100ns后,状态机跳转到扇区擦除状态(SE),同时片选信号拉低,选中已写入写使能指令的Flash芯片;状态机跳转到扇区擦除状态且片选信号拉低后,要进行tSLCH≥5ns的等待时间,等待时间过后对主输出从输入信号写入块擦除指令和3字节的块擦除地址,地址写入完成后需要进行tCHSH≥5ns的等待时间,等待时间过后拉高片选信号,取消对Flash芯片的选择,同时状态机跳回初始状态(IDLE),一次完整的扇区擦除操作完成。
后续有关代码和读写数据在下章分享;