DDR3基础和数据读取

一、DDR3概述

1.简介

工作电压(1.5V),240线接口,支持8bit预读取,工作频率在133MHz即可实现总线1066MHz的总线频率。频率从400\533\667\800MHz起跳等。芯片封装方式FBGA

2.接口

引脚包括:

  • 电源、地、配置信号 ;
  • 控制信号:CS_N ODT(阻抗匹配使能) CKE(时钟使能) reset_n(复位信号) DQM RAS\CAS\WE TDQ\TDQS DQ\DQS
  • 时钟信号:差分时钟ck_p/ck_n
  • 地址信号:CS、BA0、BA1、BA2、A0~A9、A10(对所有Bank预充电时拉高)、A11、A12、A13
  • 数据信号:DQ0~DQ15在这里插入图片描述

3.模式寄存器

模式寄存器分为MR0MR1MR2MR4

  1. MR0用来存储DDR3的不同操作模式的数据:包括突发长度、读取突发种类、CAS长度、测试模式、DLL复位等。
  2. MR1用来存储是否使能DLL、输出驱动长度、Rtt_Nom、额外长度、写电平使能等。
  3. MR2用来存储控制更新的特性, Rtt_WR阻抗,和CAS写长度。
  4. MR3用来控制MPR

4.新增功能

  1. ZQ校准功能ZQ是一个新增的引脚,接有一个240欧姆的低公差参考电阻。

  2. ODT阻抗匹配使能 :可通过读写DDR3内部的MR1寄存器,来控制DDR3 SDRAM中各个信号内部终端电阻的连接或者断开。
    ODT终端电阻的电阻值RTT可通过模式寄存器MR1A9,A6,A2来进行设置,设置的真值表为:
    在这里插入图片描述

  3. 数据电平标准SSTL_15

  4. **预取位宽(**Prefetch width):8bit

  5. 突发长度:由于DDR3的预取为8bit,所以突发传输周期(Burst Length,BL)也固定为8BL=4也是常用的,DDR3为此增加了一个4bit Burst Chop(突发突变)模式,即由一个BL=4的读取操作加上一个BL=4的写入操作来合成一个BL=8的数据突发传输,届时可通过A12地址线来控制这一突发模式;

  6. 寻址时序Timing):DDR3则在5~11之间,且附加延迟(AL)的设计也有所变化,DDR3AL有三种选项,分别是0、CL-1CL-2。另外,DDR3还新增加了一个时序参数-写入延迟(CWD),这一参数将根据具体的工作频率而定。

  7. CAS Latency(CL): 5,6,7,8,9时钟周期

  8. tRCDRAS to CAS Delay,行选通到列激活最小延时,即行选通周期;

  9. tRPRAS预充电时间;

  10. tRAS,激活预充电延时;

  11. CMD,命令速率,芯片激活向存储器发送第一个数据的时间。

  12. 两个参考电压:在DDR3系统中,对于内存系统工作非常重要的参考电压信号VREF将分为两个信号,即为命令与地址信号服务的VREFCA和为数据总线服务的VREFDQ,这将有效地提高系统数据总线的信噪等级。

  13. 点对点连接Point-to-PointP2P):大大地减轻了地址/命令/控制与数据总线的负载。面向64位构架的DDR3显然在频率和速度上拥有更多的优势,此外,由于DDR3所采用的根据温度自动自刷新、局部自刷新等其它一些功能。

  14. JEDEC标准(JESD79-3)

规定的DDR3芯片以及内存条相关参数:
在这里插入图片描述

  1. DQS(数据选取脉冲),它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。

写时序
在这里插入图片描述

读时序
在这里插入图片描述

5.SDRAM与DDR速度对比:

DDR3DDR一样是双倍数据传输速率。
在这里插入图片描述

二、DDR3接口模块IP核调用

在这里插入图片描述

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

三、DDR3读写控制

