DDR3学习总结(一)

简介
DDR3 SDRAM常 简称 DDR3 是当今较为常见的一种储存器,在计算机及嵌入式产品中得到广泛应用,特别是应用在涉及到大量数据交互的场合,比如电脑的内存条。对DDR3的读写操作大都借助IP核来完成,本次实验将采用 Xilinx公司 MIG IP核来实现DDR3读写测试。 DDR3相对于SDRAM是双沿触发,读写速度快一倍。相对于DDR2有更高的运行性能和更低的电压。本次实验使用的 DDR3芯片是MT41J256M16HA-125 ,bank位宽为 3,行位宽为 15,列位宽为10,所以它的地址大小等于即 2^28=256M,数据位宽为 16bit,所以容量大小为 256M*16bit,也就是 512MByte。

具体介绍可以看datasheet

在这里插入图片描述
在这里插入图片描述

DDR 存储

可以把ddr理解为一个方格本,bank就是代表这个本子有多少页,行列地址,可以理解为一页中一行有多少个格子col,一页有多少行row。ddr写数据和地址就是将数据填到相应的格子里。

在这里插入图片描述

硬件部分

根据不同的功能引脚有,可将DDR3引脚划分为4类:地址总线引脚、数据总线引脚、控制引脚、电源与参考电压引脚。在原理图上根据分类连接好引脚,可以参考黑金A7的核心板。

在这里插入图片描述

布局布线的话,会有硬件工程师和PCB layout工程师进行设计,电源完整性,布局布线,差分,等长,阻抗匹配,EMI问题等。

软件部分

MIG IP核是硬核,左侧是用户接口,右侧是芯片接口。如下图

如果只是单纯想要简洁快速实现DDR读写功能的话,需要着重了解的是用到的用户接口的相关信号,例化配置好 Xilinx公司 MIG IP核 ,然控制各信号进行读写即可。

在这里插入图片描述

用户接口信号在后面会详细介绍,下面我们先配置MIG IP。

MIG IP设置
新建MIG IP如下所示,在这里我们不使用AXI接口,下一步;

在这里插入图片描述

选择兼容其他相同封装不同型号的FPGA,我们这里不选择。

在这里插入图片描述

选择DDR3;

在这里插入图片描述

时钟配置Clock Period,即DDR芯片物理侧的IO时钟频率,称之为核心频率;(选择FPGA性能好的片子,DDR频率也可以到更高,手头上的xc7a100tfgg484-2 DDR3能到400M)

物理侧到控制器时钟的比例,可选4:1或2:1;决定了ui_clk的频率;如图配置的话,ui_clk = 400M /4 =100Mhz

选择DDR3的类型,Components指的是DDR3的型号是元件类,服务器用的是RDIMMs和UDIMMs,笔记本那种的插条类是SODIMMs。

数据位宽,由DDR型号决定,但是当FPGA挂了多片DDR时,位宽相应增加,我们这里用了两片,所以位宽为32;

在这里插入图片描述

系统时钟输入,建议200M,后面参考时钟可以直接使用系统时钟。

在这里插入图片描述

系统时钟是使用200M的差分时钟,低电平复位

在这里插入图片描述

50欧电阻,根据硬件而定,不用管,直接NEXT;

在这里插入图片描述

新设计 or 管脚已固定

在这里插入图片描述

如果硬件已经定了,那么就选下面管脚已固定,然后读取约束文件,设置管脚就好。

引脚约束

DDR3用到的约束引脚较多,建议导入。 用到3种电平: LVCMOS、 SSTL和 DIFF_SSTL。 LVCMOS:全称 Low Voltage Complementary Metal Oxide Semiconductor,低压互补金属氧化物半导体。 SSTL:全称 Stub Series Terminated Logic 短截线串联端接逻辑。 DIFF_SSTL:全称Difference Stub Series Terminated Logic,差分短截线串联端接逻辑。 LVCMOS 的特点是噪声容限大,速度较SSTL 慢;SSTL 速度快,通常要匹配合适的端接电阻,常用于高速内存接口如DDR3;DIFF_SSTL 则是带有差分功能的SSTL。

