spi flash(M25P16芯片)实验设计Verilog代码Quartus AX301开发板
名称:spi flash(M25P16芯片)实验设计Verilog代码Quartus AX301开发板
软件:Quartus
语言:Verilog
代码功能:
由于 FPGA 是基于 SRAM 结构的,程序掉电后会丢失,所以需要一个外置 Flash 保存程序,
FPGA 每次上电后去读取 Flash 中的配置程序,在 ALINX 开发板中,很多使用的是 SPI 接口的 nor
flash,这种 flash 只需要 4 根 IO。FPGA 的配置 flash 是特殊的 IO,上电时工作,FPGA 要使用这些
IO 来读取 Flash,读取完成后释放这些 IO 交给用户使用。
本实验做一个 SPI 主设备控制器,然后按照 spi Flash 数据手册的命令要求发出擦除、编程、
读取等指令,每次上电后将 flash 中第一个字节读取并显示出来,按键按下时,数字加 1 再写回
flash。
主要学习 spi 接口、spi flash 操作等,由于篇幅有限,本文不详细介绍 SPI 协议和 spi flash 的
操作时序
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
本代码已在AX301开发板验证,AX301开发板如下,其他开发板可以修改管脚适配:
设计文档:
SPI Flash 实验
FPGA设计
1 实验简介
由于 FPGA 是基于 SRAM 结构的,程序掉电后会丢失,所以需要一个外置 Flash 保存程序,
FPGA 每次上电后去读取 Flash 中的配置程序,在 ALINX 开发板中,很多使用的是 SPI 接口的 nor
flash,这种 flash 只需要 4 根 IO。FPGA 的配置 flash 是特殊的 IO,上电时工作,FPGA 要使用这些
IO 来读取 Flash,读取完成后释放这些 IO 交给用户使用。
本实验做一个 SPI 主设备控制器,然后按照 spi Flash 数据手册的命令要求发出擦除、编程、
读取等指令,每次上电后将 flash 中第一个字节读取并显示出来,按键按下时,数字加 1 再写回
flash。
主要学习 spi 接口、spi flash 操作等,由于篇幅有限,本文不详细介绍 SPI 协议和 spi flash 的
操作时序,但这些知识都是本实验基础。
2 实验原理
2.1 硬件介绍
如图所示,AX301、AX4010 开发板上有一个 SPI Flash,通常是做为 FPGA 的程序配置 Flash,
但是也可以做为用户 Flash 使用,我们可以把自己的少量数据保存在 Flash 中。
FPGA 版权所有 1 / 12
hdlcode.com

AX301、AX4010 开发板 SPI flash
2.2 Flash 时序和命令
对一个器件进行操作前,我们首先要了解 Flash 的各种特性,特别是和我们操作相关的特性,
大部分芯片厂商会提供芯片的数据手册,这些芯片手册一般可以通过芯片厂商网站获取,有些厂
商需要签订保密协议才能提供数据手册。所以获取芯片数据手册也是非常重要的学习内容,首先
通过搜索引擎搜索,在没有搜索结果时可到芯片厂商官网找找,很多芯片数据手册下载是需要注
册登录,然后再下载。注意:在进行试验前请先阅读配套资料芯片手册文件夹下的FLASH
datasheet,搞清楚flash 命令,地址和数据之间的时序关系。
2.2.1 SPI 模式
SPI 可以通过 CPOL,CPHA 来配置模式,这对于刚接触 SPI 协议比较费劲,暂且不去理会。SPI
Flash 支持 2 种配置模式(These devices can be driven by a microcontroller with its SPI peripheral
running in either of the two following modes):
CPOL=0, CPHA=0
CPOL=1, CPHA=1
这 2 种数据模式,数据输入都是在串行时钟的上升沿锁存数据,在串行时钟的下降沿送出数
据。(For these two modes, input data is latched in on the rising edge of Serial Clock (C), and output
data is available from the falling edge of Serial Clock (C)).
FPGA设计 2 / 12
hdlcode.com 

