MAX10片内User Flash的使用

一、Altera MAX10 FPGA片内Flash介绍

       MAX 10 FPGA 采用 TSMC 的 55 nm 嵌入式 NOR 闪存技术制造,并提供双配置CFM(Configration Flash Memery )和UFM(User Flash Memery)。配置灵活支持双配置,也支持CFM与UFM相互共享。不同型号的片子对应最大的UFM容量从Quartus软件里面即可找到:

       

       MAX10依然是SRAM结构,只是片内集成了Flash,因此加速了配置启动速度,减少了外设,从而简化了设计。既然是nor flash,那么也遵守普通nor的特点,写入慢,读取快。比eeprom多一步擦除过程

       你用或不用,它就在那。各位屌丝脑洞大开的时候到了,快想想读取快的Flash可以干些什么。我们要充分压榨max10的每一滴油水,就一定要搞定UFM。

 


二、MAX10 初体验——片内User Flash的使用

        1.在IP Catalog里面搜索flash,双击打开Altera On-Chip Flash,又打开了Qsys。看来Altera真是死磕nios了。不过不用担心,Avalon MM比起AXI简单的要命,下面简单的例子介绍后,看一下时序,想必很快就可以上手。

        

        本例为了体验片内Flash的并行速度,时钟频率设为100MHz,选择了并行数据接口,burst方式为递增,突发模式设置为最大128字节。FPGA配置方式选择单个非压缩镜像,这样做可以多释放一块Flash供我们使用。我们这次不玩IAP,且为了保护FPGA配置镜像不被意外损坏,将CFM设置为隐藏。初始化使用hex或mif文件,怎样创建都行。(逻辑本来就很简单,也懒得去仿真了,所以dat文件也就没有做。初始化文件本例用了个部分递增序列,用以检验代码的正确性)

       2.在生成HDL之前,我们还是先看一下IP核的接口,在右上侧点击block symbol,了解一下信号功能位宽及方向。

       

        其中data为Avalon MM的用户读写接口,crs为Avalon MM的控制接口。(我们只需要关注data接口即可完成正常读写工作)

       3.生成HDL

        生成HDL后,将生成的synthesis目录里面的qip文件添加到工程中。qip文件为索引文件,quartus将根据索引路径获取综合仿真所需的文件。

       4.程序源码:

 

