Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

news2024/11/24 13:37:38

引言:本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。

01.DDR3 IP核概述

7系列FPGA DDR接口解决方案如图1所示。

图1、7系列FPGA DDR3解决方案

1.1 用户FPGA逻辑(User FPGA Logic)

如图1中①所示,用户FPGA逻辑块是任何需要连接到外部DDR2或DDR3 SDRAM的FPGA设计。用户FPGA逻辑通过用户接口连接到内存控制器。

1.2 用户接口(User Interface,UI)

如图1中②和③所示,用于连接用户FPGA逻辑资源和用户接口块,它提供了一个简单的本地接口,用于实现缓冲读写数据,这也是DDR3 IP核对外接口,是编写FPGA读写逻辑需要操作的接口。

1.3 内存控制器和本地接口

如图1中④和⑤所示,内存控制器(MC)的前端向UI块显示本机接口。本机接口允许用户设计提交内存读写请求,并提供将数据从用户设计移动到外部内存设备的机制,反之亦然。内存控制器的后端连接到物理接口,并处理该模块的所有接口要求。内存控制器还提供了一个重新排序选项,可以重新排序接收到的请求,以优化数据吞吐量和延迟。

1.4 物理层和物理接口

如图1中⑥所示,PHY的前端连接到内存控制器。PHY的后端连接到外部存储设备。PHY处理存储器件信号所有的排序和时序。

02.DDR3 IP核时钟架构

DDR3 PHY设计要求使用PLL模块生成各种时钟,并使用全局和本地时钟网络在整个设计中分配时钟。PHY还需要在PLL所在的同一组中例化一个MMCM。该MMCM补偿BUFG到PHY的插入延迟。

图2、DDR3时钟架构

PHY内的时钟生成和分配电路及网络驱动块大致用于四个独立的通用功能:

  • 内部(FPGA)逻辑

  • 写入路径(输出)I/O逻辑

  • 读取路径(输入)和延迟I/O逻辑

  • IDELAY参考时钟

对于DDR3设计,IDELAY参考时钟生成需要一个MMCM。如果设计频率>667 MHz,则IDELAY参考时钟为300 MHz或400 MHz(取决于FPGA速度等级)。MIG IP核为300 MHz和400 MHz时钟生成实例化了一个MMCM。

PHY需要一个MMCM和一个PLL。PLL用于生成大多数内部逻辑的时钟、相位器的频率参考时钟,以及在多I/O Bank实现中保持PHY控制块同步所需的同步脉冲。

2.1 内部(FPGA)逻辑时钟

内部FPGA逻辑由全局时钟资源以DDR2或DDR3 SDRAM时钟频率的一半或四分之一的频率工作,这取决于MIG工具中选择的4:1或2:1模式。该PLL还输出高速DDR2或DDR3内存时钟。

2.2 写路径(输出)I/O逻辑时钟

图3、控制/地址路径时钟路径框图

由数据和控制组成的输出路径由PHASER_OUT时钟触发。PHASER_OUT为OUT_FIFO和OSERDES/ODDR的每个字节组提供同步时钟。PHASER_OUT为其相关字节组生成字节时钟(OCLK)、分字节时钟(OCLKDIV)和延迟字节时钟(OCLK_DELAYED)。这些时钟直接从频率基准时钟生成,并且彼此同相。字节时钟的频率与频率参考时钟的频率相同,分字节时钟的频率为频率参考时钟频率的一半。OCLK_DELAYED用于对DQS ODDR进行时钟设置,以实现写入DQS及其相关DQ位之间所需的90°相位偏移。PHASER_OUT还驱动写入期间生成DQ所需的信号、与数据字节组相关的DQ和DQ 三态,以及字节组OUT_FIFO的读取使能。图3和图4显示了地址/控制的时钟细节以及使用PHASER_OUT的写入路径。

2.3 读路径(输入)I/O逻辑时钟

图4、读写数据时钟路径框图

输入读取数据路径由PHASER_IN块触发。PHASER_IN块为IN_FIFO和IDDR/ISERDES的每个字节组提供同步时钟。PHASER_IN块接收相关字节组的DQS信号,并为DDR2或DDR3 SDRAM数据捕获生成两个延迟时钟:读取字节时钟(ICLK)和读取分字节时钟(ICLKDIV)。ICLK是频率基准时钟的延迟版本,其相位与其相关的DQ对齐。ICLKDIV用于将数据捕获到ISERDES中的第一级触发器中。ICLKDIV与ICLK对齐,是ISERDES中最后一列触发器的并行传输时钟。ICLKDIV还用作与字节组关联的IN_FIFO的写入时钟。移相器输入块还驱动字节组输入FIFO的写入启用(可写入)。图4显示了使用PHASER_IN读取路径的时钟细节。