2 种 SPI 模式数据波形
2.2.2 Flash 的主要操作
页编程(Page programming)
编程指令就是讲 Flash 的数据位由 1 变成 0,只能由 1 变成 0,如果要从 0 变成 1,只能使用 擦除操作。要编程一个数据字节,需要两个指令:写使能(WREN),这是一个字节和一个页编
程(pp)指令,它由四字节加上数据组成。为了提高性能,页编程(PP)指令最多允许 256 字节, 当然这些数据都必须在一页内,不能跨页连续读取。从页编程指令时序图可以看出,SPI 需要先发 送一个字节的指令,再发出 3 个字节的地址,然后再发出数据,最大 256 个数据。将数据写入后 检查状态寄存器 WIP 位(状态寄存器最低位)的值,若为 1 表示处于数据写入周期,若为 0 表示 写入周期完成,可以进行下一步操作。
FPGA设计 3 / 12
hdlcode.com

页编程指令时序
页编程之前需要写使能有效,需要先发送写使能指令,指令时序如下图,写使能只有一个字 节。可以反复发送写使能。

写使能指令时序
块擦除指令(Bulk Erase)
块擦除指令(BE)可以把整个 flash 都变成 1,同样,在块擦除之前需要先发送写使能指令。 Flash 的擦除需要的时间很长,容量不同时间会有差异,一般需要几分钟擦除整片芯片。块擦除指 令发出后,我们通过不断读取状态寄存器(Status Register)来查询擦除是否完成。
FPGA设计 4 / 12
hdlcode.com

块擦除指令时序
扇区擦除指令(Sector Erase)
扇区擦除(SE)指令可以按照扇区擦除 Flash。和块擦除不同的是,扇区擦除是要指定扇区地 址,扇区擦除前也需要发送写使能指令。

扇区擦写指令
读数据指令(Read Data Bytes)
读 flash 是非常常见的操作,首先拉低片选信号,然后发出读指令,3 个字节的读地址,然后 就可以持续读出数据,地址自动累加。器件处于擦除或数据写入周期时,数据读取指令无效并且 对当前周期无任何影响。
FPGA设计 5 / 12
hdlcode.com

读数据指令
flash 的其他指令这里不再介绍,其他指令如下图表格。

flash 指令列表
3 程序设计
spi flash 读写相对比较复杂,本实验将 flash 操作分解为 3 层,最底层为 SPI 驱动层,每次写
一个字节返回一个字节,然后是 flash 指令层,flash 指令层通过 spi 主控制器读写数据,完成最基
本的 flash 各种指令,然后是 flash 擦除、编程、读写层,为其他模块提供可直接操作 flash 的接口。
FPGA设计 6 / 12
hdlcode.com
SPI主设备控制器
(spi master)



![]()
![]()

Flash擦除、编程、 读写控制
(spi flash ctrl )
spi flash 控制器框图
为了检验 flash 掉电不丢失的功能,实验设计了一个状态机,上电一段时间后读取 flash 的第 一个字节,并通过数码管显示出来,如果按键按下,将数字加 1,再写回 flash,这样下次上电会 保持新写入的数据。
spi master 状态机设计,主要完成一个字节 spi 数据的读写,由于是全双工的,写一个字节的 同时也读一个字节。首先空闲状态“IDLE”接收到写请求后进入“DCLK_IDLE”状态,这个状态为 spi 时钟沿变化保持一定的时间,用来控制 spi 时钟的周期,然后进入 spi 时钟沿的变化状态,一 个字节上升沿和下降沿一共 16 个数据沿。在最后一个数据沿进入“LAST_HALF_CYCLE”状态,为 让最后一个沿也保持一定的时间,再进入应答状态,完成一次写请求。

