作者:Ivy Guo,AMD 赛灵思开发者
MultiBoot是FPGA远程更新配置文件时一种非常普遍的应用 ——为了确保安全,我们通常需要安排一个Golden Image,升级失败后FPGA能回跳(Fallback)到此配置,从而使FPGA始终处于可被检测的工作状态。
很多客户有同样的问题:我在升级Update Image一半时突然掉电了,为什么回跳机制不起作用了呢?FPGA怎么挂死了呢?其实这个现象是‘符合预期’的,回跳机制不能应付这种异常。如果配置文件写到一半突然中断,嵌在配置数据流里面的指令序列同样也没有了,并且有可能中断在任意位置。FPGA的控制逻辑此时就失去了工作方向,不知道下一步该做什么。https://docs.xilinx.com/v/u/en-US/xapp1247-multiboot-spi
Xapp1247, Appendix A提供了一个很好的解决方案。利用两个timer或者称之为barrier的小image,嵌在Golden和Update之间或附在Update之后,通过合理的给两个timer赋值,可以解决Update Image刷新时同步字丢失或者半程掉电的情况。
但是同时又有客户提出了问题:我的应用对回跳时间要求很高,Xapp1247,Appendix A的方案对于半程掉电的场景,只有搜索完整个Update Image区域,看到Timer#2的设置才能完成回跳。有没有办法缩短这段时间呢?
MultiBoot的跳转实际上是非常灵活的,我们这里就尝试提供一种思路。
1. 去掉Timer#2,只保留Timer#1作为Golden和Update Image之间的barrier Image。
2. Update Image采取从后往前倒着烧录的办法。(在实际应用中,烧写flash都是用CPU/MCU/FPGA控制或者第三方编程器实现的,所以这一点也很容易实现)。
3. 精确设定Timer#1的值,使其看到Update中的TIMER指令及赋值但不需更多。
工作原理如下:
Timer寄存器的值只有在Power-Cycle或者PROG_B过程中才能被清除,或者被新的Timer值覆盖,或者在整个配置数据加载完毕后自动失效。
我们通过精确设定Timer#1的值,使FPGA控制逻辑有足够时间看到Update Image中新的Timer值。TIMER指令位于Image的头部。因为Update Image是倒着写入的,能看到新的Timer值,说明Update Image基本已经更新好了。由于新的timer值是足够控制逻辑加载完整的配置数据的,Timer寄存器被新值更新后,Timer#1相当于失效了。FPGA有充足时间可以顺利读入完整配置数据,开启正常工作。
如果由于断电等原因,Update更新到一半就停止了,此时会缺失Update的同步字,TIMER指令等等位于头部的信息。Timer#1在一个有限的时间内搜索Update Timer但是没有看到,timeout之后就会直接触发回跳。因此不用等待搜索整个Update存储空间完毕,依靠尾部的Timer#2才能触发回跳了。
整个解决方案的重点就在于设定Timer#1的值。
这个其实很简单,根据你自己生成的Timer#1和Update的MCS文件 (方法参考Xapp1247),计算一下Timer#1的指令到Update的TIMER之间的字节数即可。
以KU040的bit为例,观察Update Image头部的命令/数据序列,可以看到有3002 2001,这就是设置Timer寄存器的命令TIMER。我们想Timer#1的时间足够看到Update中的3002 2001命令以及赋值,其他不需要了,随意添加几个cycle或者几个字的裕量即可。
Timer的格式如下:
注意根据自己实际的Image来计算。假设说你的Timer#1和Update之间还有一些其他的Padding,那么这些字节也需要计算进去。
如果使用了SPI x4, x8或BPI并行配置,同样对应计算一下:
假设Timer#1以及Update都是以x4读取的,那么Timer#1需设为h’F0.
综上,通过合理设定barrier#1中的Timer#1数值,我们可以极大地缩短升级掉电这种MultiBoot失效场景的回跳时间。
没有回复内容