2.4 延迟参考时钟

您需要始终提供200 MHz参考时钟,然后MIG使用额外的MMCM创建适当的IDELAYCTRL频率。IDELAYCTRL模块持续校准I/O区域中的IDELAY组件,以适应不同的环境条件。IP核需要外部时钟信号驱动IDELAYCTRL模块。如果PLL时钟驱动IDELAYCTRL输入时钟,则PLL锁定信号需要包含在IODELAY_CTRL.v内的rst_tmp_idelay信号,这确保了时钟在使用前是稳定的。

03、DDR3 IP核用户接口

用户接口定义如表1所示,允许通过DDR3控制器访问外部DDR3芯片。

表1、DDR3用户接口定义

04.DD3 IP核读写时序

4.1命令地址时序

图5、用户接口命令时序

当用户逻辑app_en信号被插入时,且app_rdy信号从用户接口(UI)被插入时,用户接口接受命令并将其写入IP核内部写FIFO。任何时候当app_rdy无效时,用户接口就会忽略该命令。用户逻辑需要将app_en与有效的命令和app_addr地址保持插入,直到如图1-74所示app_rdy有效插入。

4.2用户接口写时序

图6、4:1模式用户接口写时序(存储器突发类型=BL8)

可以发出非背靠背写入命令,如图6所示。该图描述了app_wdf_data、app_wdf_wren和app_wdf_end信号的三种情况,如下所示:

①写入数据与相应的写入命令一起插入,推荐的写入时序(BL8的后半部分)。
②写入数据在相应写入命令之前插入。
③写入数据在相应的写入命令后插入,但不应超过两个时钟周期的限制。

4.3用户接口读时序

图7、4:1模式用户接口读时序(存储器突发类型=BL8)

读取的数据由UI按请求的顺序返回,并且在以下情况下有效:app_rd_data_valid被插入(图7和图1-82)。app_rd_data_end信号表示每个读取命令突发的结束,在用户逻辑中不需要。

05.DDR3 MIG IP核配置

  • 硬件平台:XC7Z035FFG676-2

  • Vivado软件:2017.4

建立DDR3测试工程,进入DDR3 MIG IP配置界面。

2.点击Next,进入下一步。

3. 创建MIG IP设计。

Create Design 创建新设计

Component Name,编辑MIG IP核名称,自定义

Number of Controller,控制器数据量,此处选择1个

AXI4 Interface,AXI4接口,测试工程选择Native Interface接口,不选择AXI4接口。

4. Pin Compatible FPGAs,选择IP核兼容器件,方便DDR3 IP核工程移植。此处不选择。

5.存储器选择,由于电路板板载DDR3内存,故此处选择DDR3 SDRAM。

6.Controller Options,DDR3 SDRAM配置。

Clock Period,这个时钟为DDR3 IO接口时钟,即CK/CK#管脚时钟,图中配置为400MHz;

PHY to Controller Clock Ratio:DDR3 IO接口时钟和DDR3 MIG IP核用户接口时钟ui_clk比例,如① Clock Period=400MHz,此处设置4:1,则,ui_clk = 400MHz/4 = 100MHz。

③ 该部分设置DDR3芯片的特性。

Memory Part,IP核给出了很多定制好的镁光系列芯片,用户可以根据自己板载DDR3直接选择,如果器件参数不能满足需要,也可以自己输出DDR3芯片相关参数,即点击Create Custom Part即可进入参数编辑页面。此处选择MT41K256M16XX-107;

Memory Voltage,设置存储器电压,板载为1.5V芯片,故此处选择1.5V;

Data Width,选择DDR3数据位宽,板载为2片16bit DDR3,共用控制和地址,组成32bit位宽数据总线,故此处选择32;

ECC,ECC校验只支持72bit位宽,故不能选择;

Data Mask,数据屏蔽位,使能后,IP核会例化相应data mask接口,此处选择使能。

Nuber of Bank Machines,选择默认4;

ORDERING,选择默认Normal

7.Memory Options,DDR3 MIG IP配置。

Input Clock Period,输入时钟设置,该时钟为DDR3 MIG IP核输入时钟,及IP核内部PLL源时钟,此处选择5000ps(200MHz);

Read Burst Type and Length,读突发长度和类型,DDR3只支持突发长度BL = 8,此处选择突发类型为Sequential;

Output Driver Impedance Control,编程输出buffer阻抗,此处选择RZQ/7;

Controller Chip Select Pin,控制器片选信号选择,此处选择Enabel;

