当前位置:首页 期刊杂志

一种基于PCIe总线的SPIFlash内FPGA程序在线更新方法

时间:2024-08-31

王锋,吕天志,杨明洋

(中电科思仪科技股份有限公司,山东青岛,266555)

0 引言

采用SPIFlash配置的FPGA程序通常都是通过FPGA厂家提供的程序下载器进行更新,一般仪器FPGA程序的更新方式有两种:

(1)打开产品机箱用专用程序下载器通过JETAG接口更新FPGA程序,这种方式操作复杂且需要专业人员完成;

(2)把FPGA程序下载器的功能集成到电路板中,利用厂商提供的程序下载软件更新程序,这种方案需要加入额外电路器件,增加了电路板器件的布局空间、功耗及设计成本。

鉴于一般仪器的CPU模块与FPGA之间都有PCIe总线连接,并且FPGA和SPIFlash直接连接,因此在FPGA正常工作时可以让CPU软件通过PCIe总线将要更新的FPGA程序以文件形式先传递给FPGA,然后在FPGA内设计SPIFlash芯片的烧写控制逻辑,进而实现SPIFlash内FPGA程序的在线更新。

本文以7系列FPGA为例,7系列FPGA的配置过程具备MultiBoot和FallBack机制—FPGA在上电配置时,MultiBoot机制允许FPGA选择SPIFlash中指定区域的比特流来配置,此版本比特流称为update镜像,如果配置失败,则触发FallBack机制将另一个性能良好的固定版本配置到FPGA中,从而保证FPGA可以正常工作,此版本比特流称为golden镜像。golden和update这两个镜像会一起作为初始化镜像用专用程序下载器下载到SPIFlash中,在线更新仅对SPIFlash的update镜像区域进行更新。本文在7系列FPGA的MultiBoot和FallBack机制的基础上,阐述了一种在线更新Flash内FPGA程序的方法,此方法不需要拆机连接程序下载器,更不需要增加额外硬件,在软件界面上即可控制SPIFlash内FPGA程序更新过程。

1 方案设计

■1.1 总体方案

首先将golden和update镜像一起作为SPIFlash初始化镜像下载到SPIFlash中,然后需要更新FPGA程序时,使用在线程序更新功能升级SPIFlash的update镜像即可。总体数据处理流程如图1所示。

图1 SPIFlash内FPGA程序在线更新的数据处理流程

如图1所示,在VIVADO工程版本1.0时生成golden和update镜像两个FPGA程序bit文件;然后使用特定的tcl命令将golden和update镜像合并成一个MCS文件作为Flash初始化镜像,并使用专用程序下载器将此MCS文件下载到SPIFlash中。当VIVADO工程版本升级为2.0时需要更新SPIFlash中FPGA程序,此时使用在线程序更新功能升级SPIFlash的update镜像即可。由于SPIFlash内存储的FPGA程序的数据格式为bin文件,这里的bin文件不同于VIVADO生成的FPGA程序bit文件,因此CPU模块可直接将2.0版update镜像bin文件送到FPGA片内RAM,然后在FPGA内设计SPIFlash烧写模块从FPGA片内RAM逐个字节读取2.0版update镜像bin数据并将其写入update区域。

综上所述,在7系列FPGA配置过程的MultiBoot和FallBack机制需要生成两个版本的FPGA程序,在此基础上,主要通过CPU软件控制程序和FPGA烧写控制程序实现SPIFlash内FPGA程序的在线更新功能。

■1.2 FPGA多版本程序生成模块

在VIVADO工程约束文件中添加不同约束可编译生成golden和update版FPGA程序文件。如图2所示,在基本的SPI约束基础上,选择golden约束,假设编译生成名为vision_golden.bit的golden镜像bit文件;选择update约束,假设编译生成名为vision_update.bit的update镜像的bit文件。

图2 VIVADO工程中生成多版本FPGA程序的约束命令

在VIVADO使用下列tcl命令可生成SPIFlash初始化镜像MCS文件,假设两个版本的bit文件存在于计算机D盘根目录下,此tcl命令如下:

write_cfgmem -force -format MCS -interface spix1-loadbit “up 0x0

D:/vision_golden.bit up 0x2000000D:/vision_update106.bit “D:/vision_golden_update.mcs