通过控制模块,实现数据突发读写,将摄像头OV5640传过来的数据从慢时钟域到快时钟域传输数据,再从SDRAM按帧为单位,从快时钟域到慢时钟域发送数据,通过HDMI显示到屏幕上。
对于跨时钟域数据的传输采用异步FIFO缓存,然后通过乒乓操作,控制读写区域。先将SDRAMBank1用于写数据,同时读取Bank3的数据输出显示,当读写都完成后,在交换读写地址,并保证屏幕上输出的图像都是完整的一帧。
因此,对于读取侧数据没有读完之前,写侧就丢弃当前帧。

1.读写仲裁

通过这种乒乓操作保证数据的有效传输。

/************************读写优先级仲裁*****************************/
//rd_flag     ;//读请求标志
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            rd_flag <= 0;
        end 
        else if(rfifo_usedw <= `RD_LT)begin   
            rd_flag <= 1'b1;
        end 
        else if(rfifo_usedw > `RD_UT)begin 
            rd_flag <= 1'b0;
        end 
    end

//wr_flag     ;//写请求标志
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            wr_flag <= 0;
        end 
        else if(wfifo_usedw >= `USER_BL)begin 
            wr_flag <= 1'b1;
        end 
        else begin 
            wr_flag <= 1'b0;
        end 
    end

//flag_sel    ;//标记上一次操作
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            flag_sel <= 0;
        end 
        else if(read2done)begin 
            flag_sel <= 1;
        end 
        else if(write2done)begin 
            flag_sel <= 0;
        end 
    end

//prior_flag  ;//优先级标志 0:写优先级高   1:读优先级高     仲裁读、写的优先级
    always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            prior_flag <= 0;
        end 
        else if(wr_flag && (flag_sel || (~flag_sel && ~rd_flag)))begin   //突发写优先级高
            prior_flag <= 1'b0;
        end 
        else if(rd_flag && (~flag_sel || (flag_sel && ~wr_flag)))begin   //突发读优先级高
            prior_flag <= 1'b1;
        end 
    end

2.OV5640的数据写入DDR3的操作

/*********************** wrfifo 写数据   ************************/
//控制像素数据帧 写入 或 丢帧

    always  @(posedge clk_in or negedge rst_n)begin
        if(~rst_n)begin
            wr_data_flag <= 1'b0;
        end 
        else if(~wr_data_flag & ~wr_finish_r[1] & din_sop)begin//可以向wrfifo写数据
            wr_data_flag <= 1'b1;
        end
        else if(wr_data_flag & din_eop)begin//不可以向wrfifo写入数据
            wr_data_flag <= 1'b0;
        end
    end

    always  @(posedge clk_in or negedge rst_n)begin //把wr_finish从wrfifo的读侧同步到写侧
        if(~rst_n)begin
            wr_finish_r <= 0;
        end
        else begin
            wr_finish_r <= {wr_finish_r[0],wr_finish};
        end
    end

/****************************************************************/
    
    //burst_write
    always  @(posedge clk or negedge rst_n)begin
        if(~rst_n)begin
            burst_write <= 1'b0;
        end
        else begin
            burst_write <= idle2write;
        end
    end

    //burst_read
    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            burst_read <= 1'b0;
        end
        else begin
            burst_read <= idle2read;
        end
    end

    //avl_read
    always  @(posedge clk or negedge rst_n)begin
        if(~rst_n)begin
            avl_read <= 1'b0;
        end
        else if(idle2read)begin
            avl_read <= 1'b1;
        end
        else if(avl_read & avl_ready)begin 
            avl_read <= 1'b0;
        end 
    end

    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            avl_write <= 1'b0;
        end
        else if(idle2write)begin
            avl_write <= 1'b1;
        end
        else if(write2done)begin
            avl_write <= 1'b0;
        end
    end
  //rd_data rd_data_vld 输出给hdmi接口
    always  @(posedge clk_out or negedge rst_n)begin
        if(~rst_n)begin
            rd_data <= 0;
            rd_data_vld <= 1'b0;
        end
        else begin
            rd_data <= rfifo_q;
            rd_data_vld <= rfifo_rdreq;
        end
    end
    
    wrfifo u_wr_fifo(
    /*input                 */.aclr     (~rst_n       ),
    /*input   [129:0]       */.data     (wfifo_wrdata ),
    /*input                 */.rdclk    (clk          ),
    /*input                 */.rdreq    (wfifo_rdreq  ),
    /*input                 */.wrclk    (clk_in       ),
    /*input                 */.wrreq    (wfifo_wrreq  ),
    /*output  [129:0]       */.q        (wfifo_q      ),
    /*output                */.rdempty  (wfifo_empty  ),
    /*output  [8:0]         */.rdusedw  (wfifo_usedw  ),
    /*output                */.wrfull   (wfifo_full   )
    );

    assign wfifo_wrdata = {din_eop,din_sop,din};
    assign wfifo_wrreq  = ~wfifo_full & din_vld & ((~wr_finish_r[1] & din_sop) | wr_data_flag);
    assign wfifo_rdreq  = state_c == WRITE && avl_ready;

3.地址设计

// wr_addr   rd_addr
    always @(posedge clk or negedge rst_n) begin 
        if (rst_n==0) begin
            wr_addr <= 0; 
        end
        else if(add_wr_addr) begin
            if(end_wr_addr)
                wr_addr <= 0; 
            else
                wr_addr <= wr_addr + (`USER_BL << 4);
        end
    end
    assign add_wr_addr = write2done;
    assign end_wr_addr = add_wr_addr && wr_addr == (`BURST_MAX << 1)- (`USER_BL << 4);
    
    always @(posedge clk or negedge rst_n) begin 
        if (rst_n==0) begin
            rd_addr <= 0; 
        end
        else if(add_rd_addr) begin
            if(end_rd_addr)
                rd_addr <= 0;
            else
                rd_addr <= rd_addr + (`USER_BL << 4);
       end
    end
    assign add_rd_addr = read2done;
    assign end_rd_addr = add_rd_addr && rd_addr == (`BURST_MAX << 1)- (`USER_BL << 4);

//wr_finish     一帧数据全部写到SDRAM
    always  @(posedge clk or negedge rst_n)begin
        if(~rst_n)begin
            wr_finish <= 1'b0;
        end
        else if(~wr_finish & wfifo_q[129])begin  //写完  从wrfifo读出eop
            wr_finish <= 1'b1;
        end
        else if(wr_finish && end_rd_addr)begin  //读完
            wr_finish <= 1'b0;
        end
    end

4.乒乓操作

//change_bank ;//切换bank 
    always  @(posedge clk or negedge rst_n)begin
        if(~rst_n)begin
            change_bank <= 1'b0;
        end
        else begin
            change_bank <= wr_finish && end_rd_addr;
        end
    end

5.读侧FIFO

rdfifo u_rd_fifo(
    /*input               */.aclr   (~rst_n       ),
    /*input   [127:0]     */.data   (rfifo_wrdata ),
    /*input               */.rdclk  (clk_out      ),
    /*input               */.rdreq  (rfifo_rdreq  ),
    /*input               */.wrclk  (clk          ),
    /*input               */.wrreq  (rfifo_wrreq  ),
    /*output  [15:0]      */.q      (rfifo_q      ),
    /*output              */.rdempty(rfifo_empty  ),
    /*output              */.wrfull (rfifo_full   ),
    /*output  [8:0]       */.wrusedw(rfifo_usedw  )    
    );

    assign rfifo_wrdata = avl_rdata;
    assign rfifo_rdreq = ~rfifo_empty & rd_req;
    assign rfifo_wrreq = avl_rdata_valid & ~rfifo_full;

6.ddr3_controller模块


    assign initial_done = rst_n & local_init_done & local_cal_success;

//模块例化

    ddr3_rw_ctrl  u_ctrl(
    /*input               */.clk                (afi_clk            ),//ddr3侧时钟
    /*input               */.clk_in             (clk_in             ),//摄像头数据输入侧时钟
    /*input               */.clk_out            (clk_out            ),//HDMI数据输出侧时钟
    /*input               */.rst_n              (rst_n              ),
    
    //user interface
    /*input               */.rd_req             (rd_req             ),//hdmi_driver读取数据请求
    /*input   [127:0]     */.din                (din                ),//摄像头写入mem的数据
    /*inpput              */.din_sop            (din_sop            ),
    /*input               */.din_eop            (din_eop            ),
    /*input               */.din_vld            (din_vld            ),
    /*output  [15:0]      */.dout               (dout               ),//发送到显示器的数据
    /*output              */.dout_vld           (dout_vld           ),

    //ddr3_interface interface
    /*output              */.avl_ready          (avl_ready          ),//avl.waitrequest_n
	/*input               */.avl_burstbegin     (avl_burstbegin     ),//.beginbursttransfer
	/*input   [25:0]      */.avl_addr           (avl_addr           ),//.address
	/*output              */.avl_rdata_valid    (avl_rdata_valid    ),//.readdatavalid
	/*output  [127:0]     */.avl_rdata          (avl_rdata          ),//.readdata
	/*input   [127:0]     */.avl_wdata          (avl_wdata          ),//.writedata
	/*input   [15:0]      */.avl_be             (avl_byteenable     ),//.byteenable
	/*input               */.avl_read_req       (avl_read_req       ),//.read
	/*input               */.avl_write_req      (avl_write_req      ),//.write
	/*input   [8:0]       */.avl_size           (avl_size           ) //.burstcount
    );

    ddr3_interface u_dddr3_intf(
	/*input  wire         */.pll_ref_clk         (clk               ),//给ip内部PLL的参考时钟
	/*input  wire         */.global_reset_n      (rst_n             ),//global_reset.reset_n
	/*input  wire         */.soft_reset_n        (1'b1              ),//soft_reset.reset_n
	/*output wire         */.afi_clk             (afi_clk           ),//afi_clk.clk
	/*output wire         */.afi_half_clk        (                  ),//afi_half_clk.clk
	/*output wire         */.afi_reset_n         (                  ),//afi_reset.reset_n
	/*output wire         */.afi_reset_export_n  (                  ),//afi_reset_export.
	/*output wire [14:0]  */.mem_a               (mem_addr          ),//memory.mem_a
	/*output wire [2:0]   */.mem_ba              (mem_bank          ),//.mem_ba
	/*output wire [0:0]   */.mem_ck              (mem_ck_p          ),//.mem_ck
	/*output wire [0:0]   */.mem_ck_n            (mem_ck_n          ),//.mem_ck_n
	/*output wire [0:0]   */.mem_cke             (mem_cke           ),//.mem_cke
	/*output wire [0:0]   */.mem_cs_n            (mem_cs_n          ),//.mem_cs_n
	/*output wire [3:0]   */.mem_dm              (mem_dqm           ),//.mem_dm
	/*output wire [0:0]   */.mem_ras_n           (mem_rasn          ),//.mem_ras_n
	/*output wire [0:0]   */.mem_cas_n           (mem_casn          ),//.mem_cas_n
	/*output wire [0:0]   */.mem_we_n            (mem_wen           ),//.mem_we_n
	/*output wire         */.mem_reset_n         (mem_rest_n        ),//.mem_reset_n
	/*inout  wire [31:0]  */.mem_dq              (mem_dq            ),//.mem_dq
	/*inout  wire [3:0]   */.mem_dqs             (mem_dqs_p         ),//.mem_dqs
	/*inout  wire [3:0]   */.mem_dqs_n           (mem_dqs_n         ),//.mem_dqs_n
	/*output wire [0:0]   */.mem_odt             (mem_odt           ),//.mem_odt
	/*output wire         */.avl_ready           (avl_ready         ),//avl.waitrequest_n
	/*input  wire         */.avl_burstbegin      (avl_burstbegin    ),//.beginbursttransfer
	/*input  wire [25:0]  */.avl_addr            (avl_addr          ),//.address
	/*output wire         */.avl_rdata_valid     (avl_rdata_valid   ),//.readdatavalid
	/*output wire [127:0] */.avl_rdata           (avl_rdata         ),//.readdata
	/*input  wire [127:0] */.avl_wdata           (avl_wdata         ),//.writedata
	/*input  wire [15:0]  */.avl_be              (avl_byteenable    ),//.byteenable
	/*input  wire         */.avl_read_req        (avl_read_req      ),//.read
	/*input  wire         */.avl_write_req       (avl_write_req     ),//.write
	/*input  wire [8:0]   */.avl_size            (avl_size          ),//.burstcount
	/*output wire         */.local_init_done     (local_init_done   ),//local_init_done
	/*output wire         */.local_cal_success   (local_cal_success ),//local_cal_success
	/*output wire         */.local_cal_fail      (local_cal_fail    ),//.local_cal_fail
	/*input  wire         */.oct_rzqin           (mem_rzq           ) //oct.rzqin

    //PLL未设置sharing模式,所以这些信号未使能
	//output wire         pll_mem_clk,               //pll_sharing.pll_mem_clk
	//output wire         pll_write_clk,             //.pll_write_clk
	//output wire         pll_locked,                //.pll_locked
	//output wire         pll_write_clk_pre_phy_clk, //.pll_write_clk_pre_phy_clk
	//output wire         pll_addr_cmd_clk,          //.pll_addr_cmd_clk
	//output wire         pll_avl_clk,               //.pll_avl_clk
	//output wire         pll_config_clk,            //.pll_config_clk
	//output wire         pll_mem_phy_clk,           //.pll_mem_phy_clk
	//output wire         afi_phy_clk,               //.afi_phy_clk
	//output wire         pll_avl_phy_clk            //.pll_avl_phy_clk
	);

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本文是作者在华为工作期间写的一篇对DDR3全面的总结,当时有好几年经常接触DDR3的设计与测试,期间总结了大量的知识点,于是业余时间汇总起来写成本文,因为DDR3属于业界通用的器件,其中知识也不涉及到公司秘密,所以分享出来供大家参考。 文章摘要: DDR,在PC、手机、通信设备等产品中广泛应用。而随着技术发展以及用户需求提高,内存不断升级,从SDRAM, DDR, DDR2、再到DDR3,现在DDR4也开始大规模应用。其特点就是速率、容量不断提高,而且性能、功耗方面也不断优化。内存技术是很多软件、硬件、逻辑、测试工程师们关注的重点。但由于其复杂程度较高,同时,英文资料复杂,理解困难,而中文资料能较全面详细描述DDR3的文献匾乏、零散。记得刚接触DDR3时真是一头雾水,一直在其表面徘徊很久。身边小伙伴也是同感。 作者所从事的硬件领域常常接触DDR,在这方面有一些难忘的经历,期间也积累了一些知识。出于经验传承的目的,特写下本文。内存已经历多代,但很多知识是相通的,本文拿当前主流的DDR3作为重点去讲解。出于能力水平及篇幅原因,本文未能周全深入描述DDR3所有特性或者某些地方存在错误,还望读者谅解和指正。同时,本书在一些地方引用了其他文献中的图文,会在相应地方加以说明。在此,衷心希望本文能给能给想了解DDR3技术的同学提供帮助。 本文分为以下八章内容: 第一章 DDR3基础 第二章 DDR硬件设计 第三章 DDR3几个关键技术 第四章DDR3工作流程、参数详解 第五章 DDR3训练 第六章 DDR3信号完整性测试 第七章 DDR3问题案例 第八章 SDRAM、DDR、DDR2、DDR3、DDR4对比
### 回答1: allegro DDR3 是一种类型的计算机内存,用于提供高性能和可靠的数据存储和处理功能。DDR3 是第三代双倍数据率(Double Data Rate)内存技术,它比前一代DDR2内存提供更高的数据传输速率和更低的能耗。 allegro DDR3 具有多种优点和特性。首先,它的传输速率比较高,可以提高计算机的整体性能。相较于DDR2内存,DDR3内存的数据传输速率提高了约两倍。这对于要求高速数据读写的任务,如多任务处理、图形渲染和大型数据库操作,非常重要。 其次,allegro DDR3 的能效比较高。通过采用低电压操作,DDR3内存能够显著减少功耗,进一步提高了系统的效能。此外,DDR3内存还采用了节能模式,会自动降低功耗。 最后,allegro DDR3 的容量和兼容性也很广泛。它的存储容量可达到64GB,能够满足大部分计算机应用的需求。另外,DDR3内存也相对成熟,广泛应用于各种计算机领域,包括桌面、笔记本、服务器和工作站。 总的来说,allegro DDR3 是一种高性能、能效高、容量大且广泛兼容的计算机内存。无论是用于家庭办公还是大型数据处理,它都能够提供稳定可靠的数据存储和处理能力。 ### 回答2: Allegro DDR3是一种主板内存,也是一种电子产品中使用的随机存取存储器(RAM)技术。它是DDR3(双倍数据率3代)标准的一部分,是DDR2(双倍数据率2代)的升级版本。 Allegro DDR3与其前身DDR2相比,在速度、带宽和功耗方面有了显著的改进。它能提供更高的数据传输速度,通常以800 MHz到2133 MHz的频率运行。这使得计算机能够更高效地处理数据,并提高系统的整体性能。 除了速度之外,Allegro DDR3还提供了更大的存储容量。它的存储大小通常从1 GB到16 GB不等,这意味着用户可以存储更多的数据和程序在电脑上,而不需要频繁地进行读写操作。 此外,Allegro DDR3还具有较低的功耗。相比于DDR2,它能够以更低的电压运行,从而减少了能耗和发热量。这对于节能环保和延长电子产品的电池寿命都非常重要。 总之,Allegro DDR3是一种高效、高速、大容量、低功耗的内存技术。它在各种电子设备中被广泛使用,包括计算机、笔记本电脑、服务器等。随着技术的进步,DDR3的发展也在不断推进,为用户提供更好的体验和性能。 ### 回答3: Allegro DDR3(又称为Allegro Double Data Rate 3)是一种计算机内存技术,它为电子设备提供了更高的数据传输速率和更高的带宽。 DDR3是DDR (Double Data Rate) 技术的第三个版本,是在DDR2技术的基础上改进和升级的。相比于DDR2,DDR3有更高的数据传输速率和更低的功耗。 Allegro DDR3使用了先进的制造工艺,可以提供数据传输速率高达1600 MHz。它采用了高频率和低电压的设计,以提高内存的效能和性能。相对于旧款的DDR2内存,使用DDR3内存可以更好地满足现代计算需求,更快地处理和传输数据。 Allegro DDR3还具备一些其他的优点。首先,它支持双通道并发,可以同时读取和写入数据,提高系统的响应速度。其次,DDR3比DDR2更节能,可以降低电脑系统的能耗,延长电池寿命。此外,DDR3内存还具备更高的容量扩展性,允许用户增加更多的内存,以满足不同的应用需求。 总的来说,Allegro DDR3内存是一种现代化的计算机内存技术,具有更高的数据传输速率、更低的功耗和更高的容量扩展性。它被广泛应用于计算机、服务器、笔记本电脑和其他电子设备中,以提供更出色的性能和更好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值