Menu Close

SPI 通讯协议(4)SPI FLASH (verilog) 工程解析 (spi_phy.v)

在之前的文章中, 我们介绍了SPI 通讯协议,同时给出了一个简单的spi verilog 工程。 通过简单spi verilog 工程,我们可以对一些外设进行通讯。但简单的SPI 工程也有一些缺点。本文主要针对SPI FLASH 这种外设,搭建一个完整的verilog 工程。同时针简单spi 工程中的一些缺点,做一些补充,使得当前的工程可以完成spi flash 的相关操作。

参考文章:

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

 

在之前的简单spi 工程中, 我们实现了基本的spi 通讯,可以帮助大家迅速建立spi 通讯协议的概念,同时也可以做一些外设的应用。但如果想要操作spi flash 这样的外设, 还是有很多工作需要做的。同时,简单spi 工程 的 phy 时钟的速度会受到系统时钟的限制(速度不会很高)。 本文将制作一个全新的spi flash 工程,系统解决这些相关的问题, 同时增加spi flash 所相关的命令(指令),用于spi flash 的操作。

SPI FLASH 系统框图

 

整个spi flash 工程包括:

顶层模块 (top.v)

         时钟模块 (pll  IP)

         按键模块 (key_filter.v) 

         spi 通讯模块 (spi_IF.v)

                  spi 命令模块(spi_cmd.v)

                            spi phy 模块(spi_phy.v)

         uart 接口模块 (pc_uart.v)

                uart 传输模块 (uart_transceiver.v)

组成的。

这里,我们从最顶层的spi_phy.v 模块开始,一层一层向上介绍。 

 

spi_phy.v  模块

 

spi_phy.v 模块是最底层的spi 通讯接口模块, 它主要是用来完成基本的spi 相关的通讯协议。包括cs , clk, mosi, miso 等。

代码介绍


代码介绍

其中 spi_cs_cmd 是用来控制 SPI CS 信号的。

flash_din 是上层模块发送的数据(准备由spi_phy.v 发送到 mosi 上的),

flash_din_rdy 配合flash_din ,flash_din_rdy 是一个时钟宽度。

flash_data_done 信号 由spi_phy.v 模块产生, 返回给上层模块,用于通知上层模块 ,当前的数据已经发送完毕

 

flash_dout 信号由spi_phy.v 模块产生, 表示从miso 信号线上(其他spi 设备)接收到8bit数据, 准备送给上层模块

flash_dout_vld 信号表示当前的flash_dout 信号有效, 这个信号只有一个时钟宽度。

 

spi_cs       连接到其他SPI设备 的片选信号

spi_clk      连接到其他SPI设备 的时钟信号

spi_mosi  连接到其他SPI设备 的数据发送信号

spi_miso  连接到其他SPI设备 的数据接收信号

 

 

clk_stop 表示时钟停止信号, clk_stop = 1 ,  spi_clk 停止时钟输出; clk_stop = 0, spi_clk 正常输出。当8bit 数据发送完毕后(flash_data_done),clk_stop = 1, 时钟停止输出; 当新数据准备好(flash_din_rdy),clk_stop = 0, 时钟正常输出

接下来的逻辑中xilinx 工程使用的是 ODDR, 这个源语 实现的效果和 assign spi_clk = spi_clk_ce ? ~phy_clk : 0; 是一样的。但在xilinx 6 系列之后的芯片中, xilinx 建议使用ODDR 方式,作为时钟输出,这样可以减少外设对时钟的负载, 这样时钟不容易变形, 系统约束效果也是比较好的。 

 

mosi 发送逻辑



系统复位信号rst_n 和 片选有效spi_cs_cmd 这两个信号 一起生成同步rest 信号 : phy_reset_neg , 这个信号(phy_reset_neg )用来同步复位 发送状态机。
发送状态机: 有2个状态。 状态0: 接收上层模块的数据, 状态1: 用来发送当前的数据(从上层模块接收到的), 当8bit 数据发送完毕, 产生flash_data_done 信号, 用于通知上层模块当前数据发送完毕,可以接收新的数据了。(flash_data_done 和发送的最后一个bit同时产生)

miso 接收逻辑

 

rst_n , flash_data_done,  spi_cs_cmd 信号一起产生 phy_reset 信号。 即: 发送、接收结束, 片选失效, 系统复位 这3中情况 ,都会产生 phy_reset 信号,用于复位 接收逻辑

每当时钟上升沿时 , 从spi_miso 上接收1bit 数据, 当8bit 数据接收完毕, 产生flash_dout_vld 信号,将flash_dout ,flash_dout_vld 一起送给上层模块,表示当前接收到了1byte 数据。

 

spi_cs 信号

上层模块发送的spi_cs_cmd 用来驱动spi_cs 信号。

上述模块仿真:

到此, 上层模块可以控制 spi_cs 信号, 发送 8bit 数据,让spi_phy.v 模块发送到spi_mosi 上, 接收spi_miso 信号解码后的8bit 数据了

Posted in FPGA, FPGA 教材教案, RISC-V 外设, RISC-V架构, 教材与教案, 文章, 集成电路