【FPGA】FPGA实现SPI协议读写FLASH(四)----- 汇总篇

目录

  • 一、功能分析
  • 二、模块划分
  • 三、代码实现
  • 四、板级验证

写在前面:
FPGA实现通过SPI协议读写FLASH系列相关文章:
SPI通信协议
【FPGA】FPGA实现SPI协议读写FLASH(一)----- M25P16操作概述
【FPGA】FPGA实现SPI协议读写FLASH(二)----- SPI接口驱动模块设计
【FPGA】FPGA实现SPI协议读写FLASH(三)----- SPI读写控制模块设计
上篇文章介绍了SPI读写控制模块的实现,本文将对SPI读写FLASH整体工程设计进行详细介绍;本项目中所使用的开发板型号:Cyclone IV E (EP4CE6F17C8),FLASH型号:M25P16。

一、功能分析

本工程要实现的功能如下:

  1. 通过按键控制读ID请求、读数据请求、写数据请求。
  2. PC端通过串口向FPGA发送写入FLASH的数据,FPGA从FLASH读回数据后通过串口发送给PC端进行显示,1次读写8字节数据。
  3. FPGA通过控制模块控制读写时序,实现SPI接口驱动,严格按照SPI协议与FLASH进行数据交互。
  4. 通过数码管显示读回的FLASH的ID数据以及读写模式。

二、模块划分

整体工程架构如下:
【FPGA】FPGA实现SPI协议读写FLASH(四)----- 汇总篇_第1张图片
模块说明:
key_fliter:按键消抖模块,将输入的按键信号进行消抖处理,向控制模块输出稳定的请求信号。
uart_rx:串口接收模块,接收来自PC端的8字节数据,并发送给控制模块。
uart_tx:串口发送模块,将控制模块接收到的从FLASH读回的数据通过串口发送至PC端显示。
flash_control:FLASH读写控制模块,包含flash_write和flash_read模块。
flash_write:FLASH写控制模块,控制写操作指令发送顺序、数据发送以及延时操作等。
flash_read:FLASH读控制模块,控制读ID和读数据操作。
spi_interface:SPI接口驱动模块,实现SPI协议,将控制模块传输的数据按照SPI协议与FLASH进行数据交互。
seg_driver:数码管驱动模块,显示读回的FLASH的ID数据以及操作模式。

三、代码实现

1、工程顶层代码如下:

