时间:2024-05-04
王锋,吕天志,杨明洋
(中电科思仪科技股份有限公司,山东青岛,266555)
采用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 程序更新过程。
首先将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 程序的在线更新功能。
在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 命令如下:
其中,此tcl 命令指定了golden 镜像在SPIFlash 内存储地址为0x00000000~0x01FFFFFF,update 镜像存储起始地址为0x02000000。镜像区域的地址分配根据镜像规模而定,各型号FPGA 的镜像大小可查看UG470[10]文档中的相关说明。
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 操作。
首先需要根据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 程序烧写模块仿真时序图
在整机软件界面上开辟一个程序更新界面,如图7 所示。界面显示有当前版本号、更新版本号、提示信息和可能错误信息以及更新检测和开始更新两个按钮。当保存着待更新update 镜像bin 文件的U 盘或SD 卡连接仪器设备后,点击更新检测按钮,软件会检测并显示待更新update 镜像bin 文件的版本,点击开始更新按钮即可执行在线更新。在更新过程中若发生错误,则更新过程立即停止,并在界面上显示错误信息,否则更新结束时,界面会提示更新成功。
图7 SPIFlash 内FPGA 程序在线更新用户界面
在某已投产的项目中,在线更新功能取得良好的应用效果,得到技术人员的肯定。项目FPGA 程序编译文件大小约为10MB,一次完整的在线更新时间不到2 分钟,如表1 所示。
表1 SPIFlash内FPGA程序在线更新运行时间
本文在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 程序升级的工作量。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!