☰
Vivado 2020.2手动添加W25Q128JVEIQ SPI Flash固化完整教程
2026/9/28 5:47:39 网站建设 项目流程

搞FPGA固化时,SPI Flash选型经常会碰到华邦的W25Q128JVEIQ。这颗128Mbit的片子容量够用、速度也不错,在很多开发板和工控板上都能看到,但Vivado 2020.2的默认Flash列表里就是没有它。搞FPGA的人应该都懂这个尴尬:板子焊好了,工程编译通过了,最后却卡在“怎么把固件固化进去”这一步。这篇文章就完整讲一遍在Vivado 2020.2里手动添加W25Q128JVEIQ的流程,把每一步操作和SPI Flash参数细节都摊开讲,适合手里正好有这颗Flash、或者想在Vivado里添加任意非默认Flash的工程师参考。

1. 为什么非要手动添加这颗Flash

1.1 Vivado默认列表里到底缺了什么

Vivado的硬件管理器自带一份“配置存储器数据库”,里面收录了Winbond、Spansion、Micron、ISSI等厂商的几十款常见SPI NOR Flash。这个数据库覆盖范围其实不窄,但它更多是围绕Xilinx原厂开发板和主流工业级型号来整理的。实际项目里,板级工程师选Flash时考虑的是供货稳定性和成本,很容易选到一颗列表里没有的型号。W25Q128JVEIQ就是典型例子:它在华邦的产品线里属于非常基础的128Mbit SPI NOR Flash,性价比高、货源充足,偏偏Vivado 2020.2安装完成后搜不到这个名字。

手动添加听起来是个挺麻烦的操作,其实本质就是向Vivado补一份“这颗Flash怎么用”的说明书。Vivado并不认识具体芯片型号,它只知道怎么通过SPI接口发送读、写、擦除指令。只要把容量、页大小、扇区大小、JEDEC ID、指令集这些参数填对,Vivado就能正常生成固化文件,并通过JTAG把数据写进去、再做校验。换句话说,手动添加不是绕过Vivado的偏门操作,而是官方流程本来就支持的扩展方式,只是用的人少、文档里写得比较简略。

1.2 添加Flash前必须搞清的几个概念

在动手填参数之前,强烈建议先理解三个概念,后面能少走很多弯路:容量单位、Page/Sector/Block的关系、状态寄存器的角色。

容量单位是最容易踩的坑。W25Q128JVEIQ标称128Mbit,注意单位是bit不是Byte。128Mbit除以8得到16MB,也就是16777216字节。Vivado里配置存储器的容量参数、write_cfgmem命令的-size参数,单位都是Mb。所以这颗Flash对应的是128,而不是16。很多人把128Mbit记成16MB,填参数时写16,结果生成的镜像只有目标容量的八分之一,编程时报错或者启动失败。

Page、Sector、Block是SPI NOR Flash的三个基本操作粒度。W25Q128JVEIQ的Page是256字节,编程按页进行,一次最多写256字节;Sector是4KB,擦除的最小单位是Sector;Block是64KB,也支持32KB半块擦除。Vivado生成擦除和编程命令时,会按照这些粒度计算地址。如果填错,比如把Sector大小填成8KB,擦除命令和地址就会错位,轻则擦不干净,重则把不该擦的数据擦掉。

状态寄存器是很多人忽略的一块。SPI NOR Flash的写保护、忙碌标志、Quad模式使能位都放在状态寄存器里。W25Q128JVEIQ最常用的是Status Register-1的bit0(BUSY)和Status Register-2的bit1(QE)。BUSY位表示Flash是否在忙,擦除和编程前必须确认它为0。QE位决定Quad模式是否开启,如果要用SPI x4方式固化或者启动,这个位必须正确置1,否则FPGA上电后无法通过四线模式读取配置数据。手动添加Flash时,Vivado会要求把这些参数定义清楚,所以先搞清楚状态寄存器结构,后面操作才不会束手无策。

