小言_互联网的博客

FPGA纯verilog代码读写N25Q128A QSPI Flash 提供工程源码和技术支持

475人阅读  评论(0)

1、N25Q128A芯片解读

N25Q128A的参数有很多,作为FPGA开发者,需要关注如下参数:

1、4KBytes为1个Sector(扇区);
2、16个Sector(扇区)是1个Block(块)64KBytes;
3、容量为16M=128Mbite字节,共有256个Block,4096个Sector;

这三个参数直接决定了你怎么组织数据的读写操作,比如你的数据量很小,则考虑写入1个Sector(扇区),如果你的数据量很大,则考虑写多个Sector(扇区);
N25Q128A按照读写速度分为标准、Quad/Dual三种,这里只介绍标准版,学fpga就是这样,先把最基础的搞懂再去研究高级的,一步步扎实点兄弟。。。

标准模式下只需用到4个引脚:
时钟QSPI_CLK:25M即可,对于Flash来说,上升沿采集数据,下降沿输出数据;对于FPGA来说,则是下降沿输出数据,上升沿采集数据。。。我看到csdn上有人给出的代码居然直接有always @( negedge QSPI_CLK) 这样的写法,真是为这样的大佬感到震惊,感觉在校本科生也知道这样写不好吧。。。
片选信号QSPI_CS:低电平有效;
数据输出信号:QSPI_DQ1;
数据输入信号:QSPI_DQ0;
硬件原理图部分如下:

N25Q128A在本设计中需要用到的指令如下:

parameter CMD_NULL               =   8'h00  ;	//空操作
parameter CMD_RD_DEVICE_ID       =   8'h9F  ;	//读ID
parameter CMD_WR_DISABLE         =   8'h04  ;	//写禁止
parameter CMD_WR_ENABLE          =   8'h06  ;	//写使能
parameter CMD_PAGE_PROGRAM       =   8'h02  ;	//页编程
parameter CMD_RD_DATA            =   8'h03  ;	//读数据
parameter CMD_SECTOR_ERASE       =   8'h20  ;	//扇区擦除
parameter CMD_RD_STATUS_REGISTER =   8'h05  ;	//读状态寄存器

状态寄存器描述如下:

在写入指令或地址之前,需要读bit0为,确保其值为0才可操作;
其他的去看数据手册吧,太多了也写不完;

2、N25Q128A读写时序

N25Q128A读写本质上都一样,发送指令或发送指令加地址,则完成了读写操作;具体的对应关系如下,仅限本设计用到的:

/*                name                      instruction  cmd  addr  rd  wr  
读芯片信息        CMD_RD_DEVICE_ID           9F          √          √   
写禁止/写使能     CMD_WR_DISABLE/WR_ENABLE   04/06       √              
页编程(写数据)  CMD_PAGE_PROGRAM           02          √     √        √
读数据            CMD_RD_DATA                03          √     √    √   
扇区擦除          CMD_SECTOR_ERASE           20          √     √        
读状态寄存器      CMD_RD_STATUS_REGISTER     05          √          √            
空指令            CMD_NULL                   00          
*/

3、整体设计思路架构

整体设计思路架构如下:

1、VIO模拟按键:
启动一次QSPI读写操作,高电平有效;
2、QSPI读写驱动:
verilog代码实现,根据输入的指令和地址输出/输入QSPI数据;
3、QSPI读写操作:
读ID–>块擦除–>写入256个字节数据到Sector0–>读出256个字节数据–>缓存FIFO;
4、缓存FIFO:
缓存读出的256个字节数据,等待串口读取;
5、串口发送:
读取缓存FIFO数据,发送上位机显示;

4、verilog读写Flash驱动设计

使用三段式状态机实现;根据输入的指令或地址完成对应读写操作;
代码比较长,这里就不粘贴了,需要源码的兄弟可联系我;
顶层接口部分如下:

module helai_flash_driver #(
	parameter SYS_CLK_M = 200,	//系统时钟
	parameter SPI_CLK_M = 25	//QSPI时钟
)(
	input             clk            ,
	input             rst_n          ,
	input             i_flash_start  ,	//启动驱动,高电平有效
	input      [ 7:0] i_flash_cmd    ,	//输入指令
	input      [23:0] i_flash_addr   ,	//输入地址
	input             i_flash_dqout  ,	//N25Q128A输出
	output reg        o_flash_dqin   ,	//N25Q128A输入
	output            o_flash_csn    ,	//N25Q128A片选
	output reg        o_flash_cmd_ok ,	//单次读写操作完成
	output reg [ 7:0] o_flash_rx_data,	//输出数据
	output reg        o_flash_rx_de   	//输出数据有效,高有效        
);

 

5、verilog读写Flash控制器设计

使用三段式状态机实现;状态机步骤如下:

//第一步:读ID,发送CMD_RD_DEVICE_ID指令
//第二步:读ID完成,进入写禁止,发送CMD_WR_DISABLE指令
//第三步:进入写使能,发送CMD_WR_ENABLE指令
//第四步:进入页擦除,发送CMD_SECTOR_ERASE指令
//第五步:进入读状态寄存器,发送CMD_RD_STATUS_REGISTER指令
//第六步:进入写使能,发送CMD_WR_ENABLE指令
//第七步:进入页写,发送CMD_PAGE_PROGRAM指令
//第八步:进入读状态寄存器,发送CMD_RD_STATUS_REGISTER指令
//第九步:进入读状数据,发送CMD_RD_DATA指令

代码比较长,这里就不粘贴了,需要源码的兄弟可联系我;

6、FIFO缓存设计

fifo缓存读出的256字节数据,等待串口读取,很简单,不多说;

7、串口输出Flash读取数据

波特率自由配置,很简单,不多说;给出顶层接口如下:

module uart_transfer #(
	parameter SYS_CLK_M = 200,
	parameter UART_CLK  = 115200
)(
	input         clk         ,
	input         rst_n       ,
	input  [ 7:0] txd_data    ,
	input         txd_data_vld,
	output        txd_data_rdy, 
	output reg    txd_uart   
);

8、vivado工程介绍

开发板:Xilinx Artix7开发板;
开发环境:vivado2019.1;
输入:VIO;
输出:串口;

9、上板调试验证并演示

视频演示:

FPGA纯verilog代码读写N25Q128A QSPI

10、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:获取方式:私,或者看下面的名片。
网盘资料如下:


转载:https://blog.csdn.net/qq_41667729/article/details/128942960
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场