SPI Flash 擦除

`timescale 1ns / 1ns



module flash_be(
sys_clk,
reset_n,
key_in,
spi_mosi,
spi_cs,
spi_sck
    );
   input sys_clk;
   input reset_n;
   input key_in;
   output reg spi_mosi;
   output reg spi_cs;
   output reg spi_sck;  
   
   parameter WR_EN_INST = 8'h06;
   parameter BE_INST = 8'hC7;
   
   parameter IDLE = 4'b0001;
   parameter WR_EN = 4'b0010;
   parameter DELAY = 4'b0100;
   parameter BE = 4'b1000;
   
   reg [3:0] state;
   reg [3:0] next_state;
   reg [2:0] byte_cnt;  //字节计数器
   reg [4:0] clk_cnt;   //系统计数器
   reg [1:0] sck_cnt;   //时钟计数器
   reg [2:0] bit_cnt;   //数据位计数器
   
   always@(posedge sys_clk or negedge reset_n)
     begin
       if(!reset_n)
         state<=IDLE;
       else 
         state<= next_state;
     end
   
   always@(*)
     begin 
        if(!reset_n)
          next_state = IDLE;
        else
          begin
            case(state)
               IDLE:
                 begin
                   if(key_in)
                    next_state = WR_EN;
                 else 
                    next_state = IDLE; 
                 end 
               WR_EN:
                 begin
                   if(byte_cnt==2&&clk_cnt==5'd31)
                    next_state = DELAY;
                 else 
                    next_state = WR_EN; 
                 end
               
               DELAY:
                 begin
                   if(byte_cnt==3&&clk_cnt==5'd31)
                    next_state = BE;
                 else 
                    next_state = DELAY; 
                 end
                 
               BE:
                 begin
                   if(byte_cnt==6&&clk_cnt==5'd31)
                    next_state = IDLE;
                 else 
                    next_state = BE; 
                 end                                                               
            endcase
          end        
     end
   
   //系统计数器
   always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
            clk_cnt<=0;
         else if(state!=IDLE)
            clk_cnt<=clk_cnt+1'b1;
         else clk_cnt<=0;
      end
   
   //字节计数器
    always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
            byte_cnt<=0;
         else if(byte_cnt==3'd6&&clk_cnt==5'd31)
            byte_cnt<=0;
         else if(clk_cnt==5'd31)
            byte_cnt<=byte_cnt+1'b1;
         else
            byte_cnt<=byte_cnt;
      end  
   
   // 时钟计数器   
   always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
           sck_cnt<=0;
         else if(state==WR_EN && byte_cnt==3'd1)
           sck_cnt<=sck_cnt+1'b1;
         else if(state==BE && byte_cnt==3'd5)
           sck_cnt<=sck_cnt+1'b1; 
      end
    
   // 数据位计数器
   always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
           bit_cnt<=0;
         else if(bit_cnt==7&&sck_cnt==1)
           bit_cnt<=0;
         else if(sck_cnt==1)
           bit_cnt<= bit_cnt+1'b1;
         else bit_cnt<=bit_cnt;
      end
  
   //cs信号控制
     always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
            spi_cs<=1;
         else if(state==WR_EN)
            spi_cs<=0; 
         else if(state==DELAY)
            spi_cs<=1;
         else if(state==BE)
            spi_cs<=0;
         else 
            spi_cs<=1;  
      end  
      
    //时钟生成
     always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
            spi_sck<=0;
         else if(sck_cnt==1)
            spi_sck<=1;
         else if(sck_cnt==3)
            spi_sck<=0;
         else  spi_sck<=spi_sck;         
      end 
      
      //MOSI数据输出
   always@(posedge sys_clk or negedge reset_n)
      begin
         if(!reset_n)
           spi_mosi<=0;
         else if(byte_cnt==3'd1&&clk_cnt==5'd31)
           spi_mosi<=0;
         else if(byte_cnt==3'd5&&clk_cnt==5'd31)
           spi_mosi<=0;
         else if(byte_cnt==3'd1&&sck_cnt==2'd0)
           spi_mosi<=WR_EN_INST[7-bit_cnt];
        else if(byte_cnt==3'd5&&sck_cnt==2'd0)
           spi_mosi<=BE_INST[7-bit_cnt];
         else
          spi_mosi<= spi_mosi;
      end
      
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值