2. W25Q128JVEIQ核心参数与指令集速查

2.1 一颗16MB SPI NOR Flash的关键规格

手动添加Flash时用到的参数,本质上就是W25Q128JVEIQ数据手册前几页的内容。这里整理成一张速查表,后面的GUI操作和Tcl命令都会用到,建议直接收藏备查。

参数值说明
容量128Mbit / 16MB实际可用空间为16MB
工作电压2.7V – 3.6V3V系列,FPGA板载电压通常兼容
Page大小256 Bytes最小编程单位
Sector大小4KB最小擦除单位
32KB Block32KB支持半块擦除
64KB Block64KB全块擦除,速度最快
JEDEC IDEF 40 18EF=Winbond,18=128Mbit
最高时钟133 MHz实际使用时受PCB和FPGA CCLK限制
温度等级-40℃ ~ +85℃IQ后缀对应工业级

这颗Flash的Sector大小是4KB,和市面上大多数SPI NOR Flash一致,但不要想当然。有些厂商的Flash Sector是8KB,个别甚至按Uniform Sector和Boot Sector区分不同大小。填参数前一定要查对应型号的数据手册,确认实际规格,不然Vivado生成的擦除策略会出问题。

2.2 常用指令与状态寄存器详解

手动添加时,Vivado会要求填写一组操作码。这些操作码必须和W25Q128JVEIQ数据手册保持一致,核心指令如下。

功能指令码说明
Read Data0x03普通读,兼容性最好
Fast Read0x0B快速读,带Dummy周期
Fast Read Dual Output0x3B双线输出读
Fast Read Quad Output0x6B四线输出读
Fast Read Quad I/O0xEB四线I/O读,速度最快
Read JEDEC ID0x9F读取3字节芯片ID
Write Enable0x06写之前必须发送
Page Program0x02按页编程,最多256字节
Quad Page Program0x32四线写入
Sector Erase0x20擦除4KB
32KB Block Erase0x52擦除32KB
64KB Block Erase0xD8擦除64KB
Chip Erase0x60 / 0xC7整片擦除
Read Status Register-10x05读取SR1,含BUSY位
Read Status Register-20x35读取SR2,含QE位
Write Status Register0x01写状态寄存器

状态寄存器这一块值得单独拿出来说。SR1的bit0是BUSY,bit1是WEL(写使能锁存),bit2到bit5是BP0到BP3(块保护位),bit7是SRP0。SR2的bit1是QE,这是Quad模式的总开关。华邦这颗Flash出厂时QE位默认是0,也就是默认工作在标准SPI模式。如果要用SPI x4固化,必须先把QE位置1,否则即使接线支持四线,Flash也不会响应四线指令。Vivado在编程选项里提供了相关设置,后面实操部分会提到。

2.3 硬件连接与Quad模式的关系

SPI Flash的标准四线是CS#、CLK、DI(MOSI)、DO(MISO),另外两个引脚WP#和HOLD#在普通SPI模式下是功能引脚,但在Quad模式下会变成IO2和IO3。这意味着硬件设计上要特别注意:如果计划用SPI x4方式固化或启动,WP#和HOLD#不能简单接死到电源或地,必须通过电阻上拉或直接接到FPGA的可分配IO上。很多开发板为了兼容x1/x2/x4,会把这两个引脚各经10kΩ电阻上拉,再连到FPGA引脚。

实际项目里遇到过一种情况:板子为了节省IO,把HOLD#引脚直接接了地。这种设计在SPI x1模式下完全没问题,因为HOLD#不参与通信。但只要切到Quad模式,HOLD#变成IO3,电平被拉死,数据根本读不回来。如果硬件已经焊死没法改,那就只能老老实实用SPI x1模式固化,虽然慢一点,但可靠。