其中,此tcl命令指定了golden镜像在SPIFlash内存储地址为0x00000000~0x01FFFFFF,update镜像存储起始地址为0x02000000。镜像区域的地址分配根据镜像规模而定,各型号FPGA的镜像大小可查看UG470[10]文档中的相关说明。

■1.3 CPU软件控制模块

CPU模块将update镜像bin文件送给FPGA。FPGA程序一般为十几到几十MB,FPGA片内RAM难以一次性缓存,此时CPU模块可以将update镜像bin文件分包通过PCIe总线以DMA方式送给FPGA。设FPGA烧写模块的RAM为m字节大小,update镜像bin文件为n字节,则CPU模块需要将bin文件拆分成N包数据,N=[n/m],第N包数据不足m字节的话,需将第N包数据补充默认字节“0xFF”到m字节。执行在线程序更新时,CPU模块将第1包bin数据通过PCIe总线写到FPGA的RAM后启动在线烧写流程,同时监测FLASH烧写过程的各阶段状态,正常烧状态下FPGA程序每写完1包数据就会通知CPU模块发送下一包数据,若发生异常,FPGA会将异常信息上传至CPU模块。控制流程如图3所示。

图3 SPIFlash内FPGA程序在线更新CPU软件控制流程图

CPU模块和FPGA通过PCIe进行读写通信,如下所示:

首先,CPU模块在启动程序更新之前首先标记设置RAM为写状态、bin为未传完状态;

然后,确认启动程序更新之后,执行一次写RAM操作,并标记RAM是否写满和bin数据是否传完;

最后,CPU模块等待RAM是否被读空,若RAM为空时检测到bin文件已送完则等待FLASH烧写完毕后结束程序更新过程,否则再次执行一次写RAM操作。

■1.4 FPGA烧写程序模块

首先需要根据update镜像的bin文件大小和FPGA内RAM资源情况开辟一块缓冲区来接收update镜像bin数据,缓冲区越大,CPU模块向FPGA传递的bin数据包数就越少,FPGA资源占用越大。由于烧写过程和FPGA正常功能不冲突,以及SPIFlash烧写是临时占用RAM资源,因此在线烧写可以复用其他模块的RAM,这块RAM在FPGA正常工作时用于其他功能,这样可实现RAM资源共享,节省RAM资源。

用户通过界面启动在线烧写功能后,首先执行SPIFlash的update镜像区域擦除,擦除完毕后,CPU模块将update镜像bin数据通过PCIe DMA分包送到FPGA的RAM,FPGA的烧写模块将bin数据逐个字节地传递给SPIFlash,并同时接收烧写模块输出的过程标记或异常信息。因此FPGA烧写程序分为数据传递模块和烧写模块。

1.4.1 数据传递模块

FPGA负责接收每包update镜像bin文件,并将烧写过程中各阶段完成或错误标记上传给CPU模块。每传递完1包bin数据,FPGA通知CPU模块继续传递下一包bin数据,直到所有bin数据包传递结束并且全部写入SPIFlash。由于SPIFlash的update镜像区域是事先分配的一块区域,当所有bin数据全部写入FLASH时,update镜像区域一般没有被写满,此时烧写模块并不会返回FLASH烧录完成的标志;因此FPGA需要再向update镜像区域剩下的空间中写填充字0xFF,直到update镜像区域末尾烧写模块才会返回FLASH更新完成标记。

每当一包bin数据写入RAM,FPGA捕获RAM写完标记后使能读状态标记,在RAM读空之后清零RAM读状态标记。在SPIFlash的update镜像区擦除成功后,若读状态标记有效并且bin文件的数据未传递结束,则逐个读取RAM数据送给SPIFlash,当RAM读空时清零读标志。当读状态标记有效并且bin文件数据传递结束时,说明RAM中存储的是bin文件的最后一包数据,然后进入写填充字阶段,直到SPIFlash烧写完成。编制数据传递状态机,如图4所示。

图4 SPIFlash内FPGA程序在线更新FPGA数据传递控制状态机

其中,在 flash_programm_wait状态等待SPIFlash的ID校验和存储区擦除;针对CPU模块传递来的N帧数据包,第1到N-1帧的字节是在 flash_programm_write状态传递;第N帧的字节是在 flash_programm_write_ex状态传递;update区域剩余空间的默认字节“0xFF”在flash_programm_write_ex1状态传递;在这四种状态中,如果发生ID校验、或烧写错误,就停止状态机,并将相应错误标记传递给CPU模块。

