[FPGA] FPGA的flash板卡程序擦除与固化

[复制链接]
3630|3
 楼主| gaochy1126 发表于 2022-3-31 22:57 | 显示全部楼层 |阅读模式

1.擦除程序,程序擦除是可以用软件,但本文主要讨论用代码实现擦除。擦除已经固化好的程序需要对flash芯片(M25P94)的时序进行描述。时序原理如图所示:

    这里主要是对flash的前8个扇区进行擦除,为了产生擦除标志,所以多家了一个wait_3s的标识,8个扇区总共需要24秒。

2.固化原理描述,fpga是没有存储程序的空间的。所以需要flash芯片来存储程序,可以用ise软件固化,也可以用verilog代码固化。这里就需要阅读M25P64 flash芯片的手册,主要是对时序的控制。

3.通过uart协议发送固化程序,需要在ise软件中生成bin文件,然后通过matlab实现进制转化。最终发送到fpga芯片中。


 楼主| gaochy1126 发表于 2022-3-31 22:57 | 显示全部楼层
  1. /***************************
  2. spi协议控制flash扇区固化
  3. ****************************/
  4. module flash_ctrl_wr(
  5.                
  6.                 input        wire                        sclk,
  7.                 input        wire                        rst_n,
  8.                 input        wire                        pi_flag,
  9.                 input        wire        [7:0]        data_in,
  10.                
  11.                 output        reg                cs_n,
  12.                 output        reg                sck,
  13.                 output        reg                sdi
  14. );

  15. reg        [9:0]        state;
  16. parameter        idle                =10'b0000_0000_01;
  17. parameter        WAIT1                =10'b0000_0000_10;
  18. parameter        WRITE                =10'b0000_0001_00;
  19. parameter        WAIT2                =10'b0000_0010_00;
  20. parameter        WAIT3                =10'b0000_0100_00;
  21. parameter        WAIT4                =10'b0000_1000_00;
  22. parameter        PP                        =10'b0001_0000_00;
  23. parameter        INIT_ADDR        =10'b0010_0000_00;
  24. parameter        DATA_IN                =10'b0100_0000_00;
  25. parameter        WAIT5                =10'b1000_0000_00;        
  26. reg        [4:0]        sclk_cnt;
  27. parameter        SCLK_CNT=31;
  28. reg        [1:0]        cnt_init_addr;
  29. reg        [1:0]        cnt4;
  30. reg        [2:0]        bit_cnt;
  31. reg                        add_addr_flag;
  32. reg        [23:0]        init_addr;
  33. parameter        INIT_ADDR_Location=6'h00_00_00;
  34. parameter        wr_en=8'h06;
  35. parameter        PP_en=8'h02;


  36. always@(posedge sclk or negedge rst_n)
  37.         if(!rst_n)
  38.                 add_addr_flag<=0;
  39.         else if(state==WAIT5&&sclk_cnt==SCLK_CNT)
  40.                 add_addr_flag<=1;
  41.         else add_addr_flag<=0;
  42. always@(posedge        sclk or negedge rst_n)       
  43.                 if(!rst_n)       
  44.                         init_addr<=INIT_ADDR_Location;
  45.                 else if(add_addr_flag==1)
  46.                         init_addr<=init_addr+24'h0000_01;         //字节自动加一,加到255后页自动加一
  47.                 //else init_addr<=24'd0;
  48.                                        
  49. always@(posedge        sclk or negedge        rst_n)
  50.                 if(!rst_n)
  51.                         cnt4<=2'd0;
  52.                 else if(cnt4==3)
  53.                         cnt4<=2'd0;
  54.                 else if(state==WRITE||state==PP||state==INIT_ADDR||state==DATA_IN)
  55.                          cnt4<=cnt4+1;
  56. always@(posedge        sclk or negedge        rst_n)
  57.                 if(!rst_n)
  58.                         bit_cnt<=3'd0;
  59.                 else if(bit_cnt==7&&cnt4==3)
  60.                         bit_cnt<=3'd0;
  61.                 else if(cnt4==3)
  62.                                 bit_cnt<=bit_cnt+1;
  63.                                
  64. always@(posedge        sclk or negedge rst_n)
  65.                 if(!rst_n)
  66.                         cs_n<=1;
  67.                 else if(pi_flag==1)
  68.                         cs_n<=0;
  69.                 else if(state==WAIT2&&sclk_cnt==SCLK_CNT)
  70.                         cs_n<=1;
  71.                 else if(state==WAIT3&&sclk_cnt==SCLK_CNT)
  72.                         cs_n<=0;
  73.                 else if(sclk_cnt==SCLK_CNT&&state==WAIT5)
  74.                         cs_n<=1;               
  75. always@(posedge        sclk or negedge rst_n)
  76.                 if(!rst_n)       
  77.                         sclk_cnt<=5'd0;
  78.                 else if        (sclk_cnt==SCLK_CNT&&state==WAIT5)
  79.                         sclk_cnt<=5'd0;
  80.                 else if(sclk_cnt==SCLK_CNT)       
  81.                         sclk_cnt<=5'd0;
  82.                 else if(cs_n==0)
  83.                         sclk_cnt<=sclk_cnt+1;
  84.                 else if(state==WAIT3)
  85.                         sclk_cnt<=sclk_cnt+1;
  86. always@(posedge        sclk or negedge rst_n)
  87.                 if(!rst_n)
  88.                 cnt_init_addr<=2'd0;
  89.                 else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
  90.                         cnt_init_addr<=2'd0;
  91.                 else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR)
  92.                         cnt_init_addr<=cnt_init_addr+1;
  93.                        
  94. always@(posedge        sclk or negedge rst_n)
  95.                 if(!rst_n)
  96.                         state<=idle;
  97.                 else case(state)
  98.                                 idle:                if(pi_flag==1)
  99.                                                                 state<=WAIT1;
  100.                                                         else        state<=idle;
  101.                                 WAIT1:                if(sclk_cnt==SCLK_CNT)
  102.                                                                 state<=WRITE;
  103.                                                         else        state<=WAIT1;
  104.                                 WRITE:                if(sclk_cnt==SCLK_CNT)
  105.                                                                 state<=WAIT2;
  106.                                                         else state<=WRITE;
  107.                                 WAIT2:                if(sclk_cnt==SCLK_CNT)
  108.                                                                 state<=WAIT3;
  109.                                                         else         state<=WAIT2;
  110.                                 WAIT3:                if(sclk_cnt==SCLK_CNT)
  111.                                                                 state<=WAIT4;
  112.                                                         else        state<=WAIT3;
  113.                                 WAIT4:                if(sclk_cnt==SCLK_CNT)
  114.                                                                 state<=PP;
  115.                                 PP:                        if(sclk_cnt==SCLK_CNT)
  116.                                                                 state<=INIT_ADDR;
  117.                                                         else state<=PP;
  118.                                 INIT_ADDR:        if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
  119.                                                                 state<=DATA_IN;
  120.                                                                 else state<=INIT_ADDR;
  121.                                 DATA_IN:        if(sclk_cnt==SCLK_CNT)
  122.                                                                 state<=WAIT5;
  123.                                                         else        state<=DATA_IN;
  124.                                 WAIT5:                if(sclk_cnt==SCLK_CNT)
  125.                                                                         state<=idle;
  126.                                                         else state<=WAIT5;
  127.                                 default:        state<=idle;
  128.                                 endcase
  129.                                                                
  130. always@(posedge        sclk or negedge rst_n)        //时钟传递
  131.                 if(!rst_n)               
  132.                   sck<=0;
  133.                  else if(state==WRITE &&cnt4==1)       
  134.                                  sck<=1;
  135.                  else if(state==WRITE&&cnt4==3)
  136.                                  sck<=0;
  137.                  else if (state==PP&&cnt4==1)       
  138.                                  sck<=1;
  139.                  else if(state==PP&&cnt4==3)
  140.                                  sck<=0;
  141.                  else if (state==INIT_ADDR&&cnt4==1)       
  142.                                  sck<=1;
  143.                  else if(state==INIT_ADDR&&cnt4==3)
  144.                                  sck<=0;
  145.                  else if (state==DATA_IN&&cnt4==1)       
  146.                                  sck<=1;
  147.                  else if(state==DATA_IN&&cnt4==3)
  148.                                  sck<=0;
  149.                                 
  150. always@(posedge        sclk or negedge rst_n)       
  151.                 if(!rst_n)
  152.                         sdi<=1'b1;
  153.                 else if(state==WRITE)       
  154.                         sdi<=wr_en[7-bit_cnt];
  155.                 else if(state==PP)       
  156.                         sdi<=PP_en[7-bit_cnt];
  157.                 else if(state==INIT_ADDR&&cnt_init_addr==0)
  158.                         sdi<=init_addr[23-bit_cnt];
  159.                 else if(state==INIT_ADDR&&cnt_init_addr==1)
  160.                         sdi<=init_addr[15-bit_cnt];
  161.                 else if(state==INIT_ADDR&&cnt_init_addr==2)
  162.                         sdi<=init_addr[7-bit_cnt];
  163.                 else if(state==DATA_IN)
  164.                          sdi<=data_in[7-bit_cnt];
  165.                 else sdi<=1'b1;                                                       
  166. endmodule


 楼主| gaochy1126 发表于 2022-3-31 22:57 | 显示全部楼层
  1. /***************************
  2. spi协议控制flash扇区擦除
  3. ****************************/
  4. module se_ctrl(
  5.                
  6.                 input        wire        sclk,
  7.                 input        wire        rst_n,
  8.                 input        wire        pi_se_flag,
  9.                
  10.                 output        reg                led,
  11.                 output        reg                cs_n,
  12.                 output        reg                sck,
  13.                 output        reg                sdi
  14.                

  15. );

  16. reg        [9:0]        state;
  17. parameter        idle                =10'b0000_0000_01;
  18. parameter        WAIT1                =10'b0000_0000_10;
  19. parameter        WRITE                =10'b0000_0001_00;
  20. parameter        WAIT2                =10'b0000_0010_00;
  21. parameter        WAIT3                =10'b0000_0100_00;
  22. parameter        WAIT4                =10'b0000_1000_00;
  23. parameter        SE                        =10'b0001_0000_00;
  24. parameter        INIT_ADDR        =10'b0010_0000_00;
  25. parameter        WAIT5                =10'b0100_0000_00;
  26. parameter        WAIT_3S                =10'b1000_0000_00;        
  27. reg        [4:0]        sclk_cnt;
  28. parameter        SCLK_CNT=31;
  29. reg        [1:0]        cnt_init_addr;
  30. reg        [25:0]        cnt_1s;
  31. parameter        ONE_S=49_9999_99;
  32. reg        [1:0]        cnt_3s;
  33. reg        [1:0]        cnt4;
  34. reg        [2:0]        bit_cnt;
  35. reg        [3:0]        cnt_wait_3s;
  36. reg        [23:0]        init_addr;
  37. //parameter        INIT_ADDR_Location=6'h00_00_00;
  38. parameter        wr_en=8'h06;                //信号差了一个时钟周期
  39. parameter        se_en=8'hd8;
  40. parameter        CNT_wait_3s=7;
  41. reg                        cnt_3s_en;

  42. //always@(posedge        sclk or negedge        rst_n)
  43. //                if(!rst_n)
  44. //                        se_flag<=0;
  45. //                else if(pi_se_flag==1)
  46. //                        se_flag<=1;



  47. always@(posedge        sclk or negedge rst_n)        //循环擦除
  48.                 if(!rst_n)       
  49.                         cnt_wait_3s<=3'd0;
  50.                 else if(cnt_wait_3s==CNT_wait_3s&&cnt_1s==ONE_S&&cnt_3s==2)
  51.                         cnt_wait_3s<=3'd0;
  52.                 else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)
  53.                         cnt_wait_3s<=cnt_wait_3s+1'b1;

  54. always@(posedge        sclk or negedge rst_n)        //扇区地址变换
  55.                 if(!rst_n)       
  56.                 init_addr<=24'd0;
  57.                 else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)
  58.                         init_addr<=init_addr+24'h01_0000;
  59.                 else if(state==idle)
  60.                         init_addr<=24'd0;
  61.                                        
  62. always@(posedge        sclk or negedge        rst_n)                //为输出时钟计数
  63.                 if(!rst_n)
  64.                         cnt4<=2'd0;
  65.                 else if(cnt4==3)
  66.                         cnt4<=2'd0;
  67.                 else if(state==WRITE||state==SE||state==INIT_ADDR)
  68.                          cnt4<=cnt4+1;
  69. always@(posedge        sclk or negedge        rst_n)   //        bit位计数
  70.                 if(!rst_n)
  71.                 bit_cnt<=3'd0;
  72.                 else if(bit_cnt==7&&cnt4==3)
  73.                 bit_cnt<=3'd0;
  74.                 else if(cnt4==3)
  75.                                 bit_cnt<=bit_cnt+1;
  76.                                
  77. always@(posedge        sclk or negedge        rst_n)
  78.                 if(!rst_n)
  79.                 cnt_1s<=26'd0;
  80.                 else if(cnt_1s==ONE_S)
  81.                         cnt_1s<=26'd0;
  82.                 else if(cnt_3s_en==1)
  83.                         cnt_1s<=cnt_1s+1;
  84. always@(posedge        sclk or negedge        rst_n)
  85.                 if(!rst_n)
  86.                 cnt_3s<=2'd0;
  87.                 else if(cnt_1s==ONE_S&&cnt_3s==2)
  88.                         cnt_3s<=2'd0;
  89.                 else if(cnt_1s==ONE_S)
  90.                         cnt_3s<=cnt_3s+1;
  91. always@(posedge        sclk or negedge rst_n)        //3秒使能信号
  92.                 if(!rst_n)       
  93.                 cnt_3s_en<=0;
  94.                 else if(cnt_1s==ONE_S&&cnt_3s==2)
  95.                         cnt_3s_en<=0;
  96.                 else if(state==WAIT_3S)
  97.                         cnt_3s_en<=1;
  98. always@(posedge        sclk or negedge rst_n)
  99.                 if(!rst_n)
  100.                         cs_n<=1;
  101.                 else if(pi_se_flag==1)
  102.                         cs_n<=0;
  103.                 else if(state==idle)
  104.                         cs_n<=1;
  105.                 else if(state==WAIT2&&sclk_cnt==SCLK_CNT)                //片选信号没有描述对
  106.                         cs_n<=1;
  107.                 else if(state==WAIT3&&sclk_cnt==SCLK_CNT)
  108.                         cs_n<=0;
  109.                 else if(state==WAIT5&&sclk_cnt==SCLK_CNT)
  110.                         cs_n<=1;
  111.                 else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)
  112.                         cs_n<=0;
  113.                 //else if(cnt_wait_3s==CNT_wait_3s)
  114.                         //cs_n<=1;               

  115. always@(posedge        sclk or negedge rst_n)
  116.                 if(!rst_n)       
  117.                         sclk_cnt<=5'd0;
  118.                 else if        (sclk_cnt==SCLK_CNT&&cnt_wait_3s==CNT_wait_3s)
  119.                         sclk_cnt<=5'd0;
  120.                 else if(sclk_cnt==SCLK_CNT)
  121.                                 sclk_cnt<=5'd0;
  122.                 else if(cs_n==0)
  123.                         sclk_cnt<=sclk_cnt+1;
  124.                 else if(state==WAIT3)
  125.                         sclk_cnt<=sclk_cnt+1;                               
  126. always@(posedge        sclk or negedge rst_n)   //3位状态计数
  127.                 if(!rst_n)
  128.                 cnt_init_addr<=2'd0;
  129.                 else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
  130.                         cnt_init_addr<=2'd0;
  131.                 else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR)
  132.                         cnt_init_addr<=cnt_init_addr+1;
  133.                        
  134. always@(posedge        sclk or negedge rst_n)
  135.                 if(!rst_n)
  136.                         state<=idle;
  137.                 else case(state)
  138.                                 idle:                if(pi_se_flag==1)
  139.                                                                 state<=WAIT1;
  140.                                                         else state<=idle;                                                               
  141.                                 WAIT1:                if(sclk_cnt==SCLK_CNT)
  142.                                                                 state<=WRITE;
  143.                                                         else        state<=WAIT1;
  144.                                 WRITE:                if(sclk_cnt==SCLK_CNT)
  145.                                                                 state<=WAIT2;
  146.                                                         else state<=WRITE;
  147.                                 WAIT2:                if(sclk_cnt==SCLK_CNT)
  148.                                                                 state<=WAIT3;
  149.                                                         else         state<=WAIT2;
  150.                                 WAIT3:                if(sclk_cnt==SCLK_CNT)
  151.                                                                 state<=WAIT4;
  152.                                                         else        state<=WAIT3;
  153.                                 WAIT4:                if(sclk_cnt==SCLK_CNT)
  154.                                                                 state<=SE;
  155.                                 SE:                        if(sclk_cnt==SCLK_CNT)
  156.                                                                 state<=INIT_ADDR;
  157.                                                         else state<=SE;
  158.                                 INIT_ADDR:        if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
  159.                                                                 state<=WAIT5;
  160.                                                                 else state<=INIT_ADDR;
  161.                                 WAIT5:                if(sclk_cnt==SCLK_CNT)
  162.                                                                 state<=WAIT_3S;
  163.                                                         else        state<=WAIT5;
  164.                                 WAIT_3S:        if(cnt_1s==ONE_S&&cnt_3s==2)
  165.                                                                         state<=WAIT1;
  166.                                                         else if(cnt_wait_3s==CNT_wait_3s)
  167.                                                                         state<=idle;
  168.                                 default:        state<=idle;
  169.                                 endcase

  170.                                                                
  171. always@(posedge        sclk or negedge rst_n)        //时钟传递
  172.                 if(!rst_n)               
  173.                   sck<=0;
  174.                  else if(state==WRITE &&cnt4==1)       
  175.                                  sck<=1;
  176.                  else if(state==WRITE&&cnt4==3)
  177.                                  sck<=0;
  178.                  else if (state==SE&&cnt4==1)       
  179.                                  sck<=1;
  180.                  else if(state==SE&&cnt4==3)
  181.                                  sck<=0;
  182.                  else if (state==INIT_ADDR&&cnt4==1)       
  183.                                  sck<=1;
  184.                  else if(state==INIT_ADDR&&cnt4==3)
  185.                                  sck<=0;
  186.                                 
  187. always@(posedge        sclk or negedge rst_n)        //低电平传输数据 上升沿采集数据
  188.                 if(!rst_n)
  189.                         sdi<=1'b1;
  190.                 else if(state==WRITE)       
  191.                         sdi<=wr_en[7-bit_cnt];
  192.                 else if(state==SE)       
  193.                         sdi<=se_en[7-bit_cnt];
  194.                 else if(state==INIT_ADDR&&cnt_init_addr==0)
  195.                         sdi<=init_addr[23-bit_cnt];
  196.                 else if(state==INIT_ADDR&&cnt_init_addr==1)
  197.                         sdi<=init_addr[15-bit_cnt];
  198.                 else if(state==INIT_ADDR&&cnt_init_addr==2)
  199.                         sdi<=init_addr[7-bit_cnt];
  200.                 else sdi<=1'b1;                                                        //检查发现有问题

  201. always@(posedge        sclk or negedge        rst_n)
  202.                         if(!rst_n)
  203.                                 led<=0;
  204.                 else if(cnt_3s_en==1)
  205.                                 led<=1;
  206.                 else        led<=0;

  207. endmodule


 楼主| gaochy1126 发表于 2022-3-31 22:58 | 显示全部楼层
5.需要说明的是擦除需要一个标志位,可以使用按键产生。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1205

主题

11937

帖子

26

粉丝
快速回复 在线客服 返回列表 返回顶部