| 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 |