摘 要:本文首先简略介绍了几种当前对Virtex系列FPGA进行配置的方式和其不足之处, 在此基础上提出了一种使用微处理器读取SD 卡中的配置数据,并通过SELECTMAP 接口 对FPGA 进行配置的方案,并辅以电路图和工作流程图,以及配置数据在SD 卡中的存储方 式进行说明。采用此配置方案可以使产品更新只涉及到修改SD 卡中的数据,方便灵活,有 利于降低大规模产品升级时的成本,适用于通信、工控等多个领域。
1.引言
由于 FPGA 良好的可编程性和优越的性能表现,当前采用FPGA 芯片的嵌入式系统数 量呈现迅速增加的趋势,特别是在需要进行大规模运算的通信领域。目前FPGA 配置数据一 般使用基于SRAM 的存储方式,掉电后数据消失,每次上电后都要重新写入。配置数据的 写入方式有3 种,即使用JTAG 仿真器、使用专用芯片以及使用微处理器。JTAG 仿真器的 方式在调试的时候使用较多,能随时修改,但缺点是FPGA 芯片必须与电脑主机连接,失去 了灵活性。使用专用芯片的方式可以将配置数据事先存储在非易失性存储介质中,为大规模 升级提供了方便,但不利之处在于专用芯片往往价格较高,并且也必须采用特定的存储介质, 提升了系统成本,而且没有利用到板上的现有资源,需要为配置芯片设置出专用的空间,占 用了电路板上的空间资源。而第三种方式可以利用当前嵌入式系统中一般都存在的微处理 器,同时也可以自行选择合适的存储介质。下面就这种配置方案进行说明。
2. 系统介绍
2.1 系统工作原理
本配置方案中使用的微控制器是Philips 公司生产的ARM7 处理器LPC2468。FPGA 则 是Xilinx 公司的Virtex SX95T。存储配置数据的介质是成本较低而且使用广泛的SD 卡。
系统的工作原理是上电时微控制器LPC2468 从SD 卡中读取FPGA 的配置文件,然后 通过其通用IO 管脚模拟FPGA 的某种配置模式的时序,将配置文件写入到FPGA 的配置 RAM 中。Virtex 系列FPGA 有几种不同的配置模式,每种配置模式使用到的管脚以及配置 信号的时序都是不同的, 因此对配置模式需要作出合适的选择。
2.2 Viretex 系列FPGA 的配置模式
Viretex 系列FPGA 的配置模式是由上电时其专用配置管脚的状态决定的,对应的关系 如下表所示:
因在系统中使用微处理器作为主控制器,因此FPGA 的模式需选择Slave 方式,所以有 2 种模式可以选择,即Slave SelectMap 和Slave Serial。这2 种模式的区别在与数据管脚的数 目不同,Slave Serial 模式只有1 个管脚用于数据传输,属于串行传输,而Slave SelectMap 模式有8 个管脚用于数据传输,属于并行传输。这2 种模式可以任意选择,本文选择的是 Slave SelectMap 模式。
2.3 Slave SelectMap 配置模式
Slave SelectMap 配置模式在管脚信号功能、配置流程、配置数据等方面有自己的特点, 在进行电路板设计以及程序编写时需要注意。下面对其主要特点进行说明。
2.3.1 Slave SelectMap 模式使用的管脚信号:
SelectMap 模式下使用的FPGA 管脚为:
根据上表,可以将微控制器的通用IO 管脚与上述FPGA 管脚连接起来,连接电路图如图1 所示:
2.3.2 Slave SelectMap 模式的配置流程
Slave SelectMap 模式下提供时钟的是外部器件,本方案中的时钟信号是CCLK 使用 ARM 芯片的通用IO 进行模拟。同时,该模式下数据管脚有8 个,因此在每个CCLK 的上 升沿,FPGA 可以读入1 个字节的数据。需要注意的是这1 字节的最高位是D0,而不是一 般微处理器默认的D7,在电路板布线和编写配置程序时应给予相应改变。
配置过程的具体流程如图2 所示。
接收完配置数据后,DONE 管脚会被拉高。但这并不是表示配置过程已经结束,系统仍 需要时钟来进行后续的上电启动工作。为保证上电配置过程的正确进行,最好的办法是将配 置文件中的所有数据写入FPGA 中之后,然后继续输出CCLK 信号,直到DONE 管脚被拉 高。之后,再输出8 个周期的CCLK,保证配置能正常完成。
根据上述流程,配置程序的主要函数的伪码如下。
1.初始化函数SelectMAP_Init,在其它函数之前运行。
SelectMAP_Init(){
将ARM 通用IO 设置为对应的SelectMap 管脚信号;
设置 PROGRAM#,CS#和WRITE#管脚为低电平;
延时至少300ns;
设置 PROGRAM#为高电平;
循环检查INIT#是否变为高电平;
}
2.发送数据的函数SendData_Byte,发送1 字节的数据。
SendData(uint8 data){
拉低CCLK;
将 D0~D7 电平设置为与data 对应的状态;
拉高 CCLK;
}
3.发送数据的函数SendData_Sector,发送SD 卡中1 个扇区的数据。
void SendData_Sector(uint8 * data){
声明计数器,并将初始值设为0;
调用 SendData_Byte 发送1 个字节的数据,计数器加1;
检查 BUSY 管脚的状态,等待其变为低电平;
检查计数器是否到达规定的数据块大小,达到时函数返回,未到达时继续发送数据;
}
2.3.3 配置文件的格式
FPGA 支持将配置文件生成为几种不同的格式,但在本方案中不是所有格式都可以使用 的。一般最常用的格式是.BIN 和.BIT 格式。由于.BIT 格式包含头部开销,会增加额外的处 理过程,因此本方案没有支持.BIT 格式的数据,仅推荐使用.BIN 格式。
2.4 文件在SD 卡中的存储
发送数据前,需要先从SD 卡中读取配置文件。所有文件在SD 卡中都是按照一定的格式来组织的,本方案默认文件采用FAT16 格式进行存储。FAT16 格式下,SD 卡的结构如下图所示[3]。
主引导记录中最重要的参数是逻辑扇区的起始地址。获得该参数后即可以读取BIOS 参 数数据块(BPB)。BPB 中存储了扇区(Sector)、簇(Cluster)、文件分配表(FAT)的 大小,以及分区总扇区数等参数,是文件进行操作时必不可少的。文件分配表则是指明了文 件存储的位置,这些位置是以簇为单位的。每个簇包含的扇区数目在BPB 中说明。根文件 夹中存储了各不同文件的文件名和起始簇以及文件大小等信息。
2.5 配置文件的读取和发送
根据上述SD 卡存储格式的说明,可以对存储在其中的配置数据进行读取并发送出去。在本方案中,数据的读取和发送是同时进行的。
在对 SD 卡进行读取时,首先需要读取主引导记录(MBR),获得逻辑扇区的位置,然 后根据该位置读取BIOS 参数数据块(BPB),得到文件分配表(FAT)的位置以及扇区大 小等参数。在读取文件分配表之前,需要先读取根文件夹来获得文件的起始位置,然后再 通过文件分配表获得后续数据的位置。
得到文件的起始簇号之后,在文件分配表中读取对应该起始簇的字节,获得文件存储的 下一个簇的簇号,这样可以连续的进行读取。在读取一个簇后,即将整簇的数据发送出去。 如果发现文件分配表中某一簇对应的数值是0xFFFF,则说明是文件最后一个簇,这时该簇 的数据可以不足一个整簇,需要对其中的数据进行取舍,以保证发送数据的正确性。
对配置文件读取和发送的函数伪码如下所示。
ReadSD_FAT16(){
读取物理第0 扇区内容,即MBR,获取逻辑0 扇区的位置;
读取逻辑0 扇区的内容,获取每扇区字节数,每簇扇区数,FAT 表占据的扇区数等参数;
读取根文件夹的内容,根据配置文件的文件名获取其起始簇号和文件长度;
将当前簇设置为起始簇;
While(1){
读取FAT 中对应当前簇的内容,获得下一个簇的簇号;
FAT 表中对应当前簇的内容为0xFFFF 时,即说明当前簇是最后一个簇,计算该簇内的有效数据,并进行发送;
读取当前簇内容,进行发送;
当前簇指向下一个簇;
}
}
3 结束语
在当前FPGA 使用领域日趋广泛的情况下,对现有的含有FPGA 的嵌入式产品进行升 级更新成为了一项比较繁琐的工作,特别是在产品数量较多的情况下。本方案提出了采用 SD 卡存储配置数据的配置方案,使用了目前嵌入式系统中常见的ARM 微处理器和SD 卡, 不仅降低了成本,而且利用了现有资源,节省了电路板布线布局的空间。最重要的是使升级 过程更加简洁,在进行调试时也可以灵活使用。本文只给出了对Virtex FPGA 进行配置的情 况,该方案也可以适用于Spartan 系列FPGA。