module flash_se(
input wire clk,
input wire rst_n,
input wire we_flag,
input wire [23:0]SE_addr,
output reg sck,
output reg sdi,
output reg cs_n
);
reg we_en; //进入写使能指令时序的标志信号
reg se_en; //进入扇区擦除指令时序的标志信号
reg [3:0]state;//定义状态变量
reg sck0,sck1;
reg sdi0,sdi1;
reg cs_n0,cs_n1;
parameter idel = 4'b0001; //初始状态
parameter WERN = 4'b0010; //写使能指令状态
parameter SE = 4'b0100; //扇区擦除
parameter DELAY = 4'b1000;//3秒延时状态
reg[5:0]we_cnt;
reg[7:0]se_cnt;
reg[27:0]delay_cnt;
//写使能指令时序的计数器
always@(posedge clk or negedge rst_n)
if(!rst_n)
we_cnt<=0;
else if(we_cnt=='d41)
we_cnt<=0;
else if(we_en)
we_cnt<=we_cnt+1'b1;
//扇区擦除时序的计数器
always@(posedge clk or negedge rst_n)
if(!rst_n)
se_cnt<=0;
else if(se_cnt=='d128)
se_cnt<=0;
else if(se_en)
se_cnt<=se_cnt+1'b1;
parameter T3S = 28'd150_000_000-1;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
state<=idel;
delay_cnt<=0;
we_en<=0;
se_en<=0;
end
else begin
case(state)
idel: if(we_flag) //投入0.5元
state<=WERN;
else
state<=idel;
WERN:if(we_cnt=='d41)begin
state<=SE;
we_en<=0;
end
else begin
state<=state;
we_en<=1;
end
SE:if(se_cnt=='d128)begin
state<=DELAY;
se_en<=0;
end
else begin
state<=state;
se_en<=1;
end
DELAY:if(delay_cnt==T3S)begin
state<=idel;
delay_cnt<=0;
end
else begin
delay_cnt<=delay_cnt+1'b1;
state<=state;
end
default:state<=idel;
endcase
end
end
//写使能信号时序通过线性序列机
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
sck0<=0;cs_n0<=1;sdi0<=0;
end
else begin
case(we_cnt)
0 :cs_n0<=0;
1 :sck0<=1;
4 :sck0<=0;
6 :sck0<=1;
8 :sck0<=0;
10:sck0<=1;
12:sck0<=0;
14:sck0<=1;
16:sck0<=0;
18:sck0<=1;
20:sck0<=0;
22:begin sck0<=1; sdi0<=1;end
24:sck0<=0;
26:begin sck0<=1; sdi0<=1;end
28:sck0<=0;
30:begin sck0<=1; sdi0<=0;end
32:sck0<=0;
34:sck0<=1;
35:sck0<=0;
40:begin sck0<=0;cs_n0<=1;sdi0<=0;end
default: ;
endcase
end
//扇区擦除时序通过线性序列机
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
sck1<=0;cs_n1<=1;sdi1<=0;
end
else begin
case(se_cnt)
0:begin sck1<=0;cs_n1<=1;sdi1<=0;end
2 :begin sck1<=1;cs_n1<=0;end
4 :sck1<=0;
6 :begin sck1<=1;sdi1<=1;end
8 :sck1<=0;
10 :begin sck1<=1;sdi1<=0;end
12 :sck1<=0;
14 :begin sck1<=1;sdi1<=1;end
16 :sck1<=0;
18 :begin sck1<=1;sdi1<=1;end
20 :sck1<=0;
22 :begin sck1<=1;sdi1<=0;end
24 :sck1<=0;
26 :sck1<=1;
28 :sck1<=0;
30 :sck1<=1;
32 :sck1<=0;
34 :begin sck1<=1;sdi1<=SE_addr[23];end
36 :sck1<=0;
38 :begin sck1<=1;sdi1<=SE_addr[22];end
40 :sck1<=0;
42 :begin sck1<=1;sdi1<=SE_addr[21];end
44 :sck1<=0;
46 :begin sck1<=1;sdi1<=SE_addr[20];end
48 :sck1<=0;
50 :begin sck1<=1;sdi1<=SE_addr[19];end
52 :sck1<=0;
54 :begin sck1<=1;sdi1<=SE_addr[18];end
56 :sck1<=0;
58 :begin sck1<=1;sdi1<=SE_addr[17];end
60 :sck1<=0;
62 :begin sck1<=1;sdi1<=SE_addr[16];end
64 :sck1<=0;
66 :begin sck1<=1;sdi1<=SE_addr[15];end
68 :sck1<=0;
70 :begin sck1<=1;sdi1<=SE_addr[14];end
72 :sck1<=0;
74 :begin sck1<=1;sdi1<=SE_addr[13];end
76 :sck1<=0;
78 :begin sck1<=1;sdi1<=SE_addr[12];end
80 :sck1<=0;
82 :begin sck1<=1;sdi1<=SE_addr[11];end
84 :sck1<=0;
86 :begin sck1<=1;sdi1<=SE_addr[10];end
88 :sck1<=0;
90 :begin sck1<=1;sdi1<=SE_addr[9];end
92 :sck1<=0;
94 :begin sck1<=1;sdi1<=SE_addr[8];end
96 :sck1<=0;
98 :begin sck1<=1;sdi1<=SE_addr[7];end
100 :sck1<=0;
102 :begin sck1<=1;sdi1<=SE_addr[6];end
104 :sck1<=0;
106 :begin sck1<=1;sdi1<=SE_addr[5];end
108 :sck1<=0;
110 :begin sck1<=1;sdi1<=SE_addr[4];end
112 :sck1<=0;
114 :begin sck1<=1;sdi1<=SE_addr[3];end
116 :sck1<=0;
118 :begin sck1<=1;sdi1<=SE_addr[2];end
120 :sck1<=0;
122 :begin sck1<=1;sdi1<=SE_addr[1];end
124 :sck1<=0;
126 :begin sck1<=1;sdi1<=SE_addr[0];end
128 :begin sck1<=0;cs_n1<=1;sdi1<=0;end
default: ;
endcase
end
//对于输出避免冒险通过选择器
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
sck<=0;cs_n<=1;sdi<=0;
end
else if(state==WERN)begin
sck<=sck0;cs_n<=cs_n0;sdi<=sdi0;
end
else if(state==SE)begin
sck<=sck1;cs_n<=cs_n1;sdi<=sdi1;
end
endmodule
|