FPGA project : flash_secter_erase

这篇具有很好参考价值的文章主要介绍了FPGA project : flash_secter_erase。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

flash的指定扇区擦除实验。

先发写指令,再进入写锁存周期等待500ns,进入写扇区擦除指令,然后写扇区地址,页地址,字节地址。即可完成扇区擦除。

模块框图:

flash_sectors_erase,野火征途pro,fpga开发

时序图: 

flash_sectors_erase,野火征途pro,fpga开发

flash_sectors_erase,野火征途pro,fpga开发

代码: 

module spi (
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   , 
    input       wire            key_start   ,

    output      wire            miso        ,
    output      reg             mosi        ,
    output      reg             cs_n        ,
    output      reg             sck 
);
    // parameter 
    parameter   COMD_W  = 8'h06   , // 写指令
                COMD_B  = 8'hc7   , // 全擦除指令
                COMD_S  = 8'hd8   ; // 扇区擦除指令
    parameter   ADR_SE  = 8'h00   , // 扇区地址 adress secter
                ADR_PA  = 8'h04   , // 页地址   adress page
                ADR_BY  = 8'h25   ; // 字节地址 adress byte
    parameter   IDLE    = 4'b0001 ,
                WREN    = 4'b0010 ,
                WEL     = 4'b0100 ,
                SE      = 4'b1000 ;
    // wire signal degine
    wire                IDLEtoWREN; 
    wire                WRENtoWEL ;  
    wire                WRENtoSE  ;   
    wire                SEtoIDLE  ;   
    // reg signal define
    reg     [3:0]       state_c   ;
    reg     [3:0]       state_n   ;
    reg     [3:0]       cnt_20ns  ;
    reg     [3:0]       cnt_bit   ;
    reg     [3:0]       cnt_byte  ;
    reg                 flag_bit  ;
    reg                 f_b_reg   ; // flag_bit_reg的缩写
