ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Microblaze读写QSPI Flash性能优化:从2.2MB/s到11MB/s的实战指南

Microblaze读写QSPI Flash性能优化:从2.2MB/s到11MB/s的实战指南 NEXYS A7这块板子在学生项目和小型科研验证里几乎是“标配”Artix-7的资源对Microblaze软核来说相当宽裕跑一个带Cache的处理器加各种外设都不吃力。但很多人第一次在上面用Microblaze操作板载QSPI Flash时都会皱眉往Flash里写几百KB数据能等到人发困读取看起来还行可一旦数据量大、地址不连续吞吐就掉得离谱。这次的实战项目就是围绕这个问题展开的——把NEXYS A7开发板Xilinx Artix-7上Microblaze核访问板载FLASH的读写性能从“能用”优化到“尽可能快”并顺带把固化流程、启动时间一起捋顺。如果你刚好在用Vivado/Vitis搭Microblaze或者正被Flash下载失败、固化后不启动这类问题卡住这篇文章的思路和代码可以直接抄作业。我会把性能瓶颈拆开讲清楚再给出一套从IP配置、时钟调优、DMA搬运到XIP模式逐层递进的优化方案连踩坑记录也一并附上。1. 项目概述为什么软核读写Flash会卡成瓶颈1.1 这块板子上的Flash与Microblaze分工NEXYS A7板载一颗Spansion/Infineon S25FL128S容量128Mb16MB走的就是标准SPI/QSPI接口。它同时承担两件事一是作为FPGA的配置存储器上电时把bitstream从Flash加载进Artix-7二是在Microblaze启动后作为应用程序和数据的非易失存储介质。这意味着Flash的访问路径不是专属于你的逻辑的——它挂在FPGA的专用配置引脚上和系统启动强相关。Microblaze想读它需要通过AXI Quad SPI控制器想在掉电后继续运行程序也得靠它。这个双重身份决定了你优化Flash读写时必须清楚自己在动哪一块区域否则一不小心把配置文件覆盖掉板子就会“变砖”严格说是配置失效得重新烧录。1.2 优化前必须明确的三个性能指标做性能优化第一件事不是改代码而是先把指标定义清楚。我当时给自己定了三个可量化目标读吞吐连续读1MB数据统计从Flash到内存的有效带宽单位MB/s。写吞吐写入256KB数据包含必要的擦除等待统计整段的平均写速度。启动时间DONE信号拉高后从SPI Flash加载配置和应用程序到Microblaze开始执行main函数的总耗时。这三个指标看起来独立实际会互相影响。程序固化在Flash里启动时就等于做一次“巨额读取”读得快启动自然快而写Flash时页编程和擦除是物理上绕不开的慢操作优化空间和数据组织方式强相关。先把指标立住后面每次改动才有对照。2. 瓶颈分析你的时间到底花在哪了2.1 从SPI总线到Flash制造工艺先排一排链路要优化性能先得知道一条读写请求从CPU发出到数据落地中间经过哪些环节。Microblaze往Flash写一个字节数据流大致是CPU执行写寄存器的指令 → AXI总线传输 → AXI Quad SPI控制器内部的发送FIFO → SPI移位寄存器逐位输出 → Flash芯片内部完成页编程。读则是反方向但多一个“发命令、发地址、等Dummy周期、数据逐位返回”的过程。这条链路里每一级都可能成为瓶颈AXI总线频率如果AXI时钟只有50MHz32位数据总线每次传输至少一拍理论上限就是200MB/s看似足够但实际AXI交易有延迟、有等待周期尤其是Lite接口的握手开销不小。SPI时钟频率这是最直观的限制。QSPI工作在标准SPI模式时一位一位传50MHz下理论峰值只有6.25MB/s切到Quad模式后四线并行同样50MHz时钟下理论峰值到25MB/s。Flash内部操作时间读命令有Dummy周期和输出延迟页编程一条命令最多写256字节之后还要等芯片把数据写进存储阵列这个时间在毫秒级。软件搬运开销如果每次读写都由CPU在中断里搬数据再加上循环判断状态位实际吞吐往往会比总线理论值再打对折。我最初跑基准测试时用默认的AXI Quad SPI配置、轮询方式、标准SPI模式连续读1MB大约耗时450ms算下来2.2MB/s写入256KB更是花了6秒多因为每次页编程都同步等待WIP位清0再加上每512KB/64KB区段的擦除等待整个流程慢得让人怀疑人生。2.2 实测现状轮询方式到底能跑多快写一个简单的性能测试程序并不复杂关键在于分别测“纯总线传输时间”和“包含Flash内部等待的总时间”。我用Xilinx的XSpi驱动直接操作SPI控制器读的时候发一个Read命令然后连续读数据写的时候发Page Program命令然后死等状态寄存器的WIP位。这也是很多入门教程的写法代码简单、逻辑直白但性能确实一般。实测数据如下SPI时钟配置为50MHzAXI时钟100MHz操作模式实测速度备注连续读1MBStandard SPI约2.2 MB/s命令/地址/dummy开销占比高连续读1MBQuad Output Fast Read约6.8 MB/s数据线4位并行但dummy周期仍拖慢写256KB含擦除Page Program约35 KB/s受页编程等待时间和擦除时间拖累固化后启动-约800ms其中Flash读取bitstream占了大头这个结果说明了三件事第一标准SPI模式读确实浪费带宽Quad模式必须开第二写性能的主要瓶颈在Flash内部编程/擦除时间而不是SPI线速第三软件轮询带来的额外开销同样不可忽视需要把CPU从逐字节搬运中解放出来。2.3 优化策略从SPI协议、控制器配置与数据搬运三层下手既然明确了瓶颈是“线速未用满、CPU搬运低效、Flash内部等待无法消除只能规避”优化策略自然分成三层协议层把标准SPI读写命令换成Quad命令让四根数据线全部参与传输读性能立刻翻倍。工程配置层调整AXI Quad SPI IP的FIFO深度、参考时钟频率、AXI数据位宽让控制器本身不要成为瓶颈。架构层使用DMA做数据搬运减少CPU介入对于适合只读的场景直接把QSPI控制器配成AXI4内存映射模式XIP让Microblaze像访问内存一样读Flash这是读性能最彻底的提升方案。每一层优化都建立在前面一步的基础上。物理线速没跑满时上DMA也只是把慢速的SPI数据流搬到更快的地方治标不治本。3. 工具链与硬件准备NEXYS A7环境速写3.1 板载Flash颗粒与引脚连接NEXYS A7-100T的核心芯片是XC7A100T-1CSG324C板载Flash挂在一组专用引脚上原理图里的网络名一般是FLASH_CS、FLASK_SCK、FLASH_DQ0~DQ3。这颗S25FL128S支持Standard SPI、Dual SPI和Quad SPI命令集兼容主流QSPI Flash。提一个很多新手容易忽略的点Flash的IO电压和FPGA Bank电压必须匹配。NEXYS A7上这部分工作在3.3V所以你配置引脚约束时不要随意改IO Standard否则轻则读写异常重则损坏器件。3.2 Vivado/Vitis环境与Microblaze工程搭建要点我用的工具链是Vivado 2024.2 Vitis 2024.2。新版的Vitis把嵌入式开发整合进了统一IDE流程稍微变了一些但核心思路没变Vivado里搭硬件、导出XSA再到Vitis里建平台和应用工程。搭建Microblaze系统时我的习惯是先在Vivado里加一个Clocking Wizard把板载12MHz晶振转出三路时钟100MHz作为Microblaze和AXI总线时钟200MHz留给DDR如果用DDR的话50MHz作为QSPI的参考时钟。这里有个原则SPI参考时钟不要直接用AXI 100MHz因为SPI控制器的分频比是固定几个档位参考时钟太高反而难以得到合适的SPI频率而且跨时钟域的数据同步也会引入不确定性。Microblaze本身我建议打开指令Cache和数据Cache。对Flash性能测试来说Cache可能会“掩盖”一部分真实Flash读速度但实际应用就是靠Cache扛性能的所以打开更贴近真实场景。另外Microblaze的本地存储器大小要够放测试代码和数据缓冲我一般给64KB以上。3.3 把工程从“能跑”改成“方便做性能分析”默认生成的Microblaze工程如果只是拿来点个灯、打印串口完全没问题。但要做性能分析需要提前做三件事第一串口打印务必加时间戳。Microblaze没有内置高精度计时器但有一个AXI Timer把它配成64位周期计数频率设为CPU时钟就能精确测出每段代码的时钟周期数。用这个做性能基准比用秒表按手机靠谱得多。第二测试数据和目标地址要避开程序本身使用的区域。如果你要从Flash读数据到DDR或者往Flash写数据务必分清楚哪个地址段是bitstream、哪个是应用代码、哪个是数据区。我的习惯是bitstream放在Flash最前面应用代码紧随其后数据区单独划一个偏移段。数据区的读测试只访问数据区写测试也只写数据区。第三把“擦除”和“编程”拆开计时。很多人只测一个总的写时间发现瓶颈后不知道是擦除慢还是编程慢。我的做法是分别写3个函数整扇区擦除、单页编程、擦除编程连续操作分别计时这样才能定位到具体是哪一步慢。4. 第一层优化AXI Quad SPI IP配置与时钟调优4.1 IP配置表Standard/Quad/Quad IO模式怎么选在Vivado里添加AXI Quad SPI IP时配置界面有几个关键项直接决定你能用什么命令配置项可选项推荐值理由Interface TypeAXI4-Lite / AXI4Memory-Mapped先选AXI4-Lite做基准AXI4-Lite寄存器访问简单适合先跑通SPI ModeStandard / Dual / QuadQuad四线同时收发基础带宽翻倍Data Width2/4/8/16/3232与AXI总线位宽对齐减少读写寄存器次数FIFO Depth16/32/64/128/256256减少CPU等待FIFO的空满频繁切换XIP ModeEnable/Disable按需后续章节展开XIP模式用于存配置、字库等只读场景Flash Model厂商下拉框Spansion S25FL128S驱动初始化时序更匹配这里要特别解释Mode选择。很多教程让选Quad SPI指的是数据线四根全部用于读写但如果你继续用Read命令0x03数据仍然是一位一位回的Quad只是修改了写命令的传输格式。真正让读速度翻倍的是“Quad Output Fast Read”0x6B或“Quad I/O Fast Read”0xEB这类命令。IP配置里的Quad模式更多是告诉控制器“你的Flash支持四线操作驱动层可以用对应命令”。4.2 时钟树设计AXI频率和SPI参考时钟的关系SPI控制器的内部架构里SPI时钟由参考时钟分频得到。参考时钟越高能选的高SPI频率档位越多但也不是越高越好。AXI Quad SPI IP的数据手册里有个约束参考时钟和SPI时钟的比例必须在某个范围内确保发送FIFO的数据能及时补上。如果比例不合适SPI高速模式下FIFO会空转白白浪费带宽。我实测下来的一组稳定组合是AXI时钟100MHzQSPI参考时钟50MHzSPI时钟设为参考时钟的半分频即25MHz或者干脆让SPI时钟等于50MHz如果参考时钟和SPI时钟比例允许。S25FL128S在Quad模式下跑到50MHz很稳定再高也不是不行但板级信号质量开始吃紧尤其要注意DQ线之间的串扰。对于追求稳定的项目50MHz是一个性价比很高的点。4.3 实测对比只改配置不改代码性能变化当我把AXI Quad SPI IP从默认配置调整为Quad模式、32位数据宽度、256深度FIFO并且SPI时钟设为50MHz后其他代码一字未动重新跑基准测试采用Quad Output Fast Read0x6B命令连续读1MB速度从2.2MB/s升到6.8MB/s。采用Quad Page Program命令写数据配合更长的FIFO写速度从35KB/s提到48KB/s。读性能提升明显写性能提升有限原因还是擦除和页编程等待占据了大量时间。这一轮优化几乎不费吹灰之力纯粹是把控制器配置用对。但它也暴露了一个问题CPU在循环里不断读写FIFO这种“搬运工”工作占用了大量执行周期SPI再快也会被CPU的轮询节奏拖累。于是下一步开始动数据搬运架构。5. 第二层优化DMA搬运、缓存一致性与写入策略5.1 用AXI DMA把CPU从数据搬运中解放出来如果QSPI控制器是AXI4-Lite接口数据搬运是典型的“CPU读寄存器→写寄存器”流程效率确实低。更合理的做法是在系统里加一个AXI DMA让DMA直接搬数据。这里要说明一下AXI DMA本质是“内存到内存”或“内存到外设”的搬运器和SPI控制器配合时通常的做法是CPU配置好DMA的源地址、目的地址和长度DMA负责把数据从内存搬到SPI控制器发送FIFO或者从SPI控制器接收FIFO搬到内存。我用的结构是Microblaze的AXI接口分别连接AXI DMA的控制寄存器和AXI Quad SPIDMA的MM2SMemory to Stream和S2MMStream to Memory通道再通过AXI Stream接到SPI控制器的数据接口。注意这个场景下QSPI IP一般要选择AXI4Memory-Mapped接口类型因为它要能响应来自DMA的读请求。驱动层的调用也简单#include xaxidma.h #include xil_cache.h XAxiDma dma; // 配置DMA源地址srcAddr目的地址dstAddr长度len // 发送前刷新数据缓存确保DMA看到的不是陈旧数据 Xil_DCacheFlushRange((UINTPTR)srcAddr, len); XDma_SimpleTransfer(dma, (UINTPTR)srcAddr, len, XDMA_MM2S_CHANNEL); XDma_SimpleTransfer(dma, (UINTPTR)dstAddr, len, XDMA_S2MM_CHANNEL); // 等待DMA完成 while (!XDma_IsS2mmIdle(dma)); // 接收后使无效防止CPU读到缓存的旧值 Xil_DCacheInvalidateRange((UINTPTR)dstAddr, len);这段代码是我在实际项目里的核心骨架。第一次跑的时候我忽略了两行Cache操作结果数据错乱后面会专门讲这个坑。5.2 Microblaze数据缓存的坑为什么偶尔读到旧数据Microblaze开启数据Cache后CPU读内存会先查Cache写内存也会经过Cache。这本来是为了加速但如果DMA直接读写内存CPU和DMA之间就存在“看到的数据不一致”的问题。具体场景是CPU把数据写好放在内存里然后让DMA把这段数据搬到SPI控制器。如果数据还在CPU的Cache里没有回写到内存DMA实际搬运的可能是旧数据Flash里写进去的自然就是乱的。反过来DMA从内存某地址读了一段数据放好CPU再去读这个地址时可能命中Cache里的旧内容而不是DMA刚写入的新数据于是你读回来的Flash数据永远是上一轮的。解决办法就是前面代码里的两个APIDMA发送前用Xil_DCacheFlushRange确保数据落回内存DMA接收完成后用Xil_DCacheInvalidateRange让Cache失效强制从内存重新加载。这是嵌入式系统里DMA和Cache共存的通用准则不只MicroblazeZynq、RISC-V软核都一样一定要记住。5.3 写入性能优化页编程、擦除调度与减少命令开销Flash写入慢很大一部分“慢”来自Flash内部操作时间。S25FL128S的页编程一次最多256字节典型编程时间在毫秒级擦除按扇区4KB或块64KB进行一次扇区擦除典型时间数百毫秒。这是物理特性没法消除但可以通过策略优化第一数据尽量按扇区边界对齐减少跨扇区擦除次数。如果一个扇区只写了几百字节下次写另一个区域又要整扇区擦除白白浪费大量时间。第二把“擦除”和“编程”流水化。不要擦一个扇区写一个扇区同步等待到天荒地老可以维护一个工作队列先擦除多个扇区再连续编程。虽然Flash芯片不支持擦写并行但软件层面可以减少命令切换和状态轮询的开销。第三页编程命令本身尽量用Quad Page Program。S25FL128S支持0x32/0x34这类Quad写命令同样是四线并行传输虽然页编程的等待时间不变但命令和数据的传输时间大幅缩短。如果总数据量大这个节省很可观。优化后的写流程是先发Write Enable0x06再发Quad Page Program命令、3字节地址、最多256字节数据然后轮询状态寄存器等WIP位清0。这里有一个很实用的检查点在编程之前先读一次状态寄存器确认上一条命令已经完成如果前一条命令还在进行中新命令会被Flash忽略导致“写失败但代码不报错”的隐藏问题。6. 第三层优化XIP模式让Flash变成内存映射设备6.1 XIP的工作原理与适用场景XIPExecute In Place不是一个新概念但在Softcore系统里很多人没用过。它的核心是把AXI Quad SPI控制器配置为AXI4 Memory-Mapped接口控制器会把Flash映射到一段连续的AXI地址空间CPU直接通过普通的Load指令读这段地址硬件自动帮你发Fast Read命令、处理Dummy周期、返回数据。这意味着读Flash不再需要你手动发起SPI传输、等FIFO、读数据寄存器而是像读内存一样自然。配合Microblaze的数据Cache重复访问某些数据时甚至会直接命中Cache性能提升非常明显。XIP模式最适合的场景是字库、配置表、启动代码、查表数据等只读内容。我项目里把一套开机自检配置表放进了Flash映射区Microblaze启动后不经过任何驱动直接用指针访问读性能几乎追平AXI内存读。6.2 在AXI Quad SPI中开启XIP及代码切换在Vivado里启用XIP主要动作是把AXI Quad SPI IP的Interface Type选成AXI4Memory-Mapped并勾上Enable XIP。生成的地址映射里会多出一段例如0x80000000开头的区域这就是Flash在总线上的“透明访问窗口”。不过要注意XIP模式并不是所有Flash命令都能自动处理它通常固化使用Fast Read类型的读命令。如果需要写Flash建议先把控制器切回普通模式或者通过另一段寄存器接口发送Page Program命令。我在驱动里做了两层抽象普通模式负责擦除和编程XIP模式负责高速读取。二者通过同一把片选和命令逻辑切换互不干扰。一个容易踩的坑XIP模式下如果Microblaze Cache使能第一次读到的是Flash数据没错但如果这段时间里你用普通模式改写了同一块Flash区域Cache里可能还是旧数据。所以凡是涉及“用普通模式写Flash→用XIP读回新数据”的场景记得在读之前调用Xil_DCacheInvalidateRange把对应Cache行失效。6.3 XIP实测结果补充真正的“读性能天花板”开启XIP后读性能测试数据发生了质变。连续读1MB只是用一个指针循环累加数据实测速度从6.8MB/s跳到11.3MB/s。如果数据在Cache里反复命中这个数字还能更高。这时候读性能的瓶颈已经不再是SPI带宽而是Flash返回数据的Dummy周期和AXI读延迟。继续往上提需要优化的是AXI总线突发长度、Cache命中率这类系统级因素。对绝大多数应用来说11MB/s的读取速度已经足够支撑字库加载、配置文件读取、远程升级时的Flash数据回读等场景。到这里Microblaze读Flash的优化基本到头了除非你换用并行 NOR Flash 或者把数据搬到DDR里但那已经不是“优化SPI Flash性能”的范畴。下面说说和性能强相关的固化与启动问题。7. 固化流程与启动时间优化7.1 Vitis 2024.2 下生成Bootimage并固化性能优化得再好程序固化不了等于白做。Vitis 2024.2的固化流程相比老版本有些变化但核心三步不变第一步在Vivado里导出硬件生成XSA。注意勾选“包含bitstream”否则后面Bootimage里缺少FPGA配置文件。第二步在Vitis里右键Application工程选择生成Boot Image。Boot Image格式里通常包含两部分FPGA配置数据bitstream和应用可执行文件elf。如果系统简单可以不单独做FSBL直接用Microblaze的默认启动流程。第三步使用Vitis的“Program Flash Memory”功能Target选择QSPIImage File选择生成的boot.bin地址偏移一般设为0。烧录前确认板卡的启动模式跳线是SPI模式。NEXYS A7上FPGA从Flash加载配置的过程在硬件层面是由Artix-7内部的上电配置逻辑完成的不需要Microblaze参与Microblaze的应用代码则需要一个极小的启动引导通常是MIT Bootloader或者直接在链接脚本里把程序放在Flash高地址然后把可执行段加载到本地存储器或DDR运行。推荐的做法是编译时把代码段放在可执行内存通过链接脚本控制让固化镜像更小、启动更快。7.2 减小启动时间的手段启动时间由两部分组成FPGA从Flash读取配置的硬件加载时间以及Microblaze加载并运行应用的时间。前者和bitstream大小、配置时钟有关通常改不了太多后者是可以用性能优化直接受益的。我在这个项目里试过两种缩小启动时间的手段。第一种是压缩bitstreamVivado里勾选“Compress Bitstream”配置数据可以缩小一半左右FPGA配置时间明显下降。第二种是精简Microblaze应用本身把不必要的初始化模块disable掉例如用不到的UART、GPIO外设初始化不链接对应的库函数程序体积小了从Flash加载进内存的耗时自然变短。更激进的方案是让Microblaze直接在Flash里运行只读代码也就是整段代码跑XIP。这样启动时完全不需要把代码从Flash拷贝到RAMMicroblaze复位后直接跳到Flash映射地址开始执行。不过这个方案对链接脚本要求较高且代码执行速度受SPI读带宽限制——如果SPI时钟配置得不够高反而比“拷贝到DDR跑”更慢。我最终采用了折中方案只读数据和调用频率高的纯函数放XIP主程序和变量区放DDR启动时间和运行性能都兼顾。8. 常见问题排查与避坑实录8.1 Flash下载失败 - target dll has been cancelled 排查这个报错在Vitis烧Flash时非常经典尤其在你从Vivado切到Vitis、或者同时开了多个硬件服务器时容易遇到。第一次见到它我一度以为是板子坏了后来梳理出几个常见原因现象可能原因处理办法打开Program Flash Memory后立即报该错JTAG链路被另一个Vivado/Vitis占用关闭多余开发环境只保留一个连接任务管理器结束无关hw_server进程烧录中途报该错USB线供电不足/接触不良换双头USB线或外接电源重新插拔JTAG线换板子后报该错板卡上电时序问题先给板子上电等FPGA DONE亮后再连Vitis烧Flash一直报该错且ID读不到Flash型号或配置不匹配检查Target Device中的Flash型号是否选成S25FL128S确认Quad Mode打开还有一次特别坑我把QSPI控制器的参考时钟从50MHz改成80MHz结果烧录时“Flash download failed”。原因不是时钟频率本身而是Vitis的Flash下载驱动对特定参考时钟下的分频配置不兼容。降到50MHz后一切正常。所以遇到诡异问题先往“非默认配置”方向怀疑。8.2 启动失败类固化后不运行的几个隐藏原因程序固化后上电不运行是最打击人信心的环节。我的经验是按下“复位”和“掉电重启”是两回事Microblaze的复位路径不同需要分开排查。最常见的问题是链接脚本错误。Microblaze应用默认链接到本地存储器的起始地址如果你把程序固化到Flash地址偏移0x000000而上电后Microblaze去本地存储器地址读代码自然什么都读不到。解决办法是在链接脚本里把应用的可执行段放到启动引导约定的地址或者用生成的Bootimage让启动逻辑把代码从Flash搬运到内存。第二个常见问题是启动模式跳线没拨对。NEXYS A7上电默认从QSPI Flash配置但如果你之前用JTAG调试过板卡可能停留在JTAG模式掉电重启时要确认跳线位置。第三个隐藏问题bitstream和应用在Flash里位置重叠。如果你用了Bootimage它内部会打包bitstream和elf写入地址有固定约定如果你手动分段烧录务必确认应用地址没有覆盖bitstream。覆盖后FPGA配置加载会失败表现出来就是上电后DONE灯不亮连Microblaze的影子都看不到。8.3 性能上不去的隐藏原因不止是驱动问题如果按前面的优化步骤做完性能还是上不去问题往往不在驱动代码而在系统层面第一检查是否真的用了Quad命令。很多人配置了IP的Quad模式但驱动代码里还是用0x03标准Read命令数据线只有一根在工作速度自然上不去。可以在示波器上测DQ1~DQ3是否有翻转或者直接看驱动发送的命令字节。第二检查SPI时钟是否真的到了设定频率。IP配置里的参考时钟和分频参数可能被综合过程优化掉也可能因为时钟约束没加对导致实际工作频率远低于预期。在Vivado里用Clock Interaction Report过一遍时钟域确认没有未约束的跨时钟域路径。第三检查FIFO的深度和中断优先级。如果DMA方案里FIFO太浅SPI高速连续传输时可能会因为FIFO下溢插入等待周期吞吐掉得厉害。我一般把FIFO深度调到最大并且把DMA中断优先级设为高于其他外设避免高频率中断打断数据传输。第四也可能FLASH颗粒本身状态不佳。S25FL128S在频繁擦写后会出现坏块虽然QSPI NOR的坏块管理比NAND简单但强烈建议在量产项目里做一次全片检查至少对数据区做坏块标记和地址跳过。否则某个扇区擦写时间异常长会让整个写的平均速度看起来很难看。最后分享一个我个人的体会FPGA上的软核性能优化多数时候不是靠某一个“大招”解决的而是把协议、IP配置、数据搬运、缓存一致性这几个环节一点点抠到位。读性能从2.2MB/s到11MB/s写性能从35KB/s到接近100KB/s每一步优化拆开看都不复杂组合起来效果却非常明显。如果你也在做Microblaze读写Flash相关的项目希望这篇文章能帮你少走几段弯路。
返回列表