1.4.2 烧写模块

烧写模块实现FPGA和SPIFlash的通信,此模块将SPIFlash控制指令或数据通过并串转换后经SPI访问FLASH,实现SPI FLASH的ID检测,FLASH存储区擦除、数据传递以及异常检测等功能。烧写模块内部接口如图5所示,烧写模块完全由FPGA实现。

图5 SPIFlash内FPGA程序在线更新FPGA程序烧写模块接口图

其中烧写控制模块SpiFlashProgrammer的操作逻辑为:

(1) 初始化;

(2) 检测ID,读取并检验FLASH存储设备标志;

(3) 删除包含update镜像的FLASH扇区;

(4) 编码update区域。对于update镜像区域每一页:

a.发送页编码命令,

b.发送当前页的每个字,如果处于当前页的末尾,则进入c步骤,

c.使能内部FLASH页编码操作,

d.等待直到FLASH 状态准备好,即内部页编码已完成。

(5)设置镜像升级完成标志。

烧写成功时会设置升级完成标志,在任何步骤发生错误时,也会设置升级完成标志,此时CPU模块应根据烧写过程返回的状态检测是否有错误发生,若有则显示错误信息,否则显示各阶段的完成标志。

SPIFlash内FPGA程序更新过程需要考虑并串转换模块SpiSerDes,此模块和烧写控制模块连接。SPI总线有两个双向串行数据线,SpiSerDes模块在向SPI总线串行化1字节的同时,将SPI总线发来的1字节输入数据并行化。SpiSerDes模块的4个引脚必须连接到已连接SPIFlash的FPGA引脚上。其中CCLK引脚作为在线烧写时钟,默认为FPGA配置时钟专用管脚,在上电配置完成后默认不能作为普通管脚使用,如果想在配置之后将CCLK用作在线烧写时钟,即用作普通管脚,则需要将连向SPI时钟的时钟信号输入到STARTUPE原语中,并且不需要对CCLK做额外的约束。

图6展示了FPGA程序烧写模块仿真时序图,update的bin数据分三帧传递给FPGA的RAM,FPGA将每帧数据烧写到SPIFlash的update镜像区域,并且在第三帧数据送进SPIFlash之后继续传递默认字节“0xFF”,当写满SPIFlash的update镜像区域时,在线更新结束。

图6 FPGA程序烧写模块仿真时序图

2 实现效果

在整机软件界面上开辟一个程序更新界面,如图7所示。界面显示有当前版本号、更新版本号、提示信息和可能错误信息以及更新检测和开始更新两个按钮。当保存着待更新update镜像bin文件的U盘或SD卡连接仪器设备后,点击更新检测按钮,软件会检测并显示待更新update镜像bin文件的版本,点击开始更新按钮即可执行在线更新。在更新过程中若发生错误,则更新过程立即停止,并在界面上显示错误信息,否则更新结束时,界面会提示更新成功。

图7 SPIFlash内FPGA程序在线更新用户界面

在某已投产的项目中,在线更新功能取得良好的应用效果,得到技术人员的肯定。项目FPGA程序编译文件大小约为10MB,一次完整的在线更新时间不到2分钟,如表1所示。

表1 SPIFlash内FPGA程序在线更新运行时间

3 结论

本文在7系列FPGA配置过程具备MultiBoot和FallBack机制的基础上,设计一种通过主机界面即可操作的SPIFlash内FPGA程序在线程序更新方案。本方案充分利用一般仪器上CPU模块与FPGA之间有PCIe总线连接,并且FPGA和SPIFlash直接连接的特点,让CPU模块通过PCIe总线将FPGA程序数据分包传递给FPGA,然后由FPGA烧写进SPIFlash,这样使用较小的RAM空间即可实现SPIFlash内较大update程序镜像更新。并且本方法不影响设备正常工作,不增加额外硬件电路,不需要连接程序烧写器,仅仅需要装载FPGA程序的U盘等存储设备即可在通过操作烧写界面执行SPIFlash内FPGA程序更新,非常便于用户远程更新设备程序,并大大降低了仪器设备FPGA程序升级的工作量。

免责声明

我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!