在这里插入图片描述

后面依次NEXT就好了,最后生成。

在这里插入图片描述

下面是设置完成后的总结页面;

在这里插入图片描述

IP核生成完毕,打开veo文件查看例化文件,就可以添加到自己的工程里使用了。

 ddr3_top ddr3_top_inst(
        // Inputs
        // Differential system clocks and rst
        .sys_clk_p                      (sys_clk_p                     ),  // input         sys_clk_p
        .sys_clk_n                      (sys_clk_n                     ),  // input         sys_clk_n
        .sys_rst                        (1'b1                          ),  // input             sys_rst
        // Inouts
        .ddr3_dq                        (ddr3_dq                       ),  // inout  [31:0] ddr3_dq
        .ddr3_dqs_n                     (ddr3_dqs_n                    ),  // inout  [3:0]      ddr3_dqs_n
        .ddr3_dqs_p                     (ddr3_dqs_p                    ),  // inout  [3:0]      ddr3_dqs_p
        // Outputs
        .ddr3_addr                      (ddr3_addr                     ),  // output [14:0] ddr3_addr
        .ddr3_ba                        (ddr3_ba                       ),  // output [2:0]      ddr3_ba
        .ddr3_ras_n                     (ddr3_ras_n                    ),  // output [0:0]      ddr3_ras_n
        .ddr3_cas_n                     (ddr3_cas_n                    ),  // output            ddr3_cas_n
        .ddr3_we_n                      (ddr3_we_n                     ),  // output            ddr3_we_n
        .ddr3_reset_n                   (ddr3_reset_n                  ),  // output            ddr3_reset_n
        .ddr3_ck_p                      (ddr3_ck_p                     ),  // output [0:0]      ddr3_ck_p
        .ddr3_ck_n                      (ddr3_ck_n                     ),  // output [0:0]      ddr3_ck_n
        .ddr3_cke                       (ddr3_cke                      ),  // output [0:0]      ddr3_cke
        .ddr3_cs_n                      (ddr3_cs_n                     ),  // output [0:0]      ddr3_cs_n
        .ddr3_dm                        (ddr3_dm                       ),  // output [3:0]      ddr3_dm
        .ddr3_odt                       (ddr3_odt                      ),  // output [0:0]      ddr3_odt  
        // user interface signals
        .app_addr                       (app_addr                      ),  // input  [27:0] app_addr
        .app_cmd                        (app_cmd                       ),  // input  [2:0]      app_cmd
        .app_en                         (app_en                        ),  // input         app_en
        .app_wdf_data                   (app_wdf_data                  ),  // input  [255:0]    app_wdf_data
        .app_wdf_end                    (app_wdf_end                   ),  // input         app_wdf_end
        .app_wdf_mask                   (32'd0                         ),  // input  [31:0] app_wdf_mask
        .app_wdf_wren                   (app_wdf_wren                  ),  // input         app_wdf_wren
        .app_rd_data                    (app_rd_data                   ),  // output [255:0]    app_rd_data 
        .app_rd_data_end                (app_rd_data_end               ),  // output            app_rd_data_end 
        .app_rd_data_valid              (app_rd_data_valid             ),  // output            app_rd_data_vali
        .app_rdy                        (app_rdy                       ),  // output            app_rdy         
        .app_wdf_rdy                    (app_wdf_rdy                   ),  // output            app_wdf_rdy     
        .app_sr_req                     (1'b0                          ),  // input         app_sr_req
        .app_ref_req                    (app_ref_req                   ),  // input         app_ref_req
        .app_zq_req                     (1'b0                          ),  // input         app_zq_req
        .app_sr_active                  (app_sr_active                 ),  // output            app_sr_active    
        .app_ref_ack                    (app_ref_ack                   ),  // output            app_ref_ack      
        .app_zq_ack                     (app_zq_ack                    ),  // output            app_zq_ack       
        .ui_clk                         (ui_clk                        ),  // output            ui_clk           
        .ui_clk_sync_rst                (ddr_rst                       ),  // output            ui_clk_sync_rst  
        .init_calib_complete            (init_calib_complete           ),
        .device_temp                    (device_temp                   )
    );

对于mig与DDR3的读写原理我们不需要了解太多,交给mig就可以了。我们需要做的是控制好用户接口,写出正确的用户逻辑,控制好读写时序。想要写好User logic,我们就必须清楚各个用户控制接口的含义:

在这里插入图片描述

在这里插入图片描述

读写时序

读写时序如下所示:

在这里插入图片描述

基本时序如上。app_rdy表示UI已经准备好接收命令了,意思就是说必须要等app_rdy信号拉高了之后,app_en有效,app_cmd命令才能被接收。而且app_rdy信号,不受控制,不管是读还是写,都必须在app_rdy为高的时候进行操作。

写DDR的前提条件是(app_rdy & app_wdf_rdy)全部为高时,给出地址和命令(app_cmd = 3’b000),然后给出写数据的信号(使能与数据),就可以成功写入数据到DDR了。

在这里插入图片描述

地址和命令必须时序严格对齐!写数据信号相对来说有三种情况:①完全同步;②可以提前1拍;③最多延迟2拍;但是最好全部时序对齐,不容易出错。

读操作就简单了,在前提条件app_rdy为高时,给出命令(app_cmd = 3’b001)与地址(app_addr),读出的数据往往要晚若干个周期,以valid信号表示数据有效。

在这里插入图片描述

连读连写的时序如下图所示

在这里插入图片描述

在这里插入图片描述

总结:

结合上图分析

(1)写数据时需要先满足app_rdy,app_wdf_rdy,app_en有效,然后发送写命令和地址app_cmd,app_addr,最后写数据app_wdf_wren,app_wdf_data,app_wdf_end

(2)读数据时满足app_rdy,app_en有效,然后发送读命令和读地址app_cmd,app_addr,等待有效信号和数据app_rd_data,app_rd_data_valid

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
当使用FPGA来设计DDR3控制器时,需要使用特定的例程来实现相应的功能。下面是一个基于DDR3FPGA例程的大致步骤: 1. 配置FPGA引脚:首先,需要在FPGA开发板上配置引脚以适应DDR3芯片。这些引脚可以通过FPGA开发工具进行配置,确保与DDR3芯片正确连接。 2. 设计DDR3控制器:使用HDL(硬件描述语言)如Verilog或VHDL设计DDR3控制器。DDR3控制器的设计需要考虑到时序、数据传输和控制信号。 3. 生成IP核:一些FPGA供应商提供了DDR3控制器的IP核,可以直接用于设计。这些IP核包含了DDR3控制器的功能,可以根据需要进行配置和定制。 4. 添加时钟和时序:DDR3控制器需要使用时钟信号来同步数据传输。确保时钟的频率和时序满足DDR3规范的要求。 5. 配置初始化参数:DDR3芯片需要在启动时进行初始化,以配置时序和其他参数。在设计中,需要为DDR3控制器提供正确的初始化参数。 6. 实现读写操作:设计DDR3控制器的读写操作,包括地址传输、数据传输和控制信号的生成。确保读写操作按照DDR3规范进行,并能正确地与DDR3芯片进行通信。 7. 调试和验证:在设计完成后,需要进行调试和验证,以确保DDR3控制器在FPGA上正常工作。可以通过模拟、仿真和硬件测试等方法进行验证。 请注意,以上步骤仅提供了一个大致的指导,具体的DDR3控制器设计会根据不同的FPGADDR3芯片而有所差异。对于具体的设计细节和实现方法,建议参考相关的FPGA开发工具和DDR3芯片的技术文档、应用手册和参考设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

panweiwen0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值