On Die Termination(ODT),片上端接大小,此处选择RZQ/4;

⑥Memory Address Mapping Selection,存储器地址映射,此处选择{Bank,ROW,COLUMN}寻址方式。

8. DDR3 MIG IP时钟、复位、参考电压等配置。

System Clock,系统时钟输入方式,可选选择单端、差分或者No Buffer,此处选择No Buffer;

Reference Clock,参考时钟,可选选择单端、差分或者No Buffer或则Use System Clock,此处选择Use System Clock,即200MHz时钟;

System Reset Polarity,IP核复位信号极性,此处选择ACTIVE LOW,即低电平复位;

Debug Signals for Memory Controller,是否选择存储器调试接口,此处选择No;

Internal Verf,是否使用内部参考电压,IP核支持DDR3参考电压输出,此处不勾选,即使用板载参考电压;

IO Power Reduciton,选择IO功耗降低,此处选ON,即打开功耗降低功能;

XDAC Instantiation,是否例化XDAC,此处选择Enable。

9. FPGA内部端接及DCI级联配置。

① Internal Termination Impedence,内部端接阻抗,此处选择50ohms;

②DCI Cascade,DCI级联选择,此处不勾选;

关于DCI级联参考:Xilinx FPGA时钟及I/O接口规划(二)

10.选择 Fixed Pin Out。

11.配置DDR3 SDRAM IO管脚分配。

根据原理图DDR3 SDRAM和FPGA管脚连接关系分配对应管脚。如果已有管脚.ucf文件,则可以点击“Read XDC/UCF”,选择.ucf文件,读入IO约束文件;

配置完成后,需要点击Validate,进行管脚分配验证,验证通过后,方可进行NEXT。

12.选择状态信号,此处均选择No connect,即不连接。

13. 该页给出了前面DDR3 MIG IP配置总结页,可快速浏览前面配置的参数内容。

14.选择Accept,点击NEXT。

15.点击Generate,生产IP核。

至此,DDR3 MIG IP核参数配置完毕。

06.DDR3 IP核读写测试

根据上一小结,生成DDR3 IP核后,编写VerilogHDL代码,进行DDR3读写测试。

①控制信号及命令:读写DDR3,主要是按照4.1~4.3小结中的DDR3 IP核读写时序编写逻辑代码。

  • app_cmd,控制命令:3'b000为写命令,3'b001为读命令;

  • app_addr,读写地址,由于DDR3突发长度固定为8,故地址递增为8;

  • app_en,使能信号,高有效;

  • app_rdy,准备ok信号,表示UI接口可以接收命令数据;

  • app_wdf_rdy,写数据FIFO准备ok,可以写数据到DDR3;

  • app_wdf_wren,写数据有效信号,高有效;

  • app_wdf_end,表示当前写为最后一个数据,根据DDR3写时序,该信号和app_wdf_wren时序相同即可;

  • app_wdf_data,写DDR3数据,需要注意该接口数据位宽的计算;

  • app_rd_data,读出DDR3数据,该接口位宽和app_wdf_data相同;

  • app_rd_data_valid,读出DDR3数据有效信号,高有效。

   //地址、命令及使能     assign    app_cmd       = (state==WRITE) ? CMD_WRITE : CMD_READ;   assign    app_addr      = app_addr_begin;    assign    app_en        = (state==WRITE) ? (app_rdy&&app_wdf_rdy) : ((state==READ)&&app_rdy);//IP核使能   //写控制及写入数据   assign    app_wdf_end   = app_wdf_wren;    assign    app_wdf_wren  = (state==WRITE) ? (app_rdy&&app_wdf_rdy) : 1'b0; //写使能   assign    app_wdf_data  = {                                 Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],                                 Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],                                 Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],                                 Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0]                              };//写入的数据是计数器

②DDR3读写状态机:先写入一定长度数据,然后读出对应长度数据,读完后再返回写状态。读写状态机比较简单,主要是读写地址主要增量为突发长度8。

     always@(posedge ui_clk)        if(ui_clk_sync_rst&!init_calib_complete)//            begin                state           <=IDLE;                app_addr_begin  <=29'd0;                Count_64        <=24'd0;            end     else case(state)         IDLE: begin            state     <=WRITE;            if(app_addr_begin > TEST_DATA_RANGE)              app_addr_begin  <=29'd0;              Count_64         <=24'd0;            end         WRITE: begin//写DDR3                state           <=(Count_64==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy ? WAIT:state; //最后一个地址写完之后跳出写状态                Count_64        <=app_rdy&&app_wdf_rdy?(Count_64+24'd1):Count_64;                 // 计数写入的数据个数                    app_addr_begin  <=app_rdy&&app_wdf_rdy?(app_addr_begin+29'd8):app_addr_begin;     //地址突发BL=8,跳到下一个(8*32=256)bit数据地址            end         WAIT: begin                state           <=READ;                Count_64        <=24'd0;                    app_addr_begin  <=29'd0;                end         READ: begin//读DDR3                state           <=(Count_64==TEST_DATA_RANGE)&&app_rdy? IDLE:state; //读完写入数据长度,切换至初始状态                Count_64        <=app_rdy?(Count_64+24'd1):Count_64;                //读出数据个数                 app_addr_begin  <=app_rdy?(app_addr_begin+29'd8):app_addr_begin;    //读地址突发BL=8            end     default:begin                state           <=IDLE;                app_addr_begin  <=29'd0;                Count_64        <=24'd0;            end                endcase

