需求分析

用Nexys4 DDR 制作一台计算机[1] 硬件里提过,需要一个“硬盘”,用于读取只读数据。
在这里实现一个一次读取4Bytes的flash控制器。

原理分析

nexys4ddr 使用的spi flash芯片具体型号是S25FL128S芯片。
线路图如下
pic 1

什么是spi协议

简单起见,仅介绍最基础的,详细的请参考wiki
spi协议是一种串行总线,即数据用一根线一位一位的传,这里需要用的的有sck,cs_n,si,so四根信号线
sck是时钟线,用来做信号的同步,频率在工作范围内随意
cs_n是片选信号,"_n" 的意思是低电平有效,故当cs_n信号被拉低的时候,这个芯片才开始工作
si是输入到主设备的信号线,flash芯片读取数据的时候需要靠它
so是输入到flash的信号线,flash芯片写入数据的时候需要靠它

什么是flash芯片

简单来说,它是一种有一堆可读可写的颗粒(EEPROM)和一个控制器组成的,这个控制器封装了许多指令来操作那些颗粒。于是要想使用flash芯片,最主要的是对flash控制器发出正确的指令。
flash 芯片的结构如下图
pic 2
关于flash芯片的指令,每个厂商有些许不同,但由于有标准化,大多常用的指令都相同,可以参考每种芯片的文档。
S25FL128S芯片的文档

时序

flash芯片时序

由于仅仅需要读取数据,我们这里仅介绍用到的唯一一条指令:READ
根据S25FL128S的文档,我们可以看到读取指令的时序为
pic 3
从图上看,我们要想读取数据,需要做的是
1.先将cs_n拉低,
2.再保持sck在工作范围内,查阅文档可知,READ指令最大工作频率是50MHz,故sck可选的频率在(0,50M]之间,由于Nexys4 DDR的板载晶振频率是100MHz,于是这里用50MHz会比较好分频,
pic 4
3.然后通过so信号线一位一位的输入指令READ(03H),读取地址(24位),
4.最后flash芯片就会通过si信号线一位一位的输出数据

wishbone总线读时序

作为一个外设需要连接到总线上,接口需要满足总线的要求。
这台计算机用的是Wishbone总线,它的时序比较简单,这里介绍下总线读操作的信号
pic 5
简单来说工作的时候需要把STB_O和CYC_O同时拉高,地址输入到ADR_O中,再保持CLK_I的周期,之后总线就开始等待外设,当外设处理完成信号之后,就将ACK_I拉高,完成整个传输过程。
主机在接受完数据后将STB_O与CYC_O同时拉低,外设此时便知道整个访问结束,将ACK_I拉低。

设计

状态机设计

这部分主要参考了这篇文章
如图所示
pic 6