扇区擦除:
和全擦除类似
32个扇区
一个扇区 = 512kb
每256页构成一个扇区。
扇区擦除在写入指令后要加入三个字节的地址。 与全擦除的区别。
选择扇区0 00_04_25 000000000, 0000 0100 ,0010 0101
00代表扇区 04 代表页地址 25代表字节地址 WREN SE_IN 和三个地址
WREN_IN = 8'B0000_0010;
SE_IN = 8'B1100_1000;
S_ADDR = 8'B0000_0000;
P_ADDR = 8'B0000_0100;
B_ADDR = 8'B0010_0101;
module flash_se_ctrl( input wire sys_clk,input wire sys_rst_n,input wire key_flag,output cs_n,output sck,output mosi);
parameter IDLE = 4’b0001, WREN = 4'b0010,DELAY = 4'b0100,SE = 4'b1000;
//mosi 的指令 SE_IN为全擦除指令
parameter WREN_IN = 8'B0000_0010;
SE_IN = 8'B1100_1000;
S_ADDR = 8'B0000_0000;
P_ADDR = 8'B0000_0100;
B_ADDR = 8'B0010_0101;
reg mosi;
reg sck;
reg cs_n;
reg [3:0] state;
reg [5:0] cnt_clk; //时钟计数器 计数0-31
reg [3:0] cnt_byte; //字节计数器 时钟计数器一个周期后加一 0 -6 刚好七个周期
reg [10] cnt_sck; // 比特计数器为1时候为1,每个时钟周期加一,实现四分频,0123,0123.
reg [2:0] cnt_bit;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE;
else
case(state)
IDLE: if(flag == 1'b1)
state <= WREN;
WREN: if(cnt_byte == 4'b2 && cnt_clk == 6'd31)
state <= DELAY;
DELAY: if(cnt_byte == 4'd3 && cnt_clk == 6'd31)
state <= SE;
SE: if(cnt_byte == 4'd9 && cnt_clk == 6'd31)
state <= IDLE;
default: state <= IDLE;
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_clk <= 5'd0; // 5位宽会自动清零
else if(state != IDLE)
cnt_clk <= cnt_clk + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_byte <= 4'd0;
else if(cnt_byte == 4'd9 && cnt_clk == 6'd31)
cnt_byte <= 4'd0;
else if(cnt_clk == 5'd31)
cnt_byte <= cnt_byte + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_sck <= 2'd0; //计满自动清零了
else if(state ==WREN && cnt_byte == 4'd1)
cnt_sck <= cnt_sck + 1'b1;
else if(state ==SE& cnt_byte >= 4'd5 &&cnt_byte <= 4'd8)
cnt_sck <= cnt_sck + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_bit <= 3'd0;
else if(cnt_sck == 2'd2)
cnt_bit <= cnt_bit + 1'b1;
// 输出信号的赋值
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cs_n <= 1'b1;
else if(key_flag == 1'b1)
cs_n <= 1'b0;
else if(cnt_byte ==4 'd2 && cnt_clk == 5'd31 && state == WREN)
cs_n <= 1'b1;
else if(cnt_byte ==4 'd3&& cnt_clk == 5'd31 && state == DELAY)
cs_n <= 1'b0
else if(cnt_byte ==4 'd9 && cnt_clk == 5'd31 && state == SE)
cs_n <= 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
mosi <= 1'b0;
else if(state == WREN && cnt_byte == 4'd2)
mosi <= 1'b0;
else if(state == SE&& cnt_byte == 4'd9 )
mosi <= 1'b0;
else if(state == WREN && cnt_byte == 4'd1 && cnt_sck == 2'd0)
mosi <= WREN_IN[7-cnt_byte]; //先写入高位方法
else if(state == SE&& cnt_byte == 4'd5&& cnt_sck == 2'd0)
mosi <= SE_IN[7-cnt_byte];
else if(state == SE&& cnt_byte == 4'd6&& cnt_sck == 2'd0)
mosi <= S_ADDR[7-cnt_byte];
else if(state == SE&& cnt_byte == 4'd7&& cnt_sck == 2'd0)
mosi <= P_ADDR[7-cnt_byte];
else if(state == SE&& cnt_byte == 4'd8&& cnt_sck == 2'd0)
mosi <= B_ADDR[7-cnt_byte];
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
sck <= 1'b0;
else if(cnt_sck == 1'b0)
sck <= 1'b0;
else if(cnt_sck == 2'd2)
sck <= 1'b1;
endmodule