//  **************************************************************
//  Author: Zhang JunYi
//  Create Date: 2022.11.15                        
//  Design Name: spi_flash    
//  Module Name: top         
//  Target Device: Cyclone IV E (EP4CE6F17C8), FLASH(M25P16)                
//  Tool versions: Quartus Prime 18.1             
//  Description: SPI读写FLASH顶层设计模块
//  **************************************************************
module top (
    input           clk             ,
    input           rst_n           ,
    //  key_filter
    // input           rdid_req        ,       //  读ID请求  仿真用
    // input           rdda_req        ,       //  读数据请求
    // input           wr_req          ,       //  写请求
    input   [2:0]   key_in          ,

    //  上位机
    input           uart_rxd        ,
    output          uart_txd        ,
    //  FLASH
    output            sclk          ,
    output            cs_n          ,
    output            mosi          ,
    input             miso          ,
    //  seg_driver
    output  [7:0]   seg_dig         ,
    output  [5:0]   seg_sel         
);
    //  信号定义
    wire            rw_done         ;
    wire    [7:0]   rdout           ;
    
    wire    [7:0]   dout            ;
    wire            req             ;

    wire    [23:0]  display_id      ;
    wire            display_id_vld  ;
    wire    [2:0]   modle           ;

    wire    [7:0]   rxdata          ;
    wire            rxdata_vld      ;

    wire    [7:0]   txdata          ;
    wire            txdata_vld      ;
    wire            ready           ;

    wire            rdid_req        ;       //  读ID请求
    wire            rdda_req        ;       //  读数据请求
    wire            wr_req          ;       //  写数据请求

    // 模块例化
    key_filter u_key_filter1 (
    /*input           */.clk         (clk           ),
    /*input           */.rst_n       (rst_n         ),
    /*input           */.key_in      (key_in[0]     ),
    /*output    reg   */.key_out     (rdid_req      )
    );

    key_filter u_key_filter2 (
    /*input           */.clk         (clk           ),
    /*input           */.rst_n       (rst_n         ),
    /*input           */.key_in      (key_in[1]     ),
    /*output    reg   */.key_out     (rdda_req      )
    );

    key_filter u_key_filter3 (
    /*input           */.clk         (clk           ),
    /*input           */.rst_n       (rst_n         ),
    /*input           */.key_in      (key_in[2]     ),
    /*output    reg   */.key_out     (wr_req        )
    );

    uart_rx u_uart_rx (
        /*input               */.clk             (clk       ),
        /*input               */.rst_n           (rst_n     ),
        /*input               */.uart_rx         (uart_rxd  ),       //  接收到的串口数据
    
        /*output  [7:0]       */.rx_dout         (rxdata    ),       //  串行数据转换成并行数据后输出给control模块
        /*output              */.rx_dout_vld     (rxdata_vld)
    );

    uart_tx u_uart_tx (
    /*input               */.clk             (clk       ),
    /*input               */.rst_n           (rst_n     ),
    /*//  control*/
    /*input   [7:0]       */.tx_din          (txdata    ),
    /*input               */.tx_din_vld      (txdata_vld),
    /*output              */.ready           (ready     ),       //  给control模块的握手信号,表示可以接收数据进行发送 
    /*//  上位机*/
    /*output              */.uart_tx         (uart_txd  )
    );

    flash_control u_flash_control (
    /*input           */.clk             (clk       ),
    /*input           */.rst_n           (rst_n     ),
    /*//  key_filter*/
    /*input           */.rdid_req        (rdid_req  ),       //  读ID请求
    /*input           */.rdda_req        (rdda_req  ),       //  读数据请求
    /*input           */.wr_req          (wr_req    ),       //  写数据请求
    /*//  uart_rx*/
    /*input   [7:0]   */.rx_data         (rxdata    ),       //  串口接收要写入FLASH的数据
    /*input           */.rx_data_vld     (rxdata_vld),
    /*//  uart_tx*/
    /*input           */.ready           (ready     ),       //  ready
    /*output  [7:0]   */.tx_data         (txdata    ),       //  串口发送从FLASH读取的数据
    /*output          */.tx_data_vld     (txdata_vld),

    /*//  spi_interface*/
    /*input           */.rw_done         (rw_done   ),       //  SPI接口模块读写一字节完成标志
    /*input   [7:0]   */.rdin            (rdout     ),       //  SPI接口模块读回的数据
    /*output  [7:0]   */.dout            (dout      ),       //  输出给SPI接口模块要发送的数据
    /*output          */.req             (req       ),       //  读写请求
    //  seg_driver
    /*output  [23:0]  */.display_id      (display_id),       //  数码管显示读ID
    /*output          */.display_id_vld  (display_id_vld),
    /*output  [2:0]   */.modle           (modle     )        //  读写模式 001:读ID 010:读数据  100:写数据
    );

    spi_interface u_spi_interface (
    /*input               */.clk             (clk        ),
    /*input               */.rst_n           (rst_n      ),
    /*//  flash_control*/
    /*input               */.req             (req        ),       //  读写数据请求
    /*input   [7:0]       */.din             (dout       ),       //  要传输的数据
    /*output  [7:0]       */.rdout           (rdout      ),       //  读回的数据
    /*output              */.rw_done         (rw_done    ),       //  读写一字节数据完成标志
    /*//  M25P16*/
    /*output              */.sclk            (sclk),
    /*output              */.cs_n            (cs_n),
    /*output              */.mosi            (mosi),
    /*input               */.miso            (miso)   
    );

    seg_driver u_seg_driver (
    /*input               */.clk             (clk       ),
    /*input               */.rst_n           (rst_n     ),
    /*//  flash_control*/
    /*input   [2:0]       */.rw_flag         (modle     ),       //  读写标志
    /*input   [23:0]      */.disp_data       (display_id),
    /*input               */.disp_data_vld   (display_id_vld),
    /*//  数码管*/
    /*output  [5:0]       */.seg_sel         (seg_sel   ),
    /*output  [7:0]       */.seg_dig         (seg_dig   )             
    );  
endmodule

2、flash_control模块代码实现
FPGA实现SPI协议读写FLASH(三)----- SPI读写控制模块设计
3、spi_interface模块代码实现
【FPGA】FPGA实现SPI协议读写FLASH(二)----- SPI接口驱动模块设计
4、其他模块
其他的按键消抖模块、串口收发模块、数码管驱动模块比较简单,这里不过多赘述。

四、板级验证

1、读ID操作
【FPGA】FPGA实现SPI协议读写FLASH(四)----- 汇总篇_第2张图片
2、写数据操作
【FPGA】FPGA实现SPI协议读写FLASH(四)----- 汇总篇_第3张图片
3、读数据操作
【FPGA】FPGA实现SPI协议读写FLASH(四)----- 汇总篇_第4张图片

你可能感兴趣的:(FPGA,#,UART,IIC,SPI,fpga开发,SPI协议)