③DDR3管脚约束。在工程文件中,不需要手动编写约束文件,如本工程,只进行了如下管脚约束。

set_property IOSTANDARD SSTL15 [get_ports clk_100M]set_property PACKAGE_PIN C8 [get_ports clk_100M]

这是因为在创建DDR3 MIG IP核时,已经对DDR3 SDRAM管脚进行了分配,IP核自动生成对应的约束文件,包含在IP文件目录下,工程编译综合时,会自动编译该IP的约束文件。

DDR3 IP核约束文件

④测试结果。

DDR3 写入时序及数据
 

DDR3 读出时序及数据

                        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/530393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest

一、前言 “深入解析”对我来说的确有些难度&#xff0c;所以我尽量将我学习到和观察到的gtest内部实现介绍给大家。本文算是抛砖引玉吧&#xff0c;只能是对gtest的整体结构的一些介绍&#xff0c;想要了解更多细节最好的办法还是看gtest源码&#xff0c;如果你看过gtest源码…

麒麟操作系统软件更新灾难连篇之一:中文输入法消失

今天在麒麟操作系统开QQ总是过一会儿就闪退&#xff0c;于是进软件商店看看是否有更新。 真是不看不知道&#xff0c;一看吓一跳&#xff0c;居然有几十个软件更新&#xff0c;照常理&#xff0c;软件升级后应该是更加好用&#xff0c;于是先把QQ、五笔字型、搜狗输入法等几个常…

centos7.9搭建redis6.0.6哨兵模式

redis6.0.6哨兵模式搭建文档 1.准备工作1.1 ip规划安装依赖&#xff08;三台机器都操作&#xff09;1.3 gcc升级&#xff08;三台机器都操作&#xff09; 2.安装redis&#xff08;三台机器都操作&#xff09;2.1 获取安装包2.2 解压2.3 编译2.4 验证上一步是否正确2.5 安装2.6…

Windows10安装二进制Mysql-5.7.41和汉化

1.创建my.ini [mysqld] ##skip-grant-tables1 port 3306 basedirD:/webStudy/mysql-5.7.41 datadirE:/adata/mysqlData max_connections200 character-set-serverutf8 default-storage-engineINNODB sql_modeNO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES [mysql] default-char…

Liunx基础命令 - which命令

which命令 – 查找命令文件 ​ which命令的功能是用于查找命令文件&#xff0c;能够快速搜索二进制程序所对应的位置。如果我们既不关心同名文件&#xff08;find与locate&#xff09;&#xff0c;也不关心命令所对应的源代码和帮助文件&#xff08;whereis&#xff09;&#…

C++中类的静态成员变量与静态成员函数

static声明为静态的&#xff0c;称为静态成员。 不管这个类创建了多少个对象&#xff0c;静态成员只有一个拷贝&#xff0c;这个拷贝被所有属于这个类的对象共享。 静态成员 属于类 而不是对象。 静态变量&#xff0c;是在编译阶段就分配空间&#xff0c;对象还没有创建时&…

ARM-栈帧(一)

ARM 栈帧 本系列均以 corter-A7(armv7-a) 为例 在 ARM 中&#xff0c;通常为满减栈&#xff08;Full Descending FD&#xff09;, 也就是说&#xff0c;堆栈指针指向堆栈内存中最后一个填充的位置&#xff0c;并且随着每个新数据项被压入堆栈而递减。 栈的本质 要理解栈的本…

二叉搜索树、AVL树、红黑树底层源码以及迭代器模拟实现,map/set的封装

这次给大家分享的还是关于二叉树部分的内容&#xff0c;之前的文章已经分享过一些二叉树的基础知识&#xff0c;如果不了解的朋友可以看看&#xff1a;二叉树以及堆和堆排序。普通的二叉树其实是没有什么实际的应用价值的&#xff0c;而map和set大家用过或者听过吗&#xff1f;…

