Spi flash 数码管显示flash两位数 按键可实现数据写入 流程图
//
// //
// //
// Author: meisq //
// [email protected] //
// ALINX(shanghai) Technology Co.,Ltd //
// heijin //
// WEB: http://www.alinx.cn/ //
// BBS: http://www.heijin.org/ //
// //
//
// //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd //
// All rights reserved //
// //
// This source file may be used and distributed without restriction provided //
// that this copyright statement is not removed from the file and that any //
// derivative work contains the original copyright notice and the associated //
// disclaimer. //
// //
//
//================================================================================
// Revision History:
// Date By Revision Change Description
//--------------------------------------------------------------------------------
// 2017/5/3 meisq 1.0 Original
//*******************************************************************************/
//黑金fpga开发板spi flash分析流程从上至下
//模块1 spi_flash_test功能:启动后读取flash 0地址一个字节数据 在数码管种显示出来;//
// 按一次按键读取的数据增加1 并擦除写入到0地址,最后读取并显示出来
`include "spi_flash_defines.v" //里面宏定义flash命令
module spi_flash_test(
input clk, //外部时钟
input rst_n, //外部复位引脚
input key1, //外部按键引脚
output ncs, //spi flash 片选引脚
output dclk, // clock spi flash 时钟引脚
output mosi, // master output spi flash数据输出引脚
input miso, // master input spi flash数据输入引脚
output [5:0] seg_sel, //数码管选中引脚
output [7:0] seg_data //数码管段点亮引脚
);
localparam S_IDLE = 0;//程序组合时序控制状态 准备态
localparam S_READ_ID = 1; //读取数据状态
localparam S_SE = 2;//Sector Erase //擦除删去态
localparam S_PP = 3; //写数据态
localparam S_READ = 4;//读取数据状态
localparam S_WAIT = 5; //等待按键按下
reg[3:0] state;//状态寄存器
wire button_negedge;//按键下降沿有效标志 1
reg[7:0] read_data; //从spi flash 读取数据存储寄存器
reg[31:0] timer; //定时计数寄存器
reg flash_read; //flash 读取数据标志
reg flash_write; //flash 写数据标志
reg flash_bulk_erase; //flash 整个芯片擦除标志
reg flash_sector_erase; flash 扇区擦除标志
wire flash_read_ack; //flash 读取数据应答标志
wire flash_write_ack; //flash 写数据应答标志
wire flash_bulk_erase_ack; //flash 整个芯片擦除应答
wire flash_sector_erase_ack;//flash 扇区擦除应答
reg[23:0] flash_read_addr; //flash 读取数据地址
reg[23:0] flash_write_addr; //flash 写数据地址
reg[23:0] flash_sector_addr; //flash 扇区擦除地址
reg[7:0] flash_write_data_in; //flash 写数据数据
wire[8:0] flash_read_size; //flash 读取数据大小
wire[8:0] flash_write_size; //flash 写数据大小
wire flash_write_data_req; //flash 写数据请求数据
wire[7:0] flash_read_data_out; //flash 读取数据
wire flash_read_data_valid; //flash 读取数据有效
//模块2 ax_debounce 读取按键返回值:上升沿 下降沿 有效标志:功能当有按键按下 button_negedge下降沿为1
ax_debounce ax_debounce_m0
(
.clk (clk),
.rst (~rst_n),
.button_in (key1),
.button_posedge (),
.button_negedge (button_negedge),
.button_out ()
);
wire[6:0] seg_data_0;//模块3 seg_decoder数码管编码转换 功能:将4位的十六进制数转换成数码管对应的7位数
seg_decoder seg_decoder_m0(
.bin_data (read_data[3:0]),
.seg_data (seg_data_0)
);
wire[6:0] seg_data_1;//模块3 seg_decoder数码管编码转换 功能:将4位的十六进制数转换成数码管对应的7位数
seg_decoder seg_decoder_m1(
.bin_data (read_data[7:4]),
.seg_data (seg_data_1)
);
seg_scan seg_scan_m0(//模块4 seg_scan数码管刷新模块,功能实时刷新数码管数据
.clk (clk),
.rst_n (rst_n),
.seg_sel (seg_sel),
.seg_data (seg_data),
.seg_data_0 ({1'b1,7'b1111_111}),
.seg_data_1 ({1'b1,7'b1111_111}),
.seg_data_2 ({1'b1,7'b1111_111}),
.seg_data_3 ({1'b1,7'b1111_111}),
.seg_data_4 ({1'b1,seg_data_1}),
.seg_data_5 ({1'b1,seg_data_0})
);
assign flash_read_size = 9'd1; //读取flash数据大小是1
assign flash_write_size = 9'd1;//写入flash数据大小也是1
always@(posedge clk or negedge rst_n) //所有功能模块逻辑功能控制
begin
if(rst_n == 1'b0)//上电或复位初始化数据
begin
state <= S_IDLE;
flash_read <= 1'b0;
flash_write <= 1'b0;
flash_bulk_erase <= 1'b0;
flash_sector_erase <= 1'b0;
flash_read_addr <= 24'd0;
flash_write_addr <= 24'd0;
flash_sector_addr <= 24'd0;
flash_write_data_in <= 8'd0;
timer <= 32'd0;
end
else
case(state)
S_IDLE://开机稳定后进入读取flash状态
begin
if(timer >= 32'd12_499_999)
state <= S_READ;
else
timer <= timer + 32'd1;
end
S_WAIT://等待按键按下
if(button_negedge == 1'b1)
begin
state <= S_SE;//1、如果按键按下 进入flash擦除态 准备写入数据
read_data <= read_data + 8'd1;
end
S_SE: //flash删去查出态
begin
if(flash_sector_erase_ack == 1'b1)//确认扇区擦除成功 进入flash写数据态
begin
flash_sector_erase <= 1'b0;
state <= S_PP;
end
else
begin //1、flash扇区擦除标志和地址设置
flash_sector_erase <= 1'b1;
flash_sector_addr <= 24'd0;
end
end
S_PP: //flash 准备写数据
begin
if(flash_write_data_req == 1'b1)//2、判断flash准备好 设置写入数据
flash_write_data_in <= read_data;
if(flash_write_ack == 1'b1) //3、写数据完成 进入读取数据态
begin
flash_write <= 1'b0;
state <= S_READ;
end
else
begin
flash_write <= 1'b1; //1、设置写数据标志及地址
flash_write_addr <= 24'd0;
end
end
S_READ://读取flash态
begin
if(flash_read_data_valid == 1'b1)//2、读取有效数据
read_data <= flash_read_data_out;
if(flash_read_ack == 1'b1)//3、读取数据应答 则进入等待按键按下态
begin
flash_read <= 1'd0;
state <= S_WAIT;
end
else
begin
flash_read <= 1'd1; //1、设置读取数据标志和地址
flash_read_addr <= 24'd0;
end
end
default:
state <= S_IDLE;
endcase
end
spi_flash_top spi_flash_top_m0(//模块5 spi_flash_top flash控制。功能:实现数据的读取 擦除 写入
.sys_clk (clk ),
.rst (~rst_n ),
.nCS (ncs ),
.DCLK (dclk ),
.MOSI (mosi ),
.MISO (miso ),
.clk_div (16'd0 ), // 50Mhz / 4
.flash_read (flash_read ),
.flash_write (flash_write ),
.flash_bulk_erase (flash_bulk_erase ),
.flash_sector_erase (flash_sector_erase ),
.flash_read_ack (flash_read_ack ),
.flash_write_ack (flash_write_ack ),
.flash_bulk_erase_ack (flash_bulk_erase_ack ),
.flash_sector_erase_ack (flash_sector_erase_ack ),
.flash_read_addr (flash_read_addr ),
.flash_write_addr (flash_write_addr ),
.flash_sector_addr (flash_sector_addr ),
.flash_write_data_in (flash_write_data_in ),
.flash_read_size (flash_read_size ),
.flash_write_size (flash_write_size ),
.flash_write_data_req (flash_write_data_req ),
.flash_read_data_out (flash_read_data_out ),
.flash_read_data_valid (flash_read_data_valid )
);
endmodule