打印

讨论:基于FPGA技术的存储器设计及其应用【双口RAM】

[复制链接]
4304|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lover9|  楼主 | 2010-1-5 16:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lover9 于 2010-1-5 16:22 编辑

在FPGA中构造存储器
       许多系列的FPGA芯片内嵌了存储阵列,如ALTERA EPlK50芯片内嵌了5K字节的存储阵列。因此,在FPGA中实现各种存储器,如单/双端口RAM、单/双端口ROM、先进先出存储器FIFO等非常方便,而且具有诸多优点。其硬件可编程的特点允许开发人员灵活设定存储器数据的宽度、存储器的大小、读写控制逻辑等,尤其适用于各种特殊存储要求的场合。FPGA/FPGA器件可工作于百兆频率以上,其构造的存储器存取速度也可达百兆次/秒以上,这样构成的高速存储器能够胜任存储数据量不太大,但速度要求很高的工作场合。
FPGA中构造存储器主要有两种方法实现。一是通过硬件描述语言如VHDL、AHDL、Verilog HDL等编程实现。二是调用MAX+PLUSⅡ自带的库函数实现。调用库函数方法构造存储器较硬件描述语言输入方式更为方便、灵活、快捷和可靠,故也更常用之。

利用库函数构造双端口RAM
      在MAX+PLUSⅡ中有几个功能单元描述库。prim逻辑元库,包括基本逻辑单元电路,如与、或、非门,触发器、输入、输出引脚等;mf宏功能库,包括TTL数字逻辑单元如74系列芯片;而下文将要详细介绍的参数化双端口RAM模块所在的参数化模块库(mega-lpm)中,包括各种参数化运算模块(加、减、乘、除)、参数化存储模块(单、双端口RAM、ROM、FIFO等)以及参数化计数器、比较器模块等等。库中的这些元件功能逻辑描述经过了优化验证,是数字电路设计中的极好选择。
      mega-lpm库中共有五种参数化双端口RAM模块:ALTDPRAM、LPM_RAM_DP、CSDPRAM、LPM_RAM_DQ和LPM_RAM_IO。其中ALTDPRAM和LPM_RAM_DP模块读写有两套总线,读和写有各自的时钟线、地址总线、数据总线和使能端,可同时进行读写操作。除此之外,ALTDPRAM模块还有一个全局清零端口。CSDPRAM模块则有a、b两组写端时钟线、地址总线、数据总线和使能端,可同时对RAM进行写操作,但对RAM读、写只能分时进行。LPM_RAM_DQ模块相对简单,读与写共用一组地址总线,有各自的数据线和时钟线。LPM_RAM_IO模块只有一组地址总线和数据总线。
      mega-1pm函数库中的双端口RAM模块全是参数化调用,这为设计带来极大的方便。通过对各种参数的取舍、参数设置和组合,再结合读写控制逻辑就可以构造出设计需要的存储器模块。双端口RAM常见的应用模式主要有以下两种:
      1.存储器映像方式。该方式可以随意对存储器的任何单元进行读写操作。其主要应用于多CPU的共享数据存储、数据传送等。该方式中,读、写控制线、地址总线和数据总线有两套。根据两端口之间数据的传送方向为单向或双向,又有单向数据总线和双向数据总线之分。
      2.顺序写方式。该方式对RAM的写操作只能顺序写入。这种情况适用于对象特性与时间紧密相关或传送数据与顺序密切相关的场合,如文件传送、时序过程、波形分析等。根据写控制逻辑的不同,可对RAM进行循环写入或一次写入方式。该方式下的读操作可以是存储器映像读或顺序读,前一种有较大的灵活性,而后一种则类似于FIFO形式。
      在读、写使用独立的地址总线和数据总线时,可以同时对RAM不同单元进行读写操作。根据不同控制逻辑的要求,对读写时钟、时钟使能端口可以适时设置,以满足控制需要。

相关帖子

沙发
lover9|  楼主 | 2010-1-5 16:35 | 只看该作者
我用的FPGA芯片是EP1C6Q240C6,其内部静态RAM容量 Up to 294,912 RAM bits (36,864 bytes)
如果作为采集图像的中间缓存,分辨率为1280*1024的一帧图像,图像数据量为1280*1024*8bit(RAW DATA) = 10485760 bit = 1310720 bytes,远远大于RAM的容量,那么就采用双口RAM存储1行的图像数据。

使用特权

评论回复
板凳
lover9|  楼主 | 2010-1-5 16:46 | 只看该作者
本帖最后由 lover9 于 2010-1-5 16:57 编辑

lpm_ram_dp 参数化双端口 RAM 宏模块

// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module dpram16k_1to512_32 (
        data,
        wren,
        wraddress,
        rdaddress,
        wrclock,
        rdclock,
        wr_aclr,
        rd_aclr,
        q);

        input        [0:0]  data;
        input          wren;
        input        [13:0]  wraddress;
        input        [8:0]  rdaddress;
        input          wrclock;
        input          rdclock;
        input          wr_aclr;
        input          rd_aclr;
        output        [31:0]  q;

        wire [31:0] sub_wire0;
        wire [31:0] q = sub_wire0[31:0];

        altsyncram        altsyncram_component (
                                .wren_a (wren),
                                .aclr0 (wr_aclr),
                                .clock0 (wrclock),
                                .aclr1 (rd_aclr),
                                .clock1 (rdclock),
                                .address_a (wraddress),
                                .address_b (rdaddress),
                                .data_a (data),
                                .q_b (sub_wire0)
                                // synopsys translate_off
                                ,
                                .addressstall_a (),
                                .addressstall_b (),
                                .byteena_a (),
                                .byteena_b (),
                                .clocken0 (),
                                .clocken1 (),
                                .data_b (),
                                .q_a (),
                                .rden_b (),
                                .wren_b ()
                                // synopsys translate_on
                                );
        defparam
                altsyncram_component.intended_device_family = "Cyclone",
                altsyncram_component.operation_mode = "DUAL_PORT",
                altsyncram_component.width_a = 1,
                altsyncram_component.widthad_a = 14,
                altsyncram_component.numwords_a = 16384,  //2^14 = 16384
                altsyncram_component.width_b = 32,
                altsyncram_component.widthad_b = 9,         
                altsyncram_component.numwords_b = 512,  //2^9 = 512
                altsyncram_component.lpm_type = "altsyncram",
                altsyncram_component.width_byteena_a = 1,
                altsyncram_component.outdata_reg_b = "UNREGISTERED",
                altsyncram_component.indata_aclr_a = "CLEAR0",
                altsyncram_component.wrcontrol_aclr_a = "CLEAR0",
                altsyncram_component.address_aclr_a = "CLEAR0",
                altsyncram_component.address_reg_b = "CLOCK1",
                altsyncram_component.address_aclr_b = "CLEAR1",
                altsyncram_component.outdata_aclr_b = "NONE",
                altsyncram_component.power_up_uninitialized = "FALSE";


endmodule

//

使用特权

评论回复
地板
w272978559| | 2010-1-6 17:24 | 只看该作者
什么玩意?

使用特权

评论回复
5
yuangaoping| | 2010-1-24 03:09 | 只看该作者
学习了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:1、我故意学习,故意工作,故意生活,故意活得像个人。 2、以后不要在我面前说英文,OK? 3、青春就像卫生纸。看着挺多的,用着用着就不够了。

122

主题

1888

帖子

1

粉丝