前沿
在FPGA设计中,配置PROM(如18V00系列)/FLASH(XCF00系列)主要的功能是存储FPGA设计,然后在上电之后,自动将设计装载到FPGA当中。在有些时候,FPGA设计并未全部将配置PROM/FLASH的存储单元全部占用,因此,未被占用的单元就被浪费掉了。
在某些应用中,用户需要在片外(FPGA外)存储自己定义的数据,这个时候就要单独挂PROM/FLASH芯片到FPGA上,这样不仅增加了设计难度(用户需要专门编写存储控制接口)、增加成本、增加布板难度、增加FPGA管脚使用数量等,从而给设计者带来很多不便。如果用户自定义的数据量不是很大,而且正好可以放到PROM/FLASH的未被占用的存储单元中,那么将极大减轻设计者的负担,减少成本,增加系统可靠性。
下面将详细介绍如何将用户自定义数据存储到PROM/FLASH中,以及如何读取这些数据。
具体实现
原理
要想实现将用户自定义数据写入PROM/FLASH以及从它们当中读出来,首先要明确以下几个问题:
理解了以上两个问题,我们就能从总体上知道是什么原理使用户数据能写入到PROM/FLASH当中,并被读出来。看FIG1:(注:以下所有的讨论都是认为FPGA的配置模式是主-串模式)
在FIG1中,有几个关键信号:CCLK,CE/,OE_RESET/,INIT/(INIT/在FPGA上)。在主-串模式配置过程中,上电之后,由FPGA的CCLK引脚发出时钟,驱动PROM/FLASH的CLK,而PROM/FLASH根据CE/、OE_RESET/的状态来确定是否地址增加(此“地址”是PROM/FLASH内部数据存储单元的地址)。如果FPGA将所有的设计数据读取完毕,则停止产生CCLK时钟。而CE/、OE_RESET/的状态可能在FPGA配置完毕之后变化,使地址复位。注意,当CCLK产生且PROM/FLASH有数据输出时,要判断这些数据是否是设计数据。判断的方法是通过一个同步字段来实现的。不同系列的FPGA同步字段会有不同,比如Virtex系列FPGA同步字段是AA995566h。在对应FPGA的配置手册中会找到其同步字段。
上述所述过程大概描述了一个FPGA的配置过程。因此,如果要想在FPGA配置成功之后,继续读取用户自定义在PROM/FLASH中的数据,就要在上述过程中做一下变动,而且不影响正常的FPGA配置。
通过研究PROM/FLASH的手册,可以知道,当CE/变高后,PROM/FLASH的地址计数器就会复位,而不再因为CLK有脉冲而地址增加。所以,当FPGA配置完毕后,设计者要阻值CE/变高。
在配置过程中,INIT/变低,表示FPGA接收的数据有CRC校验错误,这时PROM/FLASH的地址计数器会清零。
当OE_RESET/为低,PROM/FLASH的地址计数器复位。
Tab1为OE_RESET/和CE/与PROM/FLASH地址的真值表:
通过前面分析几个信号对PROM/FLASH地址的影响以及FPGA配置过程,可以有如下的方法来实现在成功配置FPGA之后,正确读取PROM/FLASH中的用户自定义数据:
以上两个措施保证了在FPGA成功配置后,PROM/FLASH的地址不会清零。但是由于FPGA成功配置后,CCLK就停止产生,所以,尽管PROM/FLASH地址没有被复位,但是也不会增加。还要想办法使地址增加。
在上述条件满足时,地址增加就要有时钟输入到PROM/FLASH的CLK引脚上。由于CCLK的不可控性(尽管BitGen中有一些选项可以影响CCLK的变化。我没有仔细去研究过),因此需要有一个设计者可控的时钟信号输入到PROM/FLASH的CLK引脚上。当FPGA成功配置后,CCLK为3态且有一个弱的到VCCO的上拉,因此将一个USER IO连接到PROM/FLASH的CLK引脚上是可行的。也就是说FPGA的CCLK和一个USER IO同时都连接到PROM/FLASH的CLK引脚上。这样,设计者就可以在FPGA成功配置后,通过控制USER IO来产生时钟脉冲,来读取自定义在PROM/FLASH中的数据。因为数据是串行的,而且PROM/FLASH的地址对设计者来说不可见,因此借鉴FPGA在配置时是如何确定从PROM/FLASH读出的数据是设计数据的方法:识别同步头。因此,在生成用户自定义数据的时候,也要考虑一个有意义的同步头数据。
如数据可以按照FIG2来分布:
如何生成用户数据并加入到mcs文件中,在后面有描述。
Read宏单元实现
从前面描述,清楚了在硬件上如何改动,使之适合在FPGA配置成功后,能读取PROM/FLASH中的用户自定义数据。但是,如何读取、读取这个动作如何实现,还是需要专门设计一个模块才可以。
FIG3是一个标准的读PROM/FLASH数据的宏单元框图:
该宏单元实现了在FPGA成功配置后,从PROM/FLASH中读取用户自定义数据。各引脚信号说明,见Tab2:
信号名 | IO 方向 | 描述 |
clock | 输入 | 所有信号的寄存都是在clock的上升沿 |
reset | 输入 | 异步低有效复位信号。该信号将所有逻辑复位到初始状态。 |
din/d0 | 输入 | 连接到PROM/FLASH的数据输出引脚。用户数据出现在该引脚上。 |
read | 输入 | 该信号低有效。该信号指示该宏单元从PROM/FLASH中读取下一个8bit数据。 |
next_sync | 输入 | 该信号低有效。该信号指示该宏单元搜索存储在PROM/FLASH中的下一个同步字段。 |
dout[7:0] | 输出 | 用户自定义数据会出现在该总线上。该总线上是否是有效的用户数据,由data_ready来指示。当data_ready保持一个时钟周期的低电平时,表明该总线上的数据是有效的。 |
data_ready | 输出 | 该信号低有效。当该信号持续一个时钟周期为低时,就表明dout[7:0]上的数据是有效的用户自定义数据。 |
sync | 输出 | 该信号低有效。当从检测到从PROM/FLASH中读出的数据有同步字段时,该信号变低。 |
reset_prom | 输出 | 该信号低有效。当该宏单元被复位时,该信号就会变低。该信号连接到PROM/FLASH的CE/或OE_RESET/上。当该信号为低时,使PROM/FLASH的地址计数器复位。 |
cclk | 输出 | 该信号非FPGA引脚上那个CCLK。该信号只是模拟CCLK。 |
下面详细介绍该宏单元是如何被设计以及如何工作的。
如何将用户定义数据加到PROM/FLASH
前面所述都是已经假定用户数据已经装到了PROM/FLASH当中,现在就讲述具体怎样实现数据的装入。
首先存在一个名字为Perl的脚本文件,该脚本文件可以使用户定义数据加到PROM文件中。格式是Intel Object和Hex格式。
Perl脚本文件可以在参考设计的/Perl_Script目录中找到。
Perl脚本文件不支持Motorola EXORmacs和TEKTRONIX TEK两种文件格式。
为了详细解释这个脚本文件做了什么以及其如何工作,因此有必要详细PROM文件的格式。将分3部分来详细描述PROM文件的格式。
参考设计
在附件的压缩文件里有参考设计。这里简单介绍一下参考设计。FIG9是参考设计的框图:
从PROM/FLASH中读到的数据在LCD上显示。LCD的驱动有PicoBlaze实现。
其他实现方法
前面讲的是在主-串模式下从PROM/FLASH中读用户数据。当然也可以采用SelectMap模式以并行方式从PROM/FLASH中读取用户数据。在设计方法与前述无太大区别,只是采用SelectMap方式后,数据为并行方式,少了串-并转换以及bit计数。
在同步字段问题上,如果用户数据分为几个不同部分,可以采用所有同步字段都相同以及同步字段不同的方式。两者各有优缺点。如果同步字段都相同,就不清楚当前所读的数据是属于哪一段;如果同步字段不同,可以清楚当天所读数据属于哪个部分,但是存在同步字段更新和存储的问题。很好理解,不再赘述。
说明
本文档全部内容完全来自于Xilinx XAPP694文档。参考设计也完全来自Xilinx的XAPP694.zip。由于时间和个人能力原因,肯定存在翻译和理解有偏差的地方,欢迎大家指正。有部分地方存在语句不通顺及错别字,也请大家海涵。
文章评论(0条评论)
登录后参与讨论