2 FPGA实现SPI接口--SPI接口芯片的实际使用( 四 )

<= flow_cnt + 1'd1;data_send <= SECTOR_ADDR;//数据为扇区地址endelse beginflow_cnt <= flow_cnt;data_send <= data_send;endend 'd3:begin//发送页地址if(send_done)begin//发送完成flow_cnt <= flow_cnt + 1'd1;data_send <= PAGE_ADDR;//数据为页地址endelse beginflow_cnt <= flow_cnt;data_send <= data_send;endend 'd4:begin//发送字节地址if(send_done)begin//指令被发送完成flow_cnt <= flow_cnt + 1'd1;data_send <= BYTE_ADDR;//数据为字节地址endelse beginflow_cnt <= flow_cnt;data_send <= data_send;endend'd5:beginif(send_done)begin//字节地址被发送完成flow_cnt <= flow_cnt + 1'd1;data_send <= 8'd0;//清空发送数据endelseflow_cnt <= flow_cnt;end 'd6:beginif(rec_done)//这个发送最后一个字节的接收完成标志flow_cnt <= flow_cnt + 1'd1;elseflow_cnt <= flow_cnt;end'd7:begin//读取数据阶段if(rec_done)begin//接收到了一个BYTE数据if(data_cnt == BYTE_MAX - 1'd1)begin //接收到了指定长度个数据data_cnt <= 8'd0;//计数器清零spi_end <= 1'b1;//结束SPI传输flow_cnt <= flow_cnt + 1'd1;endelse begin//没有接收到指定长度的数据则继续接收data_cnt <= data_cnt + 1'd1;flow_cnt <= flow_cnt;endendelse begin//一个BYTE数据接收未完成data_cnt <= data_cnt;flow_cnt <= flow_cnt;endend'd8:begin//停留在这个状态flow_cnt <= flow_cnt;enddefault:;endcaseendendendmodule
读数据顶层模块代码如下:
//FLASH读取数据顶层模块module spi_read#(parameter BYTE_MAX= 8'd10,//一共读取多少个BYTE的数据SECTOR_ADDR = 8'b0000_0000 ,//扇区地址PAGE_ADDR= 8'b0000_0000 ,//页地址BYTE_ADDR= 8'b0000_0000//字节地址)(// 系统接口input sys_clk,//全局时钟50MHzinput sys_rst_n ,//复位信号,低电平有效// SPI物理接口input spi_miso ,//SPI串行输入,用来接收从机的数据output spi_sclk ,//SPI时钟output spi_cs,//SPI片选信号,低电平有效output spi_mosi//SPI输出,用来给从机发送数据); wirespi_start ;//发送传输开始信号,一个高电平wirespi_end;//发送传输结束信号,一个高电平wire [7:0]data_send;//要发送的数据wire [7:0]data_rec;//接收到的数据wiresend_done ;//主机发送一个字节完毕标志wirerec_done ;//主机接收一个字节完毕标志//------------<例化模块>----------------------------------------------------------------//读数据控制模块spi_read_ctrl#(.BYTE_MAX(BYTE_MAX),.SECTOR_ADDR (SECTOR_ADDR ),.PAGE_ADDR(PAGE_ADDR),.BYTE_ADDR(BYTE_ADDR)) spi_read_ctrl_inst(.sys_clk(sys_clk ),.sys_rst_n(sys_rst_n ),.send_done(send_done ),.spi_start(spi_start ),.spi_end(spi_end ),.data_send(data_send ),.data_rec(data_rec ),.rec_done(rec_done ));//SPI驱动spi_drive spi_drive_inst(.sys_clk(sys_clk ),.sys_rst_n(sys_rst_n ),.spi_start(spi_start ),.spi_end(spi_end ),.data_send(data_send ),.data_rec(data_rec ),.send_done(send_done ),.rec_done(rec_done ),.spi_miso(spi_miso ),.spi_sclk(spi_sclk ),.spi_cs(spi_cs),.spi_mosi(spi_mosi ));endmodule
2.2.3、及仿真结果
比较简单直接例化读数据模块和仿真模型即可,同时让命令窗口打印读取到的数据 。
//------------------------------------------------//--SPI驱动仿真--读数据仿真//------------------------------------------------`timescale 1ns/1ns//时间单位/精度//------------<模块及端口声明>----------------------------------------module tb_spi_read();regsys_clk;regsys_rst_n ;wire spi_miso ;wire spi_sclk ;wire spi_cs;wire spi_mosi ;parameter BYTE_MAX= 8'd10,//一共读取多少个BYTE的数据SECTOR_ADDR = 8'b0000_0000 ,//扇区地址PAGE_ADDR= 8'b0000_0000 ,//页地址BYTE_ADDR= 8'b0000_0000 ;//字节地址//------------<例化被测试模块>----------------------------------------//读数据模块spi_read #(.BYTE_MAX(BYTE_MAX),.SECTOR_ADDR (SECTOR_ADDR ),.PAGE_ADDR(PAGE_ADDR),.BYTE_ADDR(BYTE_ADDR))spi_read_inst(.sys_clk (sys_clk ),.sys_rst_n (sys_rst_n ),.spi_miso (spi_miso ),.spi_sclk (spi_sclk ),.spi_cs(spi_cs),.spi_mosi (spi_mosi ));//m25p16仿真模型m25p16memory (.c(spi_sclk ), .data_in(spi_mosi), .s(spi_cs), .w(1'b1), .hold(1'b1), .data_out(spi_miso)); //------------