这个系列开篇肯定要先了解FPGA的启动流程,试想一下:我想实现MultiBoot,那么我应该在什么时候开始升级,升级失败后FPGA进行了哪些操作,以及怎么回到Golden区?
还有一个问题,就是我硬件打板回来,烧写进FLASH后起不来,这应该怎么排查?
缩略词索引:
- K7:Kintex 7
- V7:Vertex 7
- A7:Artix 7
以上所有这些的前提就是理解FPGA启动流程。

AMD-Xilinx FPGA启动阶段大概可以分为以上几个步骤(上图参考来源:UG470 Figure 5-3),下面分别讲解每一个步骤中FPGA做哪些工作。
一、器件上电
器件外围设置
对于7系列FPGA主要的关注点就是BANK0、BANK14和BANK15,BANK0主要关注电源和配置引脚,下表是一些注意点:

关于Vertex7系列详见《UG470》表2-7和表2-8。
SPI FLASH配置使用BANK0和BANK14,BPI则是BANK0、BANK14和BANK15,相关的电源域如图1所示,对于FPGA人员主要关注BANK0,下面是一个K7的典型电路:

重点关注:M0、M1、M2引脚(其他重要引脚我们下一节重点介绍),这几个引脚是关于FPGA的启动配置引脚:

上电时序
7系列FPGA其实对于上电时序要求不是那么高,但是对于电源域的要求比较高,下图就是FPGA的上电时序要求。

相关时序要求如下:

图4中Tpor的值和具体器件有关,大概的范围是10~50ms,若是从模式配置,建议按照60ms设计,主模式配置,建议按照5ms来考虑。
二、配置初始化
配置初始化操作,也就是上电复位完成后,相关配置存储器按顺序清零。配置初始化的触发条件主要由以下几种情况:器件正常上电、Program_B信号拉低、IProg指令、JTAG的JProgram指令、Fallback重配,以及触发器通过全局(GSR)的重新初始化。配置初始化期间,除了少量的配置输出管脚外,其余IO的状态通过PUDC_B管脚上下拉确定,详细说明见图5。

配置初始化期间还会将芯片内所有模块的配置RAM清零,包括寄存器的值和Block RAM的存储值,FF触发器重新初始化。在配置存储器清零过程中,INIT_B信号一直为低电平,当完成清零后,INIT_B信号才会变成高电平。因此INIT_B信号拉高表示初始化完成,图4中也简单说明了从上电配置到INIT_B信号拉高约多长时间。
三、配置管脚读取
按照图0中步骤,经历过上面两个步骤后,接下来就是进行配置模式采集。配置模式采集也很好理解,就是当INIT_B信号拉高后读取M2,M1,M0管脚的电平状态,这几个管脚的上下拉是决定FPGA的启动模式,详细设计如图6所示。

因为INIT_B拉高后,才进行模式采样,所以可以通过外部强制把INIT_B拉低后,进行延时再配置。如果加载模式为Master模式,FPGA很快就会输出有效的CCLK。此时,FPGA开始在配置时钟的上升沿对配置数据进行采样,当然也可以通过设置,使用下降沿来采集配置数据。
四、检测同步头
当和外设进行通信的时候,我们一般都会在协议里增加头校验、尾校验以及数据校验。对于FPGA读取FLASH中配置数据一样(还没到读取用户数据流),这个头校验就叫“同步头”,它是一段特殊的同步字。“同步头”的作用和协议头校验一样帮助FPGA确定正确的数据位置,同步字之前的配置数据都会被FPGA忽略,也就是FPGA仅仅在同步化之后才正式开始接收配置数据。同步字说明详见图7。

五、器件ID检测
为了确保位流和FPGA芯片匹配,在读取到同步字后还会检测配置位流中的器件ID和目标ID是否一致。ID是一个固定的32位的数据,基于IEEE Std 1149.1标准。7系列FPGA的ID已经在UG470 的 Table 1-1中列出,下图是截取的一部分,其他详见UG470。

32位的ID中包含了28位的特征值和4位掩码。特征值包括厂商信息,器件族,器件规模等。如果器件ID和位流配置中不匹配,FPGA 会将内部寄存器的第一位ID_Err置高,软件也会显示错误信息,同时停止后续位流加载。
六、配置文件载入
在第四步和第五步顺利通过后,FPGA开始加载配置数据。
配置文件框架
7 系列 FPGA 配置文件以帧的形式排列。帧是 7 系列 FPGA 配置内存空间中最小的可寻址段,因此所有操作都必须作用于整个配置帧。每帧由 101 个 32 位组成。
因为后续我们操作基本都是通过脚本或者GUI进行配置的,这部分内容实际我们目前也用不上,所以有兴趣的可以去看看UG470中第五章关于这部分详细介绍。
七、CRC校验
配置文件载入完成后,为了验证数据的正确性,FPGA还自动设置了CRC校验(CRC是同步进行),导入完成后会将计算的CRC值与期望CRC值进行比较。如果CRC校验不正确,FPGA会自动把INIT-B拉低,放弃这次配置。用户必须把PROG-B引脚拉低,才能进行重新配置。默认情况下,生成的配置位流会自动添加CRC校验,但这个不是必须的,可以通过位流设置功能取消CRC检验,但是取消CRC校验会存在因导入的错误位流而引起功能异常甚至损坏器件。

八、启动序列
最后一个步骤就是启动序列,也是我们需要重点关注的一步。
前面几步顺利完成后就到最后一步了,FPGA进入启动序列流程。启动序列包含8个顺序启动状态(0-7)操作,其中启动状态0对用户是不透明的,Phase1-Phase7如图10所示。

启动序列事件的默认顺序为先释放DONE引脚,然后激活I/O,最后启动写使能(详见UG470中Table 5-11 默认启动顺序,下面图12中)。实际使用中,可以通过BitGen参数对启动顺序进行设置来满足不同的需求。也就是上图中除了步骤7以外,其余几个步骤启动顺序是用户可编程的,并且启动顺序中的内容也是可编辑的,如是否等待MMCM锁定或者是否等待DCI阻抗匹配这些都是可配置的,以上两个可选配置。
但是,对于1-全局使能GWE(使能RAM和Flip-Flops所有同步单元工作)置位、2-取消全局三态GTS,激活输出管脚这两步时强制执行的,否则对于1不执行的话,FPGA无法正常工作;对于2不执行则FPGA所有引脚将功能失效。
释放DONE管脚,FPGA将取消之前按照PUDC_B引脚设置的引脚默认状态。DONE引脚是开漏输出信号,因此芯片外部需要使用一个330Ω上拉,当器件释放DONE管脚,DONE管脚的电平变为高电平。上面的详细说明如图11所示:

默认启动序列时序图:


修改上面默认的启动序列的Vivado设置如下图所示。

总结
虽然还没开始进入正题,但是“前戏”也很重要,这决定了你能深入多少。本文主要需要了解的就是FPGA启动的几个步骤,其内容更适合排查和设计FPGA相关硬件。