Stratix和Stratix GX系列器件内嵌TriMatrix存储块包括512-bit M512块、4-Kbit M4K块及512-Kbit M-RAM块。TriMatrix存储结构可对输入和输出RAM块的信号加上寄存器级,实现同步(pipelined) RAM。所有TriMatrix存储器输入均为寄存器级,提供同步写周期。输出寄存器可被旁路(bypassed)。全同步的简单或真正双端口TriMatrix存储器的工作速度高达312MHz,可工作于flow-through模式(仅有输入寄存器级)或pipelined模式(输入输出寄存器级)。
Stratix和Stratix GX系列器件不支持异步存储器(没有输入输出寄存器级),但支持 flow-through读取,即在时钟周期里读地址载入时输出数据有效(the output data is available during the clock cycle when the read address is driven into it)。对于简单/真正双端口M512和M4K存储块,在时钟下降沿读入读使能和读地址寄存器值(clocking the read enable and read address registers on the negative clock edge),并将输出寄存器旁路,就实现了flow-through读取。
声明:以下测试均基于Stratix系列EP1S40F1020C5器件。所给出的波形图均为实测结果,只是分析理解未必正确,仅供参考。
TriMatrix存储器支持混合宽度配置,即允许读写端口数据宽度不同。在这种模式下,低位LSB最先写入/读出。
例如写数据(输入)宽度为8bit,读数据(输出)宽度为2bit。设二进制数据0000_0001写入写地址wrdaddress 0,则输出端读出数据如表1所示:
表1 混合宽度配置
|
读地址rdaddress |
×2 data |
|
00 |
01(LSB of ×8 data) |
|
01 |
00 |
|
10 |
00 |
|
11 |
00(MSB of ×8 data) |
1.1 文本输入方式
采用文本输入方式描述了一个32×8的RAM块。其中输入数据宽度为8bit,输出数据宽度为2bit。读输出地址宽度为7bit写输入地址宽度为5bit,低地址存低位,高地址存高位。
图1 RAM块存储单元示意图
该RAM块的设计,利用了Quartus软件LPM宏单元库中的altdpram函数。altdpram函数描述了一个简单的双端口RAM。一个端口只能写,一个只能读,读写有两套总线,读和写有各自的时钟线、地址总线、数据总线和使能端,可同时进行读写操作。此外altdpram模块还有一个全局清零端口。
图2 简单双端口RAM模型
同步altdpram的读写时序仿真波形如图3和图4所示。这里inclk和outclk共用一个时钟clock。加上输出级寄存器后,读出数据延时了一个时钟周期,但时钟到输出延时非常小,且Altera强烈推荐采用同步RAM,因此这种RAM完全适合于时钟频率较高的应用。
图3 altdpram仿真波形-1
图4 altdpram仿真波形-2
图3中,第一个时钟周期里,wren写使能有效。时钟沿到来时,输入数据10110001锁存入写地址wrdaddress 0指示的存储单元,读地址rdaddress 0读出的数据是写入前的旧值(00)。从第二个地址rdaddress 1开始读新写入的值(00)。第二个时钟周期,wren禁能,输入数据10000011无效,所以rdaddress 4读出wrdaddress 1所指存储单元的旧值(00)。
图4中有两处改动,即wren、rdaddress 0信号持续至第二个时钟周期。观察粉色椭圆所圈的数据,可知符合以上的分析。
1.2 图形输入方式
采用图形输入方式,直接调用lpm参数化模块库中的altdpram符号。端口连接相应输入输出,如图5所示:
图5 altdpram简单双端口电路原理图
编译结果及仿真波形与文本输入方式基本相同。注意,在设置altdpram器件的参数时,没有选择输出级寄存器,输出数据比图3、4早一个时钟周期。
Note:
1. 打开Quartus -> Help -> Contents目录下Shortcuts -> Megafunctions/LPM或选择Help -> Mega functions/LPM命令,即可获得参数库的元件帮助文档。
Quqrtus软件由于某些原因而停止响应时,关闭重启后打开工程。可从File -> Recent Projects打开工程。如果没有弹出HDL文件及.vwf波形文件,可从Project Navigator中打开,不必重新寻找文件路径。当然,一般还要对工程进行再编译。
RAM读写数据时,如果Functional仿真波形正确,Timing仿真波形有误,那么可能是读写时钟频率过高,将周期变大试试看。此外,Timing仿真更接近实际情况,而且Timing仿真时会指定RAM块的类型,从而确定时钟的触发沿(如M512和M4K在时钟下降沿写入,M-RAM则在上升沿写入)。当然,在时序要求比较宽松时,一般先进行功能仿真,不必考虑延时(除了内核固有延时),便于验证。
2. 在一个工程下可以编译多个HDL文件或原理图。Project -> Set as Top-Level Entity将当前工作文件设置为顶层文件,则Compile时只编译顶层文件及其所调用的模块(波形文件仿真时必须在Simulator Tool中添加相应的.vwf文件)。注意同一工程下建立和添加多个文件时(包括图形编辑窗中多个模块),一定要在Device Design Files中添加所需文件或删除不存在文件的路径,否则编译时会出现“…undefined…”或“…missing..”之类的错误。此外,多个文件名不能重名,否则会出现实体“…already exists…”的编译警告。
文件名不要采用“123”、“***_v”、“***_vhd”等形式。
3. 波形数据段可以前后拖动或复制粘贴,这可在一定程度上减少重新赋值的麻烦。拖动不同于复制或重设,不会因为没有对齐而产生“毛刺”。选中一段波形按“Delete”键,即可删除该段波形。
在“Edit”中将“End Time”增大一倍,波形会自动复制一份(而不是全零值)接在原波形的后面。“Grid Size”可设置网格大小,当网格设置很小时可将波形图放大,否则有时显示不出小精度的网格。
编辑波形文件时,Node Finder里设置Filter-->Pins:all & Registers:post-fitting,可以将中间寄存器加入波形仿真中,便于观察中间结果。需要注意的是,修改源程序并编译后,初始化波形文件中节点node一般无需重新添加,除非源程序中修改了位宽参数。
4. 在Quartus II的时序分析报告中,选中要查看的时序路径,单击鼠标右键,即可弹出一些查看路径细节的选项。如果选择“Locate”-->“Locate in RTL Viewer”或“Locate in Technology Map Viewer”,就可看到RTL或工艺映射查看器中对应的路径。如果选择“List Paths”命令,则在Quartus II的“消息窗口(Message Window)”的System页面中看到所选路径的延时细节。推荐第二种方式,因为在消息窗口可以展开路径细节,同时点击右键也有“Locate”选项。
注意,RTL Viewer基于初步综合编译,所以所示的时序路径可能不准确(不过会给出类似教材中直观的路径,便于对照理解)。另外,RTL Viewer列出了源节点和目的节点之间所有可能的路径。为了获得更准确的时序路径,可以在Technology Map Viewer中查看。
5. 推荐采用混合输入方式,这样可以利用图形输入方式设计和调试的优点。例如在图形编辑窗中调用参数库元件并设置参数后,如果再想修改某些参数,就可以在该例化块上点右键选择“MegaWizard Plug-in Manager”,修改相应参数后右键“Update Symbol or Block”即可,非常方便且不易出错。
如果要将LPM中的某一宏功能块,如lpm_rom、lpm_ram、lpm_fifo作为自己以HDL表述的设计项目中的一个元件,可以首先利用Quartus内嵌的宏功能块处理器,根据项目需要对LPM块的参数作适当设置,由此产生一个特定的LPM HDL源程序描述,最后利用元件例化语句,在顶层设计中调用该模块。
6. Quartus中对于altdpram宏单元的建议:
This megafunction is provided only for backward compatibility in Cyclone, Cyclone II, HardCopy Stratix, Stratix, and Stratix GX designs; instead, Altera recommends using the altsyncram megafunction. …… Altera strongly recommends using synchronous rather than asynchronous RAM functions.
编译时的警告:
Warning: Assertion warning: altram does not support Stratix device family -- attempting best-case memory conversions, but power-up states and read during write behavior will be different for Stratix devices.
即altram类型的RAM块不支持Stratix系列器件。后面的lpm_ram_dq、lpm_ram_dq也有同样的建议和警告,但是仿真结果均与理论分析吻合。换用altram支持的系列器件,仿真波形与之相同。
另外,最好在Tools -> MegaWizard Plug-In Manager中的storage部分选择库元件,因为此处可以设置器件系列,不支持的库元件会不显示或不可选。而在图形编辑窗用“symbol”选择参数库元件时,不能保证这点。此外,MegaWizard Plug-In Manager可以设置生成HDL文件和波形文件,尤其是波形文件特别有用,形象地给出了仿真波形示例,极大地方便了理解元件功能。当然,这里给出的波形文件是基于Functional仿真的(也只能给出功能仿真示例,因为时序仿真对不同的器件结果是不同的)。
二. lpm_ram_dp测试
lpm_ram_dp参数模块可配置成一个口读,一个口写,读写可以同时进行,也可以配置成两个口同时读或者同时写。其配置及功能与altdpram基本相同,只是没有全局清零端口。
三. altsyncram测试
可定制简单ROM,单端口RAM,简单双端口RAM,真正双端口RAM。图6所示即为真正双端口RAM模型,图中左边的A端口和右边的B端口都支持读写操作,wren信号高为写操作,低为读操作。
图6 真正双端口RAM模型
在M4K和M-RAM存储块中,字节使能(byte enable)可以屏蔽(mask)输入数据以便仅写入特定的字节。未写入的字节单元保持原来写入的旧值。写使能信号(wren)与字节使能信号(byteena)一起控制RAM块的写操作。byteena信号的缺省值为高电平(enabled),此时写操作仅由wren信号控制。
只有altsyncram宏功能具有字节使能端。当采用M4K存储块时,要求输入数据宽度为16、18、32或36bit,否则字节使能端口不可选。M4K的字节选择功能如表2所示:
表2 M4K存储块的字节使能
|
byteena |
datain×18 |
datain×36 |
|
[0] = 1 |
[8..0] |
[8..0] |
|
[1] = 1 |
[17..0] |
[17..9] |
|
[2] = 1 |
— |
[26..18] |
|
[3] = 1 |
— |
[35..27] |
采用图形设计输入方式,直接调用lpm参数化模块库中的altsyncram符号。端口连接相应输入输出,如图7所示:
图7 altsyncram真双端口电路原理图
其中,输入数据宽度为16bit,输出数据宽度也为16bit。地址宽度为5bit,字节使能信号2bit。RAM块大小为2^5×16。
编译仿真结果如图8所示:
图8 altsyncram仿真波形
如图8所示,第三个时钟沿到来时,wren_a为低电平(disabled)并持续一个时钟周期。此时data_a输入数据0304h无法写入,q_a输出为0002h。之所以高字节为00h,是因为前一个data_a输入数据0102h的高字节未写入address_a 1地址指示的存储单元(字节使能信号byteena_a为01),从而该存储单元的值为0002。
在第四个时钟沿到来时,wren_a为高电平(enabled),byteena_a为10,此时输入数据高字节03h写入address_a 1单元,低字节04h被屏蔽,q_a输出03XXh。
至于为什么wren_a为高,byteena_a为01时q_a输出XX20h;wren_a变低时输出0002h,原因还不清楚。只是参数库提供的波形也是这样的。
注意:在双端口RAM方式下,无论是读或写都是针对同一个物理RAM块进行的。address_a 0与address_b 0指示同样的存储单元,所以在65.0ns时钟上升沿到来时,address_a与address_b分别置为0和8。如果均指向单元0,则会出现下面的警告:
Warning: Simultaneous write to memory block address 0 at time 68.9ns in vector source file -- data is invalid in memory block.
四.altshift测试
在一些DSP应用中,如FIR滤波器、伪随机码生成器、多信道滤波、自相关和协相关函数等,往往需要一些多抽头的移位寄存器来存储本地数据。传统的实现方法时用FPGA内部的触发器串接组成,优点是抽头灵活,容易使用,但在实际设计中,往往会出现LE中的触发器资源紧张的情况。M512和M4K支持移位寄存器模式,用它们来实现移位寄存器可节省逻辑单元和布线资源,并且效率更高。
设移位寄存器输入数据宽度为w,抽头(taps)长度为m,抽头数为n。如图9所示。在用RAM块实现移位寄存器时,需满足w×n小于RAM块最大支持的数据宽度,w×n×m小于RAM块的最大比特数。M4K的最大数据宽度为18bit,最大比特数为576。M4K的最大数据宽度为36bit,最大比特数为4608。而如果需要更大的移位寄存器可以用更多的RAM级联实现。
图9 RAM块实现移位寄存器
在MegaWizard Plug-In Manager中调用altshift_tags,勾选“Create groups for each tap output”。如图10所示:
图10 altshift_tags移位寄存器模型
设置移入移出数据宽度(w)均为9bit,移位宽度(m)为9bit。时延参数模块建立的移存器,没有对m即每级移存器宽度的设置,默认和数据宽度w相同。抽头数taps为n,抽头距离(tap_distance)为3,表示经过3个时钟周期才移到下一级。中间各级结果taps可输出。
编译仿真结果如图11所示:
图11 altshift测试仿真波形
五.lpm_ram_dq测试
lpm_ram_dq模块相对简单,读与写共用一组地址总线,有各自的数据线和时钟线。该测试加入了内存初始化文件mif。若没有数据写入端口,该模块就实现了ROM功能。
所有的Stratix存储器配置都必须为同步输入,因此ROM的地址线均有一级寄存器输入级。输出数据可以有一级寄存器输出级(Registered),也可以不选该寄存器级(combinatorial)。ROM的读操作等效于单端口RAM的读操作。
测试电路原理图如图12所示,其中we为写使能信号。
图12 lpm_ram_dq电路原理图(单端口RAM应用)
下面是VHDL格式的ROM数据初始化文件(文件可用任何文本编辑器实现):
1 WIDTH = 9; --存储器数据宽度为9位 2 DEPTH = 16; --存储器容量为16个单元 3 4 ADDRESS_RADIX = HEX; --地址用16进制表示 5 DATA_RADIX = BIN; --数据用二进制表示 6 7 CONTENT BEGIN 8 00 : 000000001; --前一列表示地址,后一列表示该地址的初始化数据 9 01 : 111101100; 10 02 : 111111101; 11 ………… 12 0E : 111011110; 13 0F : 000001100; 14 END;