另外,7系列FPGA在SPI配置模式下会占用一部分专用引脚作为配置相关功能,具体哪些引脚不能乱接,要参考板卡原理图和UG570。如果固化后无法启动,先把这些物理连接问题排查完,再怀疑软件配置。

3. Vivado 2020.2手动添加与固化全流程

3.1 开始前需要准备什么

开始操作前,先确认三件事:一是Vivado 2020.2已经能正常识别JTAG下载器;二是目标板原理图里W25Q128JVEIQ的SPI引脚连接完整;三是手头有编译通过、能正常运行的bit文件。

JTAG下载器驱动是很多人第一次卡住的地方。Vivado安装目录下有Cable Drivers,Windows下需要额外的WinPcap或Wireshark驱动支持,否则open_hw_target会一直找不到设备。如果确实装不上,可以试试以管理员身份运行安装脚本,或者换一个USB口。这个坑属于老生常谈,但真的很影响开局体验。

硬件连接上还建议确认一下Flash供电。W25Q128JVEIQ工作电压是2.7V到3.6V,板子上通常用3.3V供电。如果Flash电压域和FPGA的配置引脚电压域不匹配,可能出现能识别但编程失败的诡异现象。用万用表量一下Flash VCC和FPGA VCCO实际电压,能省掉后面很多排查时间。

3.2 在Hardware Manager中手动添加Flash模型

连接好硬件并打开Hardware Manager后,操作路径如下:在Hardware窗口里右键点击FPGA器件,选择“Add Configuration Memory Device”。弹出的对话框里默认会按厂商分组显示一批Flash型号,搜索框直接输入w25q128,通常能找到W25Q128JV系列,但不同小版本可能没有JVEIQ这个具体型号。找不到时,点击窗口里的“Add”或“Create/Import”按钮,打开部件编辑表单。

表单里需要填写的核心字段如下:

  • Name:W25Q128JVEIQ
  • Manufacturer:Winbond
  • Density:128Mb
  • Page Size:256 Bytes
  • Sector Size:4096 Bytes
  • Jedec Device ID:EF 40 18,有的界面需要写成0xEF4018,注意按实际输入格式来
  • Read指令:0x03
  • Fast Read指令:0x0B
  • Page Program指令:0x02
  • Sector Erase指令:0x20
  • Chip Erase指令:0xC7
  • Quad Enable:启用,QE位定义在Status Register-2的bit1

填完保存后,这颗Flash会出现在列表中,以后新建工程也能直接复用。如果不想在GUI里逐项填写,也可以从社区下载现成的Vivado配置部件XML文件,通过导入功能加载。导入后建议核对JEDEC ID和Sector大小,防止拿到的是其他型号的定义。

这里分享一个很实际的经验:JEDEC ID一定不能填错。Vivado在编程后校验时,会通过0x9F指令回读芯片ID,与填写的值比对。ID不一致会直接报错。网上确实有人把W25Q128的ID错写成EF 40 17,结果每次烧写都卡在校验环节,排查半天才发现是ID填错。手工填写这类参数时,最好打开数据手册对着填,不要凭记忆。

3.3 生成bit流时必须设置的配置参数

手动添加完Flash模型后,需要在综合实现工程的bit流设置里,确认几个和配置相关的参数。

第一个是SPI总线宽度,对应属性BITSTREAM.CONFIG.SPI_BUSWIDTH。如果硬件上WP#和HOLD#都引出来了,建议直接设成4,启用Quad模式读取,启动速度更快。如果硬件没引出,只能设成1或2。

第二个是配置时钟频率,对应BITSTREAM.CONFIG.CONFIGRATE,单位是Hz。建议从33MHz开始试,稳定后再往上提。不要一上来就拉满,SPI Flash实际读取能力受PCB布线和上拉电阻影响很大,频率太高容易读错数据。

第三个是配置模式,对应BITSTREAM.CONFIG.CONFIG_MODE,可以显式指定SPIx1或SPIx4。这几个参数可以在Vivado的“Edit Device Properties”中修改,也可以用Tcl直接写在工程里:

