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  IOFPGA 的配置 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开发板如下,其他开发板可以修改管脚适配:AX301开发板.png


设计文档:

spi flash(M25P16芯片)实验.docx

SPI Flash 实验

FPGA设计



1 实验简介

由于 FPGA 是基 SRAM 结构的,程序掉电后会失,所以需要一个外置 Flash 保存程序,

FPGA 每次上电后去读取 Flash 中的配置程序,在 ALINX 开发板中,很多使用的是 SPI 接口的 nor

flash,这种 flash 只需要 根 IOFPGA 的配置 flash 是特殊的 IO,上电时工作,FPGA 要使用这些

IO 来读取 Flash,读取成后释放这些 IO 交给用户使用。


本实验做一个 SPI 主设备控制器,然后按照 spi Flash 数据手册的命令要求发出擦除、编程、

读取等指令,每次上电后将 flash 中第一个字节读取并显示出来,按键按下时,数字加 再写回

flash


主要学习 spi 接口、spi flash 操作等,由于篇幅有限,本文不详细介绍 SPI 协议和 spi flash 

操作时序,但这些知识是本实验基础。


2 实验原理


2.1 件介绍


如图所示,AX301AX4010 开发板上有一个 SPI Flash,通常是做为 FPGA 的程序配置 Flash

但是也可以做为用户 Flash 使用,我们可以把自己的少量数据保存在 Flash 中。


















FPGA 版权所有 12


hdlcode.com


















AX301AX4010 开发板 SPI flash


2.2 Flash 时序和命令


一个器件进行操作前,我们首先要了解 Flash 的各种特性,特别是和我们操作相关的特性,

大部分芯片厂商会提供片的数据手册,这些芯手册一般可以通过芯片商网站获取,有些厂

商需要签订保密协议才提供数据手册。所以获芯片数据手册也是非常要的学习内容,首先

通过搜索引擎搜索,在有搜索结果时可到芯片商官网找找,很多芯片据手册下载是需要注

册登录,然后再下载。意:在进行试验前请先读配套资料芯手册文夹下的FLASH

datasheet,搞清楚flash 命令,地址和数据之间的时序关系。



2.2.1 SPI 模式


SPI 可以通过 CPOLCPHA 来配置模式,这对于刚接触 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设计 12


hdlcode.com 

















种 SPI 模式数据波形


2.2.2 Flash 的主要操作


