FPGA读写Flash模块 Verilog程序设计
采用黑金Spartan6的开发板,板内的硬件电路设计如图
电路严格按照datasheet的规定连接。
按照上图 控制FLASH芯片仅需要控制QSPI_MIS0、QSPI_MIS1、QSPI_MIS2、QSPI_MIS3以及QSPI_CS、QSPI_CLK
按照程序实现的功能需要
1. 读Manufacturer / Device ID (90h):先发送命令字90(1001 0000),再发送24位的地址(全0),然后接收2个byte的数据(第一个数据是Manufacturor:FEh,第二个是设备的Device ID:17h)。数据在时钟的上升沿采样。
2.写使能(06):发送命令字06(0000 0110),数据都在时钟的上升沿采样。
3.写不使能(04):发送命令字04(0000 0100),数据都在时钟的上升沿采样。
4.Sector擦除(20):先发送命令字20(0010 0000),再发送24位的地址。数据都在时钟的上升沿采样。
5.读状态寄存器1 (05):先发送命令字05(0000 0101),然后接收16位的寄存器数据。数据都在时钟的上升沿采样。
6. Page编程(02):先发送命令字02(0000 0010),再发送24位的地址,然后写入256个编程的数据(数据的数量可以自己修改, 但不能超过256个)。数据都在时钟的上升沿采样。
7. 数据读(03):先发送命令字03(0000 0011),再发送24位的地址,然后接收数据。数据在时钟的上升沿采样。
根据时序图只需要用到IO0、IO1发送命令,命令都是8个二进制数,需要8个clk。
顶层的电路设计图FLASH_TEST
flash_test内部采用flash_spi模块实现数据的传输
flash_spi使用状态机控制逻辑。cmd_type[3:0]为自定义编码,用于区分不同的操作。
接收flash的数据的程序,接收read_num个数的byte数据。
需要设计的控制标志有:
开始读写标志 datacome
bit的计数标志 cntb
byte计数标志 read_cnt
数据输出有效标志 myvaild
结束标志 read_finish
*****通过移位操作接收数据*****
mydata <= {mydata[6:0],flash_out};
完成上述后,我们就完成了flash的控制器,下面用小例子来使用我们的控制器。
通过简易的状态机完成状态的跳转,下面的操作完全按照协议即可。
i=0:读FLASH的Device ID;
4'd0 :
if( Done_Sig ) begin
flash_cmd <= 8'h00;
i <= i + 1'b1; cmd_type <= 4'b0000;
end else begin flash_cmd <= 8'h90;
flash_addr <= 24'd0;
cmd_type <= 4'b1000;
end
i=1:发送FLASH写使能命令;
4'd1:
if( Done_Sig ) begin
flash_cmd <= 8'h00;
i <= i + 1'b1;
cmd_type <= 4'b0000;
end
else begin
flash_cmd <= 8'h06;
cmd_type <= 4'b1001;
end
其余同理。
i=2:发送Sector擦除命令,擦除从地址0开始的4KB的数据;
i=3:等待100个clock;
i=4:读状态寄存器的数据,等待Busy标志位为0;
i=5:发送FLASH写不使能命令;
i=6:读状态寄存器的数据,等待Busy标志位为0;
i=7:发送FLASH写使能命令;
i=8:等待100个clock;
i=9:发送FLASH编程命令,从地址0开始写入256个数据(0~255);
i=10:等待100个clock;
i=11:读状态寄存器的数据,等待Busy标志位为0;
i=12:发送FLASH写不使能命令;
i=13:读状态寄存器的数据,等待Busy标志位为0;
i=14:发送FLASH读命令,读取256个数据;
i=15:结束;
flash_cmd 传输控制字
flash_addr 24位传输地址
cmd_type为自定义编码的操作代码
之后根据协议控制flash进行相应的读写操作