set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] set_property BITSTREAM.CONFIG.CONFIGRATE 33000000 [current_design] set_property BITSTREAM.CONFIG.CONFIG_MODE SPIx4 [current_design]

生成bit流之后,再用write_cfgmem命令生成mcs或bin文件。我比较喜欢用Tcl命令,比GUI更直观,而且方便做版本管理。以下两条命令覆盖了两种常见场景:

# 生成bin文件,SPI x1模式 write_cfgmem -force -format bin -interface spi x1 -size 128 \ -loadbit "up 0x0 D:/fpga_project/top.bit" \ -file D:/fpga_project/top.bin # 生成mcs文件,SPI x4模式(Quad) write_cfgmem -force -format mcs -interface spi x4 -size 128 \ -loadbit "up 0x0 D:/fpga_project/top.bit" \ -file D:/fpga_project/top.mcs

注意-size参数是128,不是16,前面已经解释过单位是Mb。-interface参数要和bit流设置里的SPI_BUSWIDTH保持一致。如果bit流按x4生成,cfgmem却用x1封装,FPGA上电后读取方式对不上,一样无法启动。

3.4 通过JTAG把固件写进Flash

在硬件管理器里选中FPGA器件后,右键菜单选择“Program Configuration Memory Device”,或者直接用Tcl命令操作。GUI操作时,编程选项里建议把Erase、Blank Check、Program、Verify四个都勾上。很多人为了省时间只勾Program,结果擦除不干净,出现启动后逻辑混乱、部分功能不工作的现象。Verify更是不能省,烧写完自动回读校验,能在现场暴露连接和参数问题。

Tcl方式固化,命令块如下:

open_hw connect_hw_server -url localhost:3121 open_hw_target set_property PROGRAM.FILE {D:/fpga_project/top.mcs} [current_hw_cfgmem] set_property PROGRAM.ERASE 1 [current_hw_cfgmem] set_property PROGRAM.VERIFY 1 [current_hw_cfgmem] program_hw_cfgmem [current_hw_cfgmem]

编程时间取决于镜像大小和时钟频率。16MB全片擦除大概要几十秒,加上写入和校验,整个流程两三分钟很正常。如果超过十分钟还没结束,建议检查JTAG链和Flash供电,不要一直干等。

3.5 上电验证与启动模式确认

烧写完不要急着收工。断电,把FPGA配置模式引脚切到SPI启动模式,重新上电,观察FPGA是否正常加载。以7系列为例,M[2:0]接到001是Master SPI模式,具体以板卡手册为准。如果板子上有DONE指示灯,直接看灯最方便,DONE亮起说明配置成功。

如果上电后没有任何反应,大概率不是Flash烧写问题,而是配置模式引脚没设对,或者FPGA侧初始化失败。这时候先检查模式引脚,再用示波器量一下SPI CS#和CLK是否有波形。上电瞬间如果有一个片选拉低的动作、CLK上有一串时钟,说明FPGA已经在尝试读取配置数据;如果一直安静,问题基本在前面,不在Flash。

4. 固化过程中的常见问题与排查

4.1 找不到W25Q128JVEIQ或添加后列表不显示

这是手动添加最常遇到的第一个问题。如果GUI里找不到手动添加入口,还有一个办法:去Vivado安装目录下的部件配置文件里直接加一条记录。不同版本这个文件的位置有点差异,大致在安装目录/data/xicom下。在不清楚具体路径时,用文件搜索功能搜w25q128这个关键词,找到已有W25Q128相关型号的定义文件,仿照格式新增一个条目保存,重启Vivado后再看。

如果不想折腾XML,去论坛或GitHub搜现成的配置文件更高效。很多工程师已经把W25Q128JVEIQ的定义做成了XML,下载下来导入就能用。导入后注意核对Jedec ID和Sector大小,因为网上流传的文件质量参差不齐,有的刚好是别的型号改了个名字。

