DDR3基础和数据读取

这篇具有很好参考价值的文章主要介绍了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~DQ15ddr预读取,fpga开发,硬件工程

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来进行设置,设置的真值表为:
    ddr预读取,fpga开发,硬件工程

  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芯片以及内存条相关参数:
ddr预读取,fpga开发,硬件工程

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

写时序
ddr预读取,fpga开发,硬件工程

读时序
ddr预读取,fpga开发,硬件工程

5.SDRAM与DDR速度对比:

DDR3DDR一样是双倍数据传输速率。
ddr预读取,fpga开发,硬件工程

二、DDR3接口模块IP核调用

ddr预读取,fpga开发,硬件工程

ddr预读取,fpga开发,硬件工程
ddr预读取,fpga开发,硬件工程
ddr预读取,fpga开发,硬件工程
ddr预读取,fpga开发,硬件工程

三、DDR3读写控制

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

1.读写仲裁

通过这种乒乓操作保证数据的有效传输。文章来源地址https://www.toymoban.com/news/detail-619962.html

/************************读写优先级仲裁*****************************/
//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
	);

到了这里,关于DDR3基础和数据读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于fpga的ddr3读写控制,纯verilog实现,能实现多通道图像数据读写控制

    基于fpga的ddr3读写控制,纯verilog实现,能实现多通道图像数据读写控制,模块接口清晰,可移植性高. 基于FPGA的DDR3读写控制是一项重要的技术,它为多通道图像数据的读写提供了高效的解决方案。本文将介绍一种纯Verilog实现的DDR3读写控制模块,旨在实现模块接口清晰、可移

    2024年04月12日
    浏览(55)
  • 【FPGA】MIG DDR3读写逻辑测试

            笔者在之前通过microblaze软核的方式实现了DDR3芯片的读写测试,当时对于Xilinx MIG DDR控制器的理解还比较肤浅。还是想通过控制用户接口时序的方式来读写DDR,扩展和加深自己对DDR的理解。 MIG IP核配置请看我的前一篇文章 【FPGA测试】Microblaze测试DDR读写_microblaze

    2024年01月22日
    浏览(41)
  • 【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之DDR3 IP简单读写测试(六)

    本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发平台)简介 盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板,全

    2024年01月23日
    浏览(63)
  • 基于紫光同创 FPGA 的 DDR3 读写实验

    此篇为专栏 《紫光同创FPGA开发笔记》 的第二篇,记录我的学习FPGA的一些开发过程和心得感悟,刚接触FPGA的朋友们可以先去此专栏置顶 《FPGA零基础入门学习路线》来做最基础的扫盲。 本篇内容基于笔者实际开发过程和正点原子资料撰写,将会详细讲解此 FPGA 实验的全流程

    2024年01月20日
    浏览(48)
  • 【Xilinx FPGA】DDR3 MIG IP 仿真

    Memory Interface Generator (MIG 7 Series)是 Xilinx 为 7 系列器件提供的 Memory 控制器 IP,使用该 IP 可以很方便地进行 DDR3 的读写操作。本文主要记录 Xilinx DDR3 MIG IP 的仿真过程,包括 IP 配置和 DDR3 读写仿真两部分内容。 目录 1 MIG IP 配置 2 DDR3 读写仿真         在 Vivado 开发平台 IP C

    2024年02月09日
    浏览(48)
  • 【Quartus FPGA】EMIF DDR3 读写带宽测试

    在通信原理中,通信系统的有效性用带宽来衡量,带宽定义为每秒传输的比特数,单位 b/s,或 bps。在 DDR3 接口的产品设计中,DDR3 读/写带宽是设计者必须考虑的指标。本文主要介绍了 Quartus FPGA 平台 EMIF 参数配置,以及测试 DDR3 读写带宽的过程,FPGA 器件型号是 Cyclone 10 GX

    2024年02月13日
    浏览(43)
  • FPGA入门 —— DDR3(MIG IP 核) 入门

    DDR 简介 DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM 是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器。而DDR SDRAM是Double Data Rate SDRAM的缩写,是双倍速率同步动态随机存储器的意思。 SDRAM在一个时

    2024年01月16日
    浏览(54)
  • 【Xilinx FPGA】DDR3 MIG 时钟管脚分配

    之前在验证 FPGA 板卡的芯片管脚时,所用的测试工程使用内部 PLL 生成的时钟作为 DDR3 的参考时钟。后来尝试将参考时钟改为外部 100M 晶振时钟,发现 MIG IP 配置工具找不到相应管脚,于是学习并梳理了 Xilinx DDR3 MIG IP 时钟管脚的分配规则,在这里做个记录。   目录 1 MIG 时钟

    2024年02月06日
    浏览(46)
  • DDR3 基础知识分享

    DDR系列文章分类地址: (1)DDR3 基础知识分享 (2)DDR3 控制器 MIG IP 详解完整版 (AXI4VivadoVerilog) (3)DDR3 控制器 MIG IP 详解完整版 (nativeVivadoVerilog) (4)基于 DDR3 的串口传图帧缓存系统设计实现 (5)基于 DDR3 的native接口串口局部传图缓存系统设计实现 (6)基于 DDR3 的

    2024年02月13日
    浏览(35)
  • FPGA-基于AXI4接口的DDR3读写顶层模块

    AXI4(Advancede Xtensible Interface 4)是一种高性能、高带宽的总线接口协议,用于在系统级芯片设计中连接不同的IP核(Intellectual Property)或模块。它是由ARM公司开发的,被广泛应用于各种SoC(System-on-Chip)设计中。 AXI4接口协议定义了一组规范,用于描述数据传输、地址传输、控

    2024年04月15日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包