Menu Close

SPI 通讯协议(6)SPI FLASH (verilog) 工程解析 (spi_IF.v)

spi_IF.v 模块为上层的系统模块, 这个模块 主要是接收系统的命令, 同时向下面的模块(spi_cmd.v) 发送spi 的指令。 这个模块的主要时钟是sys_clk ,通过fifo 和 异步握手方式和spi_cmd.v 模块通讯。 通过接收上层模块的指令,得到相应的操作命令。

参考文章:

SPI 通讯协议 及 SPI 相关工程 详解

spi_IF.v 结构图

spi_IF.v 模块主要是从上层模块 接收 几个按键的信息:在当前的例子中会接收:

1)spi flash DEV-ID ,

2)向 spi flash 中的 0x80_0000 地址 写入 128 bytes 的数据 , 数据为 0x00 – 0x7f

3)向 spi flash 中的 0x80_0000 地址 读取 128 bytes 的数据。

4)擦除 地址为 0x80_0000 的扇区

 

除此之外, spi_IF.v 的状态机 还可以接收 上层模块传递下来的 uart 信息,在uart 模块中, 可以产生各种不同的spi 命令(不但可以控制spi flash, 也可以用来控制其他的spi 设备)。

代码介绍:


 

接口介绍

 


与spi_cmd.v 交互的异步握手逻辑




状态机逻辑:

状态机0:初始化所有变量状态,等待上电时所有fifo 复位结束, 跳转状态1

状态机1:空闲状态,等待上层模块的相关spi 操作,如果:

按键读取spi flash ID命令, 跳转状态2

按键写数据命令, 跳转状态5

按键擦除命令, 跳转状态5

按键读数据, 跳转状态22

uart 接收到spi 命令, 跳转状态26

// 读取spi flash ID

状态机2:发送spi flash ID 读命令,向spi_fifo_wr 中写入 (18’h0_009f)跳转状态3

状态机3:发送spi flash 读长度3,结束命令,向spi_fifo_wr 中写入 (18’h2_0003)跳转状态4

状态机4:等待下层模块发送结束, 跳转状态31

// 设置spi flash  06 寄存器 (打开写操作)

状态机5:写spi flash 06 寄存器,write enable 寄存器打开, 允许对spi flash  进行写(编程),擦除等操作, 跳转状态6

状态机6:没有需要从spif flash 读的数据,结束标志,跳转状态7

状态机7:f当前的操作(transaction) 结束后,如果是写(编程)操作, 跳转8; 如果是擦除操作,跳转18

// 写(编程) 操作

状态机8:写(编程)操作, 02 命令字,跳转9

状态机9:连续写3次spi flash 地址, 跳转 10

状态机10:写 0x00 数据到spi flash 中 ,跳转11

状态机11:写0x01 – 0x7f 数据到 spi flash 中, 跳转12

状态机12:没有数据需要读取, 发送结束标志。 跳转13

状态机13:等待当前的操作(transaction) 结束,即 spi_phy.v 完全将数据发送到spi 设备时,跳转14

// 读spi flash  05 寄存器 (读取flash 的状态寄存器内容)

状态机14:读spi flash 05 (状态寄存器)操作(transaction), 先等待128个clock (没有必要快速读取05 寄存器, spi flash 需要一定的反映时间,然后spi flash 设备才能更新05 状态寄存器),跳转15

状态机15:发送结束标志,从spi flash 中准备读取 1 byte数据, 跳转16

状态机16:等待操作(transaction)结束,跳转17

状态机17:检查05 状态寄存器的数据,如果 bit[0] == 1,编程或者擦除等命令还没有结束,重新检查05寄存器, 跳转14; 如果 bit[0] == 0, 跳转31。

// 擦除操作

状态机18:发送擦除命令,跳转19

状态机19:连续发送3bytes 的地址到spi flash, 跳转20

状态机20:发送结束标志,没有数据需要从spi flash 中读取。 跳转21

状态机21:等待操作(transaction) 结束,跳转14。 (检查05 状态寄存器)

// 读spi flash 操作

状态机22:发送读spi flash 命令, 跳转23

状态机23:连续发送3bytes 的地址数据到spi flash,跳转24

状态机24:发送结束标志,并且需要读取128 bytes的数据,跳转25

状态机25:等待当前的操作(transaction)结束,跳转31

// 从uart 端 接收的相关spi 操作(可能是任何一种spi 操作)

状态机26:如果uart 接收fifo 不是为空,从uart fifo 中读取一个数据,跳转27

状态机27:读信号结束,跳转28

状态机28:如果uart fifo 为空,表示当前从fifo 里读取的最后一个数据为结束标志,发送这个数据(包括读取spi flash 的长度),跳转29。如果uart fifo 不为空,继续读取uart fifo 中的数据,跳转27

状态机29:等待当前操作结束(transaction),跳转31

// 结束当前操作

状态机31:通知上层模块,当前的操作(transaction)结束,跳转1

总结

到此,所有关于spi 的操作,介绍完毕。 上层的应用(按键发送相关的命令,  或者 uart 发送相关的spi 命令)只需要发送命令即可,上层模块不再关心具体的spi 操作细节。

Posted in FPGA, FPGA 教材教案, IP开发, RISC-V IPcore设计, RISC-V 教材教案, RISC-V架构, 教材与教案, 文章, 集成电路