查看原代码

  1. module ufm_test(

  2. input wire i_clk,

  3. input wire i_rst_n,

  4. output wire [31:0]readdata,

  5. output wire rdatavalid

  6. );

  7. wire clk50;

  8. wire rst;

  9. wire locked;

  10. reg [14:0]flash_raddr;

  11. wire waitrequest;

  12. pll u_pll (

  13. .areset (~i_rst_n),

  14. .inclk0 (i_clk),

  15. .c0 (clk100),

  16. .locked (locked)

  17. );

  18. assign rst = ~(i_rst_n & locked);

  19. //gen read address

  20. always@(posedge clk100 or posedge rst)

  21. if(rst)

  22. flash_raddr <= 15'd0;

  23. else if(waitrequest)

  24. flash_raddr <= flash_raddr;

  25. else if(flash_raddr == 15'd29184 - 15'd8)

  26. flash_raddr <= 15'd0;

  27. else

  28. flash_raddr <= flash_raddr + 15'd8;

  29. userflash u0 (

  30. .clock (clk100 ),// clk.clk

  31. .reset_n (~rst ),// nreset.reset_n

  32. //crs

  33. .avmm_csr_addr (1'b0 ),// csr.address

  34. .avmm_csr_read (1'b0 ),// .read

  35. .avmm_csr_writedata (32'd0 ),// .writedata

  36. .avmm_csr_write (1'b0 ),// .write

  37. .avmm_csr_readdata ( ),// .readdata

  38. //data

  39. .avmm_data_addr (flash_raddr),// data.address 15bit

  40. .avmm_data_read (1'b1 ),//.read always enable

  41. .avmm_data_writedata (32'd0 ),//.writedata 32bit

  42. .avmm_data_write (1'b0 ),//.write

  43. .avmm_data_readdata (readdata ),//.readdata 32bit

  44. .avmm_data_waitrequest (waitrequest),//.waitrequest

  45. .avmm_data_readdatavalid (rdatavalid ),//.readdatavalid

  46. .avmm_data_burstcount (8'd8 ) //.burstcount

  47. );

  48. endmodule

        5.下载pof

       由于sof文件包含的内容为sram结构的配置信息,不包含flash的内容,所以UFM初始化文件不会通过sof下载写入flash,所以需要将ufm信息包含到pof文件,并下载

       综合完毕后,打开Convert Programming File将sof转换为pof

        

         选择pof格式Mode选择Internal Configuration添加已经生成的sof文件先不要着急Generate,现在还添加UFM初始化文件。

       

        点击Options/Boot info按钮,UFM source选择Load memory file并添加自己定义的UFM的初始化文件。

        添加UFM初始化后再生成pof文件。此时的pof包含了用户逻辑与UFM的初始化信息,文件个头会稍微大一些。

       6.sinaltap抓数

       本例的工程将avalon的读取data相关的信号进行了抓取:

        

        上图触发时刻后为四组突发长度为8的读取模式,下图为其中一段的放大:

       从图中可以看出 当valid为高时,输出的读取数据按字节递增,说明读取过程正确无误。

       当前clk为100MHz,发起一个长度为8的突发读取需要22个clk,共读出了32个字节。由此可以算出当前的flash读取速率为每clk 1.45个字节,不得不说并行读取速率就是快。这么快的速率完全可以跟上程序的处理速度,用Max10不好好利用UFM,简直暴殄天物。


三、个人感受

       1.鉴于Altera On-Chip Memery是基于Qsys的IP核,可以看得出Altera在推广Avalon和Nios上的一贯作风。

       2.非集成Flash的FPGA,如cyclone4系列只能串行读写EPCS,来当做UFM使用,且总线速率不超过25MHz。MAX10的体验确实出乎意料,并行总线读取flash,那叫一个快。

       3.本文没有尝试写入,是因为nor flash的写入过程确实太慢,手册说擦除一个扇区就需要350ms。如果只是存一个用户参数,再写入之前先进行读取备份,然后再执行擦除操作,再执行写入操作。过程繁琐,且在寄存器中备份需要占用大量LE,也不划算。

       4.IAP过程也需要程序写入到相应的Flash,但是一个配置文件就将近1MBytes(本文的sof就有700多KB,pof有800多KB)。由于写入过程很慢,最好需要通过nios系统并外挂一个片外的RAM来缓存要写入的配置文件。尽管MAX10支持DDR3跑400M,但是需要消耗大量的逻辑来支持DDR,如果单独为了IAP而添加外部的RAM,有些得不偿失。建议IAP最好还是在不额外增加bom的时候使用。其他时候安心的用单个配置flash吧,其他的都划作UFM,想怎么用,就怎么用。

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用STM32的flash进行32位数据的读写时,可以参考如下的方法: 1. 首先,需要确保已经正确配置了flash的相关参数,包括flash的起始地址、扇区大小等。可以通过参考STM32的相关文档或者示例代码来进行配置。 2. 对于数据的写入,可以使用HAL库提供的相关函数。例如,可以使用HAL_FLASH_Unlock()函数来解锁flash,后使用HAL_FLASH_Program()函数来进行数据写入。需要注意的是,HAL_FLASH_Program()函数可以一次写入一个字(即32位数据),所以可以直接将32位的数据作为参数传入该函数。 3. 对于数据的读取,可以使用HAL库提供的相关函数。例如,可以使用HAL_FLASH_Program()函数来读取flash中的数据。需要注意的是,flash的读取是以字为单位进行的,所以需要将读取到的数据转换为32位的数据。 需要注意的是,在进行flash读写操作时,需要注意保护flash的擦除与写入操作的顺序,并且要避免在flash擦除和写入过程中进行其他操作,以防止数据的损坏。 总结起来,使用STM32的flash进行32位数据的读写可以通过以下步骤实现: 1. 配置flash的相关参数; 2. 使用HAL库提供的函数进行flash的解锁; 3. 使用HAL库提供的函数进行数据的写入或读取; 4. 如果需要,可以使用HAL库提供的函数进行flash的锁定。 参考文献: https://www.st.com/resource/en/application_note/cd00264379-getting-started-with-stm32f10xxx-hardware-development-stmicroelectronics.pdf https://www.st.com/resource/en/user_manual/cd00240193-getting-started-with-stm32f10xxx-hardware-development-stmicroelectronics.pdf<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [关于STM32的flash读写数据和HardFault_Handler的问题](https://download.csdn.net/download/weixin_38687539/12703186)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [STM32F103硬件I2C主机收发数据,亲测可用](https://download.csdn.net/download/m0_70861064/88218633)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值