Metasploit Framework(MSF)对Metasploitable2的渗透解析

简介 Metasploitable2虚拟系统是一个特殊的ubuntu操作系统&#xff0c;本身设计目的是作为安全工具测试和演示常见漏洞攻击的环境。 其中最核心是可以用来作为MSF攻击用的靶机。这样方便我们学习MSF框架的使用。 并且开放了很多的高危端口如21、23、445等&#xff0c;而且具有…

李薇:大模型时代的数据变革

Datawhale干货 作者&#xff1a;李薇&#xff0c;上海人工智能实验室 前言 今天&#xff0c;我将向那些希望深入了解大模型的同学们&#xff0c;分享一些关于大模型时代的数据变革的知识。作为上海人工智能实验室OpenDataLab的产品主管&#xff0c;我会介绍我们在开放数据和大…

大数据技术闲侃之岗位选择解惑

前言 写下这篇文章是因为五一节前给群友的承诺&#xff0c;当然按照以往的惯例&#xff0c;也是我背后看到的这个现象&#xff0c;我发现大部分同学在投递岗位的时候都是投递数据分析岗位&#xff0c;其实背后并不是很清楚背后的岗位是做啥的&#xff0c;想想我自己的工作生涯…

用户/用户组管理

用户管理 * useradd 命令添加用户&#xff0c;会在/etc/passwd生成用户信息&#xff0c;信息分为7列&#xff0c;被6个冒号隔开 第一列 username (login name) 第二列 密码&#xff0c;但是该列已经被移除&#xff0c;用x表示&#xff0c;密码信息已经存放在了/etc/shadow文…

Android以aar包形式引入hunter-debug,Java(3)

Android以aar包形式引入hunter-debug&#xff0c;Java&#xff08;3&#xff09; &#xff08;1&#xff09;首先把hunter的master分支代码拉下来&#xff0c;在本地编译&#xff0c; https://github.com/Leaking/Hunterhttps://github.com/Leaking/Hunter此过程主要目的是获得…

理解学习曲线:芯片工作中的平台价值和个人价值

作为一名芯片工程师&#xff0c;从毕业出到步入公司的第一天开始&#xff0c;需要完成一次明显的转变&#xff0c;随着工作的日益开展和项目推进&#xff0c;个人能力的也得到了潜移默化的提升&#xff0c;当我们回看个人的知识/技能成长的曲线时&#xff0c;可能会发现很多的发…

CMake:递归检查并拷贝所有需要的DLL文件

文章目录 1. 目的2. 设计整体思路多层依赖的处理获取 DLL 所在目录探测剩余的 DLL 文件 3. 代码实现判断 stack 是否为空判断 stack 是否为空获取所有 target检测并拷贝 DLL 4. 使用 1. 目的 在基于 CMake 构建的 C/C 工程中&#xff0c;拷贝当前工程需要的每个DLL文件到 Visu…

将nacos从本地切换到远程服务器上时报错:客户端端未连接,Client not connected

报错信息&#xff1a; 09:34:38.438 [com.alibaba.nacos.client.Worker] ERROR com.alibaba.nacos.common.remote.client - Send request fail, request ConfigBatchListenRequest{headers{charsetUTF-8, Client-AppNameunknown, Client-RequestToken65c0fbf47282ae0a7b85178…

android点击事件,跳转界面

Android 事件处理 1&#xff0c;采用在Activity中创建一个内部类定义点击事件 主要xml代码 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http:…

【SAP Abap】X-DOC:SE37 - ABAP 功能模块之更新模块(Function Module 之 Update module)

【SAP Abap】X-DOC&#xff1a;SE37 - ABAP 功能模块之更新模块&#xff08;Function Module 之 Update module&#xff09; 1、简介1.1、什么是更新函数1.2、更新函数的类型1.3、更新函数的参数要求1.4、更新函数的调用方式1.5、更新函数的调试方式1.6、更新任务的执行模式1.7…

C语言——控制语句

目录 1. 分支语句1.1 if语句1.1.1 基本结构1.1.2 分层结构1.1.3 嵌套结构 1.2 switch case 语句 2.循环语句2.1 for循环2.1.1 基本结构2.1.2 嵌套结构2.1.3 变形 2.2 while循环2.3 do while循环2.4 死循环2.5 循环控制语句 控制语句即用来实现对程序流程的选择、循环、转向和返…

Shiro框架漏洞分析与复现

Shiro简介 Apache Shiro是一款开源安全框架&#xff0c;提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用&#xff0c;同时也能提供健壮的安全性&#xff0c;可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。 1、Shiro反序列…