/****************************************************************************/
    // 三段式状态机
    // 现态与次态描述
    // state_c
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            state_c <= IDLE ;
        else
            state_c <= state_n ;
    end
    // state_n
    always @(*) begin
        case (state_c)
        IDLE   :if(IDLEtoWREN)
                    state_n <= WREN ;
                else 
                    state_n <= IDLE ;
        WREN   :if(WRENtoWEL)
                    state_n <= WEL  ;
                else 
                    state_n <= WREN ;
        WEL    :if(WRENtoSE)
                    state_n <= SE   ;
                else 
                    state_n <= WEL  ;
        SE     :if(SEtoIDLE)
                    state_n <= IDLE ;
                else 
                    state_n <= SE   ;
        default:    state_n <= IDLE ;
        endcase
    end
    // 状态转移描述
    assign  IDLEtoWREN  = ( state_c == IDLE) && ( key_start     ) ;
    assign  WRENtoWEL   = ( state_c == WREN) && ( f_b_reg       ) ;
    assign  WRENtoSE    = ( state_c == WEL ) && ( cnt_20ns == 6 ) ;
    assign  SEtoIDLE    = ( state_c == SE  ) && ( f_b_reg       ) ;
    // 相关信号描述
    // reg     [3:0]       cnt_20ns  ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_20ns <= 4'd0 ;
        else 
        case (state_c)
        IDLE :  cnt_20ns <= 4'd0 ;
        WREN :  if(cnt_20ns || f_b_reg)
                    cnt_20ns <= 4'd0 ;
                else 
                    cnt_20ns <= cnt_20ns + 1'b1 ;
        WEL  :  if(cnt_20ns == 6) // 60x20ns==120ns
                    cnt_20ns <= 4'd0 ;
                else
                    cnt_20ns <= cnt_20ns + 1'b1 ;
        SE   :    if(cnt_20ns || f_b_reg)
                    cnt_20ns <= 4'd0 ;
                else 
                    cnt_20ns <= cnt_20ns + 1'b1 ;
        default:    cnt_20ns <= 4'd0 ;
        endcase
    end
    // reg     [3:0]       cnt_bit   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n)
            cnt_bit <= 4'd0 ;
        else 
        case (state_c)
        IDLE :  cnt_bit <= 4'd0 ;
        WREN :  if(!cnt_20ns && sck && cnt_bit == 7)
                    cnt_bit <= 4'd0 ;
                else if(!cnt_20ns && sck)
                    cnt_bit <= cnt_bit + 1'b1 ;
        WEL  :  cnt_bit <= 4'd0 ;
        SE   :  if(!cnt_20ns && sck && cnt_bit == 7)
                    cnt_bit <= 4'd0 ;
                else if(!cnt_20ns && sck)
                    cnt_bit <= cnt_bit + 1'b1 ;
        default:    cnt_bit <= 4'd0 ;
        endcase
    end
    // reg      [3:0]       cnt_byte
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_byte <= 4'd0 ;
        else if(cnt_bit == 7 && !cnt_20ns && sck && cnt_byte == 4)
            cnt_byte <= 4'd0 ;
        else if(cnt_bit == 7 && !cnt_20ns && sck)
            cnt_byte <= cnt_byte + 1'b1 ;
        else 
            cnt_byte <= cnt_byte ;
    end
    // reg                 flag_bit  ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            flag_bit <= 1'b0 ;
        else
        case (state_c)
        IDLE :  flag_bit <= 1'b0 ;
        WREN :  if(cnt_bit == 7 && sck && !cnt_20ns)
                    flag_bit <= 1'b1 ;
                else 
                    flag_bit <= flag_bit ;
        WEL  :  flag_bit <= 1'b0 ;
        SE   :  if(cnt_bit == 7 && sck && !cnt_20ns && cnt_byte == 4)
                    flag_bit <= 1'b1 ;
                else 
                    flag_bit <= flag_bit ;
        default: flag_bit <= 1'b0 ;
        endcase
    end
    // reg                 f_b_reg   ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            f_b_reg <= 1'b0 ;
        end else begin
            f_b_reg <= flag_bit ;
        end
    end
    // output signal
    // wire            miso        ,
    assign miso = 1'bz ;
    // mosi
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n)
            mosi <= 1'b0 ;
        else
        case (state_c)
        IDLE :  mosi <= 1'b0 ;
        WREN :  if(!cnt_bit) // (cnt_bit == 0)
                    mosi <= COMD_W[7] ;
                else if(cnt_20ns && sck)
                    mosi <= COMD_W[7 - cnt_bit] ;
                else 
                    mosi <= mosi ;
        WEL  :  mosi <= 1'b0 ;
        SE   :  case (cnt_byte)
                    1:  
                        begin
                            if(!cnt_bit)
                                mosi <= COMD_S[7] ;
                            else if(cnt_20ns && sck)
                                mosi <= COMD_S[7 - cnt_bit] ;
                            else 
                                mosi <= mosi ;  
                        end
                    2:  
                        begin
                            if(!cnt_bit)
                                mosi <= ADR_SE[7] ;
                            else if(cnt_20ns && sck)
                                mosi <= ADR_SE[7 - cnt_bit] ;
                            else 
                                mosi <= mosi ;  
                        end
                    3:  
                        begin
                            if(!cnt_bit)
                                mosi <= ADR_PA[7] ;
                            else if(cnt_20ns && sck)
                                mosi <= ADR_PA[7 - cnt_bit] ;
                            else 
                                mosi <= mosi ;  
                        end
                    4:  
                        begin
                            if(!cnt_bit)
                                mosi <= ADR_BY[7] ;
                            else if(cnt_20ns && sck)
                                mosi <= ADR_BY[7 - cnt_bit] ;
                            else 
                                mosi <= mosi ;  
                        end
                default:        mosi <= 1'b0 ;
                endcase
        default:    mosi <= 1'b0 ;
        endcase
    end
    // reg             cs_n        ,
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cs_n <= 1'b1 ;
        end else begin
            case (state_c)
            IDLE :  if(key_start)
                        cs_n <= 1'b0 ;
                    else 
                        cs_n <= 1'b1 ;
            WREN :  if(f_b_reg)
                        cs_n <= 1'b1 ;
                    else 
                        cs_n <= cs_n ;
            WEL  :  if(cnt_20ns == 6) 
                        cs_n <= 1'b0 ;
                    else 
                        cs_n <= cs_n ;
            SE   :  if(f_b_reg)
                        cs_n <= 1'b1 ;
                    else 
                        cs_n <= cs_n ;
            default:    cs_n <= 1'b1 ;
            endcase
        end
    end
    // reg             sck 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n)
            sck <= 1'b0 ;
        else 
        case (state_c)
        IDLE :  sck <= 1'b0 ;
        WREN :  if(cnt_20ns)
                    sck <= ~sck ;
                else 
                    sck <= sck  ;
        WEL  :  sck <= 1'b0 ;
        SE   :  if(cnt_20ns)
                    sck <= ~sck ;
                else 
                    sck <= sck  ;
        default:    sck <= 1'b0 ;
        endcase
    end