spi master 模块状态图
spi_master 模块中模拟了一个 spi 时钟,在状态机进入到‘DCLK_EDGE’时进行翻转
FPGA设计 7 / 12
hdlcode.com
在‘spi_flash_top’模块中例化‘spi_master’模块时已经设定‘clk_div’的值为 0,目的是将 模拟的 spi 时钟‘DCLK_reg’进行 4 分频,也就是当‘clk_div=0’整个模块运行时,从状态‘IDLE’ 跑到状态‘DCLE_EDGE’需要 4 个‘sys_clk’周期。至于其他不能够理解的地方请
大家详细了解 spi 总线时序和 flash 读写时序后再来看或许会有更深的认识。当然,最直观的方法还是仿真
spi master 端口说明
FPGA设计 8 / 12
hdlcode.com
spi _flash_cmd 模块状态机设计,如下图所示,在收到命令请求以后进入“S_CMD_LATCH”命 令锁存状态,将请求的命令记录下来,然后进入“S_CS_LOW”状态,
拉低 spi 的片选信号,再进
入“S_WR_CMD_CODE”状态,发送一个字节的命令码,如果这个命令只有一个字节,进入
“S_KEEP_CS_LOW”状态,保持一个周期的片选拉低,然后进入“S_CS_HIGH”状态,拉高片选。 如果命令后面还有地址等数据,进入“S_WRITE_BYTES”写数据状态,或进入“S_READ_BYTES” 读。需要注意,在 spi 数据接口‘data_recv’向数据输出接口‘data_out’传送数据时,是舍弃了 3 个字节的地址位,只传送数据位。而在产生‘data_req’信号时‘byte_cnt’却是到 2,为了满 足数据写入的时序要求,这里提前了一个时钟周期

spi_flash_cmd 状态机
FPGA设计 9 / 12
hdlcode.com
spi_flash_cmd 模块端口
spi_flash_ctrl 模块主要完成 flash 擦除、编程、读操作。擦除前需要写使能有效、等待擦除完
成等多项 flash 命令。状态机如下图所示:
“S_IDLE”:空闲状态
“S_WREN”:写使能命令状态
“S_READ”:读状态
“S_WRITE”:写状态(编程)
“S_SE”:扇区擦除
“S_BE”:块擦除
“S_CK_STATE”:状态寄存器检查,用来检测是否擦除完成等。
“S_ACK”:请求应答

spi_flash_ctrl 状态机
FPGA设计 10 / 12
hdlcode.com
spi_flash_ctrl 端口
在这个模块状态机的‘S_CK_STATE’状态,进行状态转移的条件不仅有命令应答信号还需
要判断‘state_reg’寄存器的最低位,需要知道的是‘state_reg’的最低位就是 WIP 位,显示 SPI
是否在写入状态,为 0 时表示该状态不忙。同时,在 spi_flash_ctrl 模块中,我们调用了一个宏定
FPGA设计 11 / 12
hdlcode.com
义模块,和 C 语言里的宏定义类似,宏定义模块里面定义了对 flash 操作的各种命令,其用法和格
式请参照例程。
4 实验现象
将程序下载到开发板以后,数码管显示一个数字,这个数字是 flash 的第一个字节,通过按下
key1 键,数字会加一,同时擦除了 flash,并将新的数据写入,重新上电后,加载下载程序,数码
管将显示最后一次按按键的数字。注意:由于 flash 擦写需求一定的时间,按键不能按的太快。

FPGA设计 12 / 12
部分代码展示:
`define CMD_WREN 8'h06 `define CMD_WRDI 8'h04 `define CMD_RDID 8'hAB //EPCS4 EPCS16 is 0'hab st spi flash is 8'h9f `define CMD_RDSR 8'h05 `define CMD_WRSR 8'h01 `define CMD_READ 8'h03 `define CMD_FAST_READ 8'h0b `define CMD_PP 8'h02 `define CMD_SE 8'hd8 `define CMD_BE 8'hc7
代码文件(付费下载):
![]()
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » spi flash(M25P16芯片)实验设计Verilog代码Quartus AX301开发板
发表评论
模板文件不存在: ./template/plugins/comment/pc/index.htm