`timescale 1ns / 1ns
module flash_be(
sys_clk,
reset_n,
key_in,
spi_mosi,
spi_cs,
spi_sck
);
input sys_clk;
input reset_n;
input key_in;
output reg spi_mosi;
output reg spi_cs;
output reg spi_sck;
parameter WR_EN_INST = 8'h06;
parameter BE_INST = 8'hC7;
parameter IDLE = 4'b0001;
parameter WR_EN = 4'b0010;
parameter DELAY = 4'b0100;
parameter BE = 4'b1000;
reg [3:0] state;
reg [3:0] next_state;
reg [2:0] byte_cnt; //字节计数器
reg [4:0] clk_cnt; //系统计数器
reg [1:0] sck_cnt; //时钟计数器
reg [2:0] bit_cnt; //数据位计数器
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
state<=IDLE;
else
state<= next_state;
end
always@(*)
begin
if(!reset_n)
next_state = IDLE;
else
begin
case(state)
IDLE:
begin
if(key_in)
next_state = WR_EN;
else
next_state = IDLE;
end
WR_EN:
begin
if(byte_cnt==2&&clk_cnt==5'd31)
next_state = DELAY;
else
next_state = WR_EN;
end
DELAY:
begin
if(byte_cnt==3&&clk_cnt==5'd31)
next_state = BE;
else
next_state = DELAY;
end
BE:
begin
if(byte_cnt==6&&clk_cnt==5'd31)
next_state = IDLE;
else
next_state = BE;
end
endcase
end
end
//系统计数器
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
clk_cnt<=0;
else if(state!=IDLE)
clk_cnt<=clk_cnt+1'b1;
else clk_cnt<=0;
end
//字节计数器
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
byte_cnt<=0;
else if(byte_cnt==3'd6&&clk_cnt==5'd31)
byte_cnt<=0;
else if(clk_cnt==5'd31)
byte_cnt<=byte_cnt+1'b1;
else
byte_cnt<=byte_cnt;
end
// 时钟计数器
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
sck_cnt<=0;
else if(state==WR_EN && byte_cnt==3'd1)
sck_cnt<=sck_cnt+1'b1;
else if(state==BE && byte_cnt==3'd5)
sck_cnt<=sck_cnt+1'b1;
end
// 数据位计数器
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
bit_cnt<=0;
else if(bit_cnt==7&&sck_cnt==1)
bit_cnt<=0;
else if(sck_cnt==1)
bit_cnt<= bit_cnt+1'b1;
else bit_cnt<=bit_cnt;
end
//cs信号控制
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
spi_cs<=1;
else if(state==WR_EN)
spi_cs<=0;
else if(state==DELAY)
spi_cs<=1;
else if(state==BE)
spi_cs<=0;
else
spi_cs<=1;
end
//时钟生成
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
spi_sck<=0;
else if(sck_cnt==1)
spi_sck<=1;
else if(sck_cnt==3)
spi_sck<=0;
else spi_sck<=spi_sck;
end
//MOSI数据输出
always@(posedge sys_clk or negedge reset_n)
begin
if(!reset_n)
spi_mosi<=0;
else if(byte_cnt==3'd1&&clk_cnt==5'd31)
spi_mosi<=0;
else if(byte_cnt==3'd5&&clk_cnt==5'd31)
spi_mosi<=0;
else if(byte_cnt==3'd1&&sck_cnt==2'd0)
spi_mosi<=WR_EN_INST[7-bit_cnt];
else if(byte_cnt==3'd5&&sck_cnt==2'd0)
spi_mosi<=BE_INST[7-bit_cnt];
else
spi_mosi<= spi_mosi;
end
endmodule
SPI Flash 擦除
最新推荐文章于 2024-05-10 21:50:52 发布