4.2 添加成功但写入失败

写不进去先查两个地方,一个是Flash的WP#引脚是否被拉低,另一个是状态寄存器里的块保护位是否被置位。有些板子的WP#默认接到GPIO上,GPIO初始化成低电平就把Flash保护了。解决办法是把WP#拉高,或者先通过写状态寄存器命令解锁块保护。

另一个高频原因是SPI模式选错。手动添加时如果启用了Quad模式,但硬件上的HOLD#引脚被直接接地,编程时Vivado会通过IO2/IO3与Flash通信,信号被拉死,自然写不进去。遇到这种情况,要么改回SPI x1模式,要么从硬件层面把HOLD#释放出来,改成经过电阻上拉或者接到FPGA引脚。

4.3 固化后FPGA不启动

固化成功但上电不启动,排查顺序很重要,建议按这个思路来:

  1. 配置模式引脚是否正确。7系列FPGA要确认M[2:0]处于SPI模式,很多开发板用拨码开关控制,拨错位置就是白费功夫。
  2. bit流配置里的SPI_BUSWIDTH和Flash实际接线是否一致。x4和x1不匹配是常见的启动失败原因,没有之一。
  3. 用示波器测量Flash的CS#和CLK。上电瞬间应该有读请求,如果一直没波形,说明FPGA没有发起配置读取。
  4. 检查bit流是否开启了回退加载(Fallback)。如果开了Fallback,且首地址不是有效镜像,FPGA会去回退地址找,找不到就卡住。

还有一个隐蔽问题:比特流里设的CONFIGRATE太高,超过Flash实际读取能力。有人图启动快直接设到66MHz,结果数据读错,FPGA配置失败。稳妥做法是先用33MHz验证全流程,确认没问题后再根据裕量调高。

4.4 几个很容易踩但很少有人提的细节

手动添加Flash型号后,最好把工程里生成的mcs文件和Flash型号定义一起纳入版本管理。否则同事用另一台电脑打开工程时,可能找不到自定义的Flash定义,还得重新导入一遍。

write_cfgmem里的-loadbit参数“up 0x0”表示从0地址开始连续加载。如果后续要做多镜像启动,要注意镜像对齐到Sector边界。W25Q128JVEIQ的Sector是4KB,镜像起始地址尽量按4KB对齐,否则无法独立擦除某个镜像。

量产阶段建议把编程选项里的Verify保留,并且定期抽查。SPI Flash写入受接触电阻影响比较大,JTAG连接器氧化、排线松动都会导致偶发编程失败。有了Verify,问题能当场暴露,不会等到整机测试时才被发现。

5. 从一颗Flash扩展到更多场景

搞明白了W25Q128JVEIQ,换一颗其他SPI Flash其实也是完全一样的流程。只要是符合标准SPI NOR协议的芯片,手动添加时把容量、页大小、扇区大小、JEDEC ID、指令集替换成对应数据手册的值就行。区别主要在于某些厂商芯片的QE位位置、状态寄存器定义、以及擦除指令选择,这些细节都能在数据手册里查到。

如果后续要支持FPGA的Multiboot、Golden Image回退、远程更新这些功能,Flash参数的准确性就更重要了。多镜像的地址分配、回退地址、启动顺序,都和Sector大小、Block大小有直接关系。把基础参数吃透,后面做远程升级会从容很多。

个人最后再分享一个习惯:我会把常用Flash的型号参数整理成一个表格,放在工程docs目录下,每次新板子选型时直接对照。换芯片时只改配置文件,不用重新摸索。平时多存几个不同厂商Flash定义好的XML文件,也能在关键时刻节省不少时间。毕竟FPGA工程里最怕的就是“明明前面都验证过,换个芯片又卡住了”这种重复劳动。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询