endmodule
module top(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            key_in      ,

    output      wire            cs_n        ,
    output      wire            sck         ,
    output      wire            mosi        
);
    // 例化间连线
    wire            key_flag ;

key_filter key_filter_inst(
    .sys_clk                    ( sys_clk   ) ,
    .sys_rst_n                  ( sys_rst_n ) ,
    .key_in                     ( key_in    ) ,

    .key_out                    ( key_flag  )     
);

spi spi_inst(
    .sys_clk                    ( sys_clk   ) ,
    .sys_rst_n                  ( sys_rst_n ) ,
    .key_start                  ( key_flag  ) ,

    .mosi                       ( mosi      ) ,
    .miso                       (           ) ,
    .cs_n                       ( cs_n      ) ,
    .sck                        ( sck       )
);endmodule
module key_filter
#(
    parameter MAX_CNT_20MS = 20'd100_0000 
)(
    input           wire    sys_clk     ,
    input           wire    sys_rst_n   ,
    input           wire    key_in      ,

    output          wire    key_out     
);

    reg     key_r_0 ;
    reg     key_r_1 ;
    wire    nege    ;
    wire    pose    ;

    reg     [19:00]     cnt_20ms     ;
    wire                add_cnt_20ms ;
    wire                end_cnt_20ms ;
    reg                 add_cnt_flag ;

    // key_r_0 key_r_1 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            key_r_0 <= 1'b1 ;
        end else begin
            key_r_0 <= key_in ;
        end
    end
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            key_r_1 <= 1'b1 ;
        end else begin
            key_r_1 <= key_r_0 ;
        end
    end

    // nege pose
    assign nege = ~key_r_0 &&  key_r_1 ;
    assign pose =  key_r_0 && ~key_r_1 ;

    // add_cnt_flag
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            add_cnt_flag <= 1'b0 ;
        end else begin
            if(nege) begin
                add_cnt_flag <= 1'b1 ;
            end else begin
                if( pose || end_cnt_20ms ) begin
                    add_cnt_flag <= 1'b0 ;
                end else begin
                    add_cnt_flag <= add_cnt_flag ;
                end
            end 
        end
    end

    // cnt_20ms add_cnt_20ms end_cnt_20ms
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_20ms <= 20'd0 ;
        end else begin
            if(add_cnt_20ms) begin
                if(end_cnt_20ms) begin
                    cnt_20ms <= 20'd0 ;
                end else begin
                    cnt_20ms <= cnt_20ms + 20'd1 ;
                end
            end else begin
                cnt_20ms <= 20'd0 ;
            end
        end
    end
    assign add_cnt_20ms = add_cnt_flag ;
    assign end_cnt_20ms = add_cnt_20ms && cnt_20ms == ( MAX_CNT_20MS - 1'b1 ) ;

    // key_out
    // always @(posedge sys_clk or negedge sys_rst_n) begin
    // // always @(*) begin // 这样的话 会综合成 数据选择器
    //     if(~sys_rst_n) begin
    //         key_out <= 1'b0 ;
    //     end else begin
    //         if(end_cnt_20ms) begin
    //             key_out <= 1'b1 ;
    //         end else begin
    //             key_out <= 1'b0 ;
    //         end
    //     end
    // end
    assign key_out = end_cnt_20ms ;
endmodule

 仿真图:忘记截屏了。

需要用到仿真模型。

上版验证通过。文章来源地址https://www.toymoban.com/news/detail-771794.html

到了这里,关于FPGA project : flash_secter_erase的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA使用SPI控制FLASH

    通过控制FLASH芯片进一步熟悉SPI协议 Flash 存储器 : Flash 存储器是一种非易失性存储器,它具有 RAM 和 ROM 的一些特点。与 ROM 类似,Flash 存储器的内容在断电时不会丢失,但与 RAM 类似,它可以通过编程来修改存储的内容。Flash 存储器通常用于嵌入式系统中存储程序代码、配置

    2024年03月19日
    浏览(54)
  • 提高Xilinx FPGA Flash下载速度

    最近在编写完FPGA逻辑,成功生成.bin文件后,可以通过Vivado软件进行设置,提高烧写速度。操作如下: (1)布局布线完成后,点击Open Implementation。 (2)点击Tool----- Edit Device Properties... (3)General -----Enable Bitstream Compression -----TRUE,选择压缩数据流,提高下载速度。 (4)Co

    2024年02月03日
    浏览(59)
  • FPGA 如何 固化程序到 FLASH中

    1、导出Hardware 2、导出bit文件 3、打开SDK 4、 点击Ok 5、创建工程 6、 输入工程名称:guhua 7、选择 Zynq FSBL 8、单击 guhua、然后点击 build 点击:build all 9、 右键之后,点击:Creat Boot Image 10、点击 Create Image 、创建 BOOT.BIN 11、关掉SDK之后;将板子的拨码开关 下拨; 白色代表拨码;

    2024年02月06日
    浏览(47)
  • FPGA模块——SPI协议(读写FLASH)

    芯片引脚图: 内部结构图: 存储区域总共分成了32块,每块64KB。每块又分成了16个部分,每个部分4KB。方便进行读取和局部操作。 电路设计 SPI的四种模式 这里使用这个模式: 主机和从机在时钟上升沿放入要输出的数据,在时钟下降沿读取要输入的数据。 8个时钟后交换一个

    2024年02月05日
    浏览(47)
  • 基于FPGA 外置qspi Flash的读写

    1.写在前面 FPGA内部不具有掉电存储程序的功能,所以都需要外置的flash存储器来存储程序,上电后从flash加载程序到FPGA中运行。外置的flash可以存储程序,也可以存储任何用户数据,可以更有效的利用flash的存储空间。 值得注意的是,用于存储程序的flash和fpga连接用的是fpga的

    2024年02月12日
    浏览(49)
  • Xilinx FPGA固化QSPI FLash程序

    本文以流水灯代码为例,需要已经成功生成bitstream文件。 FPGA型号:X7A200T,板载FLASH型号:MT25QL128,开发环境:Vivado 2020.2。 注意需要根据实际情况,选择自己板载的FLASH芯片。 首先,点击 进度条跑完后显示生成成功,点击OK即可。 然后在FPGA芯片处右击,选择“Add Configurati

    2024年02月15日
    浏览(45)
  • FPGA VIVADO 实现FLASH固化操作步骤

    2.1  按顺序选择ToolsGenerate Memory Configuration File    2.2 生成MCS  2.3 对选择的spi总线进行约束 默认是spi x1,如果在上一步选择了其他的模式,可以直接在xdc文件中直接添加约束语句(举例spi x4如下:选择了其他spi总线只需更改第五句代码中的总线数。 或者直接在vivado中选择  

    2024年02月05日
    浏览(50)
  • FPGA vitis实现固化程序到flash

    之前有实现PL端的数据固化,仅对A、K系列的板子有效。需要的可以参考 FPGA VIVADO 实现FLASH固化操作步骤_fpga固化程序-CSDN博客 再者ZYNQ的开发板上一般都是要通过SDK固化的,所以本期讲解一下vitis怎么固化程序。 由于ZYNQ有好几种固化方式,我们先讲一下最简单的固化到flash,以

    2024年04月10日
    浏览(43)
  • FPGA project : IIC_wr_eeprom

    简单双向二线制,同步串行总线。 scl:串行时钟线,用于同步通讯数据。 sda:双向串行数据线。 1,支持挂载多设备。 2,二线制。 3,每个设备有其单独的地址。 4,空闲时,sda会被上拉电阻拉高。 5,存在多个主机时,通过仲裁逻辑决定那个主机控制总线。 6,三个速度模

    2024年02月08日
    浏览(47)
  • FPGA project : dht11 温湿度传感器

    没有硬件,过几天上板测试。        其他模块都是之前的,就不发了。    

    2024年02月08日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包