页编程(Page programming


编程指令就是讲 Flash 的数据位由 1 变成 0,只能由 1 变成 0,如果要从 0 变成 1,只能使用 擦除操作要编程一个数据字节,需要两个指令:写使能(WREN),这是一个字节和一个页编

程(pp)指令,它由四字节加上数据组成。为了提高性能,页编程(PP)指令最多允许 256 字节, 当然这些数据都必须在页内,不能跨连续读取。从页编程指令时序图以看出,SPI 需要先发 送一个字节的指令,再发出 3 字节的地址,然后再发出数据,最 256 个数据。将数据写入后 检查状态寄存器 WIP 位(状态寄存器最低位)的值,若为 表示处于数据写入周期,若为 表示 写入周期完成,可以进行下一步操作。























FPGA设计 12


hdlcode.com



























页编程指令时序


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















写使能令时序


块擦除指令(Bulk Erase


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



FPGA设计 12


hdlcode.com














块擦除指令时序


扇区擦除指令(Sector Erase


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














扇区擦写指令


读数据指令(Read Data Bytes


读 flash 是非常常见的操作,首先拉低片选信号,然后发出读指令,个字节的读地址,然后 就可以持续读出数据,地址自动累加。器件处于擦除或数据写入周期时,数据读取指令无效并且 对当前周期无任何影响














FPGA设计 12


hdlcode.com

















读数据指令


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


























flash 指令列表


3 程序设计

spi flash 读写相对比较复杂,本实验将 flash 操作分解为 层,最底层为 SPI 驱动层,每次写

一个字节返回一个字节然后是 flash 指令层,flash 指令层通过 spi 主控制器读写数据,完成最基

本的 flash 种指令,然后是 flash 除、编程、读写层,为其他模块提供可直接操作 flash 的接口。



FPGA设计 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设计 12


hdlcode.com


在‘spi_flash_top’模块中例化‘spi_master’模块时已经设定‘clk_div’的值为 0,目的是将 模拟的 spi 时钟‘DCLK_reg’进行 分频,也就是当‘clk_div=0’整个模块运行时,从状态‘IDLE’ 跑到状态DCLE_EDGE需要 个‘sys_clk’周期。至于其他不能够理解地方请

大家详细了解 spi 总线时序和 flash 读写时序后再来看或许会有更深的认识。当然,最直观的方法还是仿真


信号名称

方向

说明

sys_clk

in

时钟输入

rst

in

异步复位输入,高复位

nCS

out

spi 片选信号,等于 nCS_ctrl

DCLK

out

spi 串行时钟

MOSI

out

spi 串行数据输出

MISO

in

spi 串行数据输入

CPOL

in

Clock Polarityspi 时钟的极性

0:空闲状态为 0

1:空闲状态为 1

CPHA

in

Clock Phasespi 时钟的相位,

0:第一个沿采样,

1:第二个沿采样

nCS_ctrl

in

nCS 控制

clk_div

in

spi 时钟频率控制

spi 时钟=系统时钟/(2*2+ clk_div)

clk_div 最小值可以为 0,当为 0 时,spi 时钟是系统 时钟的 1/4

wr_req

in

写一个字节请求

wr_ack

out

写应答,高有效

data_in

in

数据

data_out

out

返回的数据,当写应答有效

spi master 端口说明

FPGA设计 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’传送数据时,是舍弃了 个字节的地址位,只传送数据位。而在产生‘data_req’信号时‘byte_cnt’却是到 2,为了满 足数据写入的时序要求这里提前了一个时钟周期


















spi_flash_cmd 状态机


信号名称

方向

说明

sys_clk

in

时钟输入

rst

in

异步复位输入,高复位

cmd

in

命令编码

cmd_valid

in

命令有效

cmd_ack

out

命令应答

addr

in

flash 地址

data_in

in

命令有写操作时的数据

size

in

命令+数据长度(字节)

data_req

out

命令有写操作时请求数据,其他 data_in 一个时钟周 

data_out

out

命令有读操作时读出的数据


FPGA设计 12


hdlcode.com


data_valid

out

命令有读操作时读有效

CS_reg

out

 spi master 接口,spi 片选控制

wr_req

out

 spi master 接口,spi 写请求

wr_ack

in

 spi master 接口,spi 写应答

send_data

out

 spi master 接口,spi 写数据

data_recv

in

 spi master 接口,spi 读数据

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 状态机


信号名称

方向

说明

sys_clk

in

时钟输入

rst

in

异步复位输入,高复位

flash_read

in

flash 读请求


FPGA设计 10 12


hdlcode.com


flash_write

in

flash 写请求

flash_bulk_erase

in

块擦除请求

flash_sector_erase

in

扇区擦除请求

flash_read_ack

out

读应答

flash_write_ack

out

写应答

flash_bulk_erase_ack

out

块擦除应答

flash_sector_erase_ack

out

扇区擦除应答

flash_read_addr

in

读请求地址

flash_write_addr

in

写请求地址

flash_sector_addr

in

扇区擦除地址

flash_write_data_in

in

写请求数据

flash_read_size

in

读字节大小

flash_write_size

in

写字节大小

flash_write_data_req

out

写数据拉取,提前 flash_write_data_in 一个时钟

flash_read_data_out

out

读数据

flash_read_data_valid

out

读数据有效

cmd

out

连接 spi_flash_cmd 模块,命令编码

cmd_valid

out

连接 spi_flash_cmd 模块,命令有效

cmd_ack

in

连接 spi_flash_cmd 模块,命令应答

addr

out

连接 spi_flash_cmd 模块,flash 地址

data_in

out

连接 spi_flash_cmd 模块,命令有写操作时的数据

size

out

连接 spi_flash_cmd 模块,命令+数据长度(字节)

data_req

in

连接 spi_flash_cmd 模块,命令有写操作时请求数 据,其他 data_in 一个时钟周期

data_out

in

连接 spi_flash_cmd 模块,命令有读操作时读出的数 

data_valid

in

连接 spi_flash_cmd 模块,命令有读操作时读有效

spi_flash_ctrl 端口

在这个模块状态机的‘S_CK_STATE’状态,进行状态转移的条件不仅有命令应答信号还需

要判断‘state_reg’寄存器的最低位,需要知道的是‘state_reg’的最低位就是 WIP 位,显示 SPI

是否在写入状态,为 时表示该状态不忙。同时,在 spi_flash_ctrl 模块中,我们调用了一个宏定


FPGA设计 11 12


hdlcode.com


义模块,和 语言里的宏定义类似,宏定义模块里面定义了对 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

代码文件(付费下载):



1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » spi flash(M25P16芯片)实验设计Verilog代码Quartus AX301开发板

发表评论

模板文件不存在: ./template/plugins/comment/pc/index.htm

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员