1.擦除程序,程序擦除是可以用软件,但本文主要讨论用代码实现擦除。擦除已经固化好的程序需要对flash芯片(M25P94)的时序进行描述。时序原理如图所示:
这里主要是对flash的前8个扇区进行擦除,为了产生擦除标志,所以多家了一个wait_3s的标识,8个扇区总共需要24秒。
2.固化原理描述,fpga是没有存储程序的空间的。所以需要flash芯片来存储程序,可以用ise软件固化,也可以用verilog代码固化。这里就需要阅读M25P64 flash芯片的手册,主要是对时序的控制。
3.通过uart协议发送固化程序,需要在ise软件中生成bin文件,然后通过matlab实现进制转化。最终发送到fpga芯片中。
4.擦除与固化的代码为:
/***************************
spi协议控制flash扇区固化
****************************/
module flash_ctrl_wr(
inputwiresclk,
inputwirerst_n,
inputwirepi_flag,
inputwire[7:0]data_in,
outputregcs_n,
outputregsck,
outputregsdi
);
reg[9:0]state;
parameteridle=10'b0000_0000_01;
parameterWAIT1=10'b0000_0000_10;
parameterWRITE=10'b0000_0001_00;
parameterWAIT2=10'b0000_0010_00;
parameterWAIT3=10'b0000_0100_00;
parameterWAIT4=10'b0000_1000_00;
parameterPP=10'b0001_0000_00;
parameterINIT_ADDR=10'b0010_0000_00;
parameterDATA_IN=10'b0100_0000_00;
parameterWAIT5=10'b1000_0000_00;
reg[4:0]sclk_cnt;
parameterSCLK_CNT=31;
reg[1:0]cnt_init_addr;
reg[1:0]cnt4;
reg[2:0]bit_cnt;
regadd_addr_flag;
reg[23:0]init_addr;
parameterINIT_ADDR_Location=6'h00_00_00;
parameterwr_en=8'h06;
parameterPP_en=8'h02;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
add_addr_flag<=0;
else if(state==WAIT5&&sclk_cnt==SCLK_CNT)
add_addr_flag<=1;
else add_addr_flag<=0;
always@(posedgesclk or negedge rst_n)
if(!rst_n)
init_addr<=INIT_ADDR_Location;
else if(add_addr_flag==1)
init_addr<=init_addr+24'h0000_01; //字节自动加一,加到255后页自动加一
//else init_addr<=24'd0;
always@(posedgesclk or negedgerst_n)
if(!rst_n)
cnt4<=2'd0;
else if(cnt4==3)
cnt4<=2'd0;
else if(state==WRITE||state==PP||state==INIT_ADDR||state==DATA_IN)
cnt4<=cnt4+1;
always@(posedgesclk or negedgerst_n)
if(!rst_n)
bit_cnt<=3'd0;
else if(bit_cnt==7&&cnt4==3)
bit_cnt<=3'd0;
else if(cnt4==3)
bit_cnt<=bit_cnt+1;
always@(posedgesclk or negedge rst_n)
if(!rst_n)
cs_n<=1;
else if(pi_flag==1)
cs_n<