FPGA:spi_flash读写测试

SIP_FLASH逻辑设计
  1. 需求
SPI读写flash,最大4mbit,实现给定地址,长度可完成存储数据读取。
本设计包含指令:RSR-1、PP、SE、BE、READ。
用户接口:

Port name

Direction

Type

Description

clk_sys

INPUT

WIRE

输入系统时钟

rst_sys

INPUT

WIRE

输入系统复位

rd_en

INPUT

WIRE

flash读使能

wr_en

INPUT

WIRE

flash写使能

chip_es_en

INPUT

WIRE

flash片清除信号

rd_sr

INPUT

WIRE

读flash状态寄存器

sr_data

OUTPUT

WIRE

读寄存器输出值

data_i

INPUT

[31:0]

写FIFO,32位数据信号

data_vld_i

INPUT

WIRE

写FIFO,数据有效信号

wr_almostfull_o

OUTPUT

WIRE

写FIFO,fifo满信号

wr_datacnt_o

OUTPUT

WIRE

写FIFO,计数

data_o

OUTPUT

REG

读FIFO,数据输出

data_o_en

INPUT

WIRE

读FIFO,数据使能信号

rd_empty_o

OUTPUT

WIRE

读FIFO,高有效表示FIFO内数据为空。

rd_almostfull_o

OUTPUT

WIRE

读FIFO,almost_full信号,当信号为1,表示FIFO内存仅剩50个数存储量。

rd_datacnt_o

OUTPUT

WIRE

FIFO内存数据计数。

length_i

INPUT

[15:0]

写数据总长度,16位宽最大为2mbit。

address_i

INPUT

[23:0]

写数据初始地址

addr_vld

INPUT

WIRE

数据地址和数据长度有效信号

 
物理层接口:

Port name

Direction

Type

Description

si_io

input

wire

SPI输入数据线,MOSI

so_io

output

 reg

SPI输出数据线,MOSO

cs_io

output

reg

片选信号,低有效

用户接口时序:
1)       读使能与写使能以及片擦除使能均有效两个时钟周期,下图仅展示读使能。
 
2)       写入数据时序如下图所示:
 
 
3)       当full_o信号为1时,暂停数据写入,等待full_o信号置0后,继续写入数据。
 
 
4)       读数据时序如下图:
 
 
5)              读数据时,empty为0时数据有效。如下如:
 
 
6)       数据长度、起始地址信号时序如下:
 
 
 
状态机:
 
 
Figure 1 SPI_FLASH 状态机
 
总结:
1)       尝试配置 FLASH 管脚时,会发现 CCLK 管脚是不可配置的,这实际上是因为 CCLK_0 管脚在内部已经被占用,我们必须通过其他方式获取/设置,这里使用原语控制CCLK_0。读SR1寄存器,在读写操作前后均需要发出都寄存器指令检测FLASH是否能够继续下一步操作,主要检测WEL和WIP位。
2)       SO_IO并不是一定随着时序在发送结束后立即置高。是否为一不影响后续指令操作,一切看状态寄存器。
3)       PP操作时,若给定地址不是页头地址,当数据写数据超过当前页区域时,后续数据将从当前页区域首地址继续写数据。而读书则自动做地址偏移。
  1. Flash命令和SPI协议时序
1.1.  Flash指令
 
写使能(WREN)需要在PP、SE、BE、操作前将wel写使能处于锁存状态。
.
1.2.  SPI时序
1.2.1.     READ(Read Data Bytes)
作用:读取数据;
时序图(SPI mode):
 
1.2.2.     SE(Sector Erase)
作用:将扇区所有数据擦除即全“1”;在发送SE之前需要发送WREN将WEL位设置;
时序图(SPI mode):
 
1.2.3.     CE(Chip Erase)
作用:将FLASH上所有数据擦除即全“1”;在发送之前需要发送WREN将WEL位设置;
时序图(SPI mode):
 
1.2.4.     PP(Page Program)
作用:对内存写0;在发送之前需要发送WREN将WEL位设置;若发送的数据超过256Bytes,它会将最后256Bytes发送到FLASH;若发送的数据不超过256Bytes,数据将发送到请求的地址;
时序图(SPI mode):
  1. 仿真以及时序对齐:
      Spi读FIFO数据,初始设计时序逻辑的spi_clk下降沿触发32位宽的fifo_dout左移一位,由于spi写数据时为连续写入,导致从fifo中读出数据时无法及时触发读rd_en使能,所以写入数据始终为初始数据;
      修改为组合逻辑,设置spi_clk 的上升沿信号(spi_pos)和下降沿信号(spi_neg),组合逻辑中触发32位宽数据fifo_dout的移位以及从FIFO中读数据。
跨时钟域处理:对于clk_sys时钟域的读写指令信号,通过打三拍的方式在spi_clk慢时钟域抓取。
 
仿真:
写数据仿真;
 
读数据仿真;
 
 
FLASH时钟原语配置:
STARTUPE2 #(
       .PROG_USR              ("FALSE"),
       .SIM_CCLK_FREQ  (0.0)
)
STARTUPE2_inst(
       .CFGCLK                   (cfgclk),
       .CFGMCLK        (cfgmclk),
       .EOS                    (eos),
       .PREQ                 (),
       .CLK                   (0),
       .GSR                   (0),
       .GTS                    (0),
       .KEYCLEARB           (1),
       .PACK                 (1),
       .USRCCLKO             (usrcclk),
       .USRCCLKTS           (0),
       .USRDONEO             (1),
    .USRDONETS          (0)
);
CFGCLK,配置逻辑主时钟,仅在配置时有输出,在 master 模式下也一直存在(存疑;根据后面的测试,文档所说的 Persist Enabled 应当指的是 Master 模式下一直使能/连接,但除了配置的时候存在时钟,其他时候为无效的高电平;在配置了 USRCCLK 时,在 FPGA 配置结束后三个 clk 该时钟将切换到 USRCCLK)。Configuration mode 是根据 M[2:0] 管脚配置的,最常用的是 M[2:0]=001 对应的 Master SPI 配置模式,笔者开发板即本模式,Master 模式下 CCLK 由 FPGA 输出给 FLASH 的 SCK;
 
EOS,End Of Start,指示 FPGA 配置的结束;
 
CFGMCLK,配置内部振荡器时钟,是从内部的一个锁相环输出的 65MHz 时钟(不是很准,笔者输出到 GPIO 用示波器看过,那块板子的 ~68MHz);
 
USRDONEO,输出到FPGA 的 DONE_0 管脚。一般而言,在硬件设计中会在这个管脚挂一个 LED 灯,以指示 FPGA 完成配置开始运行;
 
USRDONETS,控制 DONE 管脚的三态门,1 将设置为高阻,0 将会把用户给入的 USRDONEO 输出到 DONE_0 管脚;
 
USRCCLKO,在配置完成后,驱动 CCLK_0 管脚的用户自定义时钟。在配置完成后,前三个时钟周期用于切换时钟源,且不会被输出,但如果使用了 EMCCLK 管脚,则 EMCCLK 信号会出现在 CCLK 管脚上,直到过渡到用户自定义时钟;
 
USRCCLKTS,控制 USRCCLKO 的三态门;
 
GTS,全局三态门使能,要用户自定义 CCLK/DONE 等,此管脚必须置低。
 
posted @ 2024-01-15 17:26  Arkam  阅读(93)  评论(0编辑  收藏  举报