1. 引言
对于需要大的片上存储器的各种不同的应用,FPGA 需要提供可重构且可串联的存储器阵列。通过不同的配置选择,嵌入式存储器阵列可以被合并从而达到位宽或字深的扩展并且可以作为单端口,双端口存储器,只读存储器,FIFO,大的查找表或移位寄存器,每种应用都支持不同的数据宽度和高度。
在本文中我们设计的嵌入式存储器是一个可配置的同步16Kb模块。如图1所示,每个存储器模块有两个独立的端口,它们的结构和工作模式完全对称,并且支持双端口工作模式。每个端口都有自己的时钟信号,时钟使能信号,写信号。虽然对每个端口的操作是完全同步且独立于另一个端口的,但是可以通过外面的电路连接扩展数据位宽或地址宽度。当写允许信号WEN为低,EN为高时,存储器模块读取地址确定的存储单元的数据,当WEN和EN同时为高时,输入总线上的数据被写入存储单元。在存储器模块被用于流水线逻辑中的情况下,根据数据路径逻辑获取存储器数据时不同的需要,每个存储器模块的写数据过程可以配置成三种工作模式。根据不同的配置,输出数据总线上的数据可以随输入数据同时更新,或者一个时钟周期后更新,或者保持不变。
每个存储器模块都支持多种配置方式,可以配置成以下各种工作模式:16Kx1, 8Kx2, 4Kx4, 2Kx8, 1Kx16 and 512x32。一个可重构的正交开关矩阵用于连接输入/输出与外部数据总线。存储器模块可以配置成只读存储器。只读存储器的数据在配置过程通过第三个端口确定,也即下面讲到的存储单元的C端口。在配置过程,该配置端口支持读写操作。
一种全新的存储单元的设计方法以及实现各种配置的电路设计方法将会重点介绍。最后将给出Nanosim的仿真结果。
图1. 存储器模块 图2 三端口存储单元
2. 存储器模块的设计
2.1 存储单元的设计
当存储器模块配置为只读存储器时,只读存储器的内容必须要在FPGA的配置过程予以定义,在有些情况下还需要对存储器模块的内容予以初始化,所以存储单元需要提供一个端口专门用于存储器内容的定义或初始化。我们的存储单元采用的是一个三端口的结构,其中两个端口用于片上逻辑,第三个端口用于片外逻辑。片外即第三个端口用于只读存储器或查找表的内容定义或静态存储器的内容初始化,也可用于存储器测试中的验证。如图2所示,存储单元实际上是一对交叉耦合的反相器,通过三对NMOS与三个端的位线(bitline)连接,三个端的字线分别控制各端的NMOS导通与否。A,B端用于片上逻辑的读写操作,而C端作为配置端只在配置过程中应用。A,B两端口的位线为垂直走向,字线为水平走向,而配置端C端恰好相反,其位线为水平走向,字线为垂直走向,原因在于在FPGA的配置过程中 ,配置数据按列送入FPGA[4][5]。这种存储器单元结构同时满足了实现存储器模块的片外配置功能和片上功能的需要。
2.2 位线结构
A,B两端口的位线结构用于正常的读写操作,下图3给出了此位线结构。一列存储单元(256个)共用一对位线,它们在读/写过程的开始前被预充电至vdd,然后被选中的存储单元驱动(读过程)或被输入缓冲器驱动(写过程)。在读过程中灵敏放大器被其使能信号触发以放大位线上的差分信号,然后其单输出数据经过缓冲器被驱动经过列选择器,再经过总线选择开关矩阵,最后到达输出数据总线。灵敏放大器用于将小信号的差分输入(位线电压)放大为大信号的单端输出。如图3.B所示我们采用了一种锁存型灵敏放大器,它的两个输出经过一个改进缓冲器以单端输出,这种灵敏放大器结构简单,驱动能力强,建立时间短,有效地缩短了存储器的读取时间,提高了性能[1],[2]。
2.3 配置电路的设计
如前所述,存储器模块可以配置成以下存储器结构:16Kx1, 8Kx2, 4Kx4, 2Kx8, 1Kx16 以及512x32,配置电路就是能够实现这些配置的逻辑。组成配置电路的就是上面提到的列选择器和总线选择开关矩阵。通过对列选择器和总线选择开关矩阵的配置,可以实现以上各种存储器结构,以及读过程中的三种输出模式。