您的当前位置:首页正文

DDR2程序设计方案

2021-07-04 来源:钮旅网


DDR2程序设计方案

程序设计目标

实现DDR2的读写功能,并且读写正常。

程序设计思路

考虑到直接写DDR2读写时序有困难,所以使用DDR2 IP核。

调用DDR2 IP核,并且为DDR2 IP核生成相应的时钟,根据模块化思想,将读写操作进行封装成模块,在顶层模块为读写模块提供地址与数据。

程序具体设计

根据以上思路需要做到以下几点: 1) 生成DDR2 IP核 2) 基于DDR核的读写模块 3) 顶层模块设计 4) 使用PLL生成时钟

DDR2 IP核的生成过程

打开核生成器

创建一个新的工程

根据工程需要指定工程路径,并且给工程取名。

点击Part选择芯片型号,点击Generation选择语言,点击ok。

找到mig核,并双击,进入DDR2核生成过程。

进入DDR2 IP核的配置界面,核对建立工程时的信息,点击下一步

重新定义”Component Part”,点击下一步

点击下一步

选择DDR2_SDRAM,点击下一步

设置时钟为200M,数据位宽为16

点击此页的”Creat Custom Part”,设置器件名称为k4t1g164qf,此名称可以自由定义并作为DDR2芯片名,在最下方根据芯片手册选择相应的列地址,行地

址以及BANK地址,点击保存,回到之前的页面,点击下一步

选择”Burst Length”为4,点击下一步

“System Clock”选择”Single-Ended”,单端时钟比较好操作,点击下一步。

接下来是DDR2引脚的配置,此时的配置需要明确DDR2在FPGA上的引脚,同时这一步也是检验DDR2引脚在FPGA上分配是否正确的方法。选择”Fixed Pin Out:...”这一选项,点击下一步

将FPGA的引脚标识添加到对应DDR2信号名称的引脚上。多余引脚,先找一些无用的引脚填上,之后再修改ucf文件即可。如果ucf已经存在,也可以使用”ReadUCF”来进行加载,如果引脚有不正确的分配,进行”Valide”时会提示错误。如果无错误,点击下一步

点击下一步

选择”Accept”,点击下一步,之后一直点击下一步,直到最后点击”Generate”,生成DDR2 IP核。

到此DDR2 IP核生成完成。

打开DDR2 IP核所在文件,ucf文件在par目录下,下图是路径,此ucf文件中有之前配置的引脚,其中一些引脚需要修改或删除。

基于DDR2核的读写模块设计

DDR2 IP核信号介绍

DDR2读写需要操作的信号如下: 信号 phy_init_done rst0_tb clk0_tb app_wdf_afull app_af_afull

位宽 1 1 1 1 1 定义 此信号为DDR2初始化信号,此信号为高有效 DDR2操作时的复位信号,此信号高电平有效 DDR2操作时的时钟信号 写数据时FIFO满标志,为1时表示满 写地址时FIFO满标志,为1时表示满

rd_data_valid app_wdf_wren app_af_wren app_af_addr app_af_cmd rd_data_fifo_out app_wdf_data app_wdf_mask_data

DDR2 IP核读写时序分析 写时序分析

1 1 1 31 3 32 32 4 读数据时,数据输出有效标志 写数据使能 写地址使能 地址线,无效的位写1(建议) 命令信号,000为写数据,001为读数据 数据输出端口 写数据时的数据输入线 写入数据时的数据屏蔽信号 此图中的写数据是4突发连续写

图中reset_tb为复位信号,本次生成核的复位信号为rst0_tb,此信号为1表示复位。phy_init_done为DDR2初始化完成信号,如果此信号不为高,表示DDR2核未完成初始化,此时DDR2核无法工作。

在复位无效并且phy_init_done为高的情况下,进行突发写数据。

这里突发长度为4个数据,4个16位的数据,app_wdf_data的位宽为32位,所以需要写两次数据,即图中所示的D1D0,D3D2。地址是4的倍数,如第一个地址为0,第二个地址便为4,之后就是8,12...

读时序分析

在不断写入地址的过程中,数据会在rd_data_valid拉高的时候通过rd_data_fifo_out输出。

不断写入地址,等待rd_data_valid拉高,读rd_data_fifo_out中的数据。 读数据也一样,地址是以4为基数不断累加输入的。

顶层模块设计

顶层模块需要主要完成三个工作:调用DDR2核,使用PLL生成DDR2核所需时钟,为读写模块提供数据与地址。

DDR2核模块需要两个时钟信号,一个是sys_clk,一个是idly_clk_200,这两上时钟都为200M,使用锁相环生。

DDR2核所需要时钟的生成与DDR2核的修改

在DDR2核的内部也调用了一个锁相环,这个文件名为:ddr2_infrastructure.v 如果顶层模块的时钟直接引入到DDR2核中,会产生一系列的问题,修改如下: 将下图中的两个IBUFG名修改为BUFG。

程序测试及程序改进方案

最开始程序按照读写时序图写入四个地址,8个32位的固定数据。

结果发现在rd_data_valid为1的情况下,只有在clk0_tb为低电平的时候数据是写入的数据,即数据分成了16个小段,在clk0_tb高电平时的数据不稳定,在低电平时,数据稳定下来。 结果如下图所示:

改进1:在clk0_tb的上升沿或下降沿去获取数据,查看数据的稳定性。在查一些资料显示,地址不使用的高位需要置1,改进程序中结果如下图所示:

图中,data_fifo_out_p是在clk0_tb上升沿获取数据,data_fifo_out_n是在clk0_tb下降沿获取数据。如上图所示,在下降沿获取的数据比较稳定。

获取的数据过程中是先写地址,数据是随着rd_data_valid变为高后,数据从rd_data_fifo_out中输出,所以将读写模块中读部分只是写入地址,读数据在顶层进行。同时,为了方便操作,读写模块写数据部分只写一次突发的数据,即64位的数据。为了使读取的数据更加稳定,数据进行两次处理:第一次,在时钟下降沿获取rd_data_fifo_out中的值,名称为data_fifo_out_n,第二次,在时钟上升沿获取data_fifo_n的值,取名为data_fifo_p_ff1,data_fifo_p_ff1为最终获取的稳定数据。结果如下图所示:

测试过程中出现问题及分析

问题1:编译失败,锁相环出现问题。

原因:顶层模块调用了锁相环,DDR2 IP核内部也使用了锁相环,两个锁相

环之间的时钟连接有问题。

解决办法:将DDR2 IP核内部锁相环的时钟输入处的IBUFG修改为BUFG. 结果:可以编译通过。

问题2:phy_init_done未变高。

原因:在分配UCF引脚过程中dm引脚分配出错。 解决办法:查看原理图,修改引脚分配。 结果:phy_init_done拉高。

心得与体会

地址:

DDR2的芯片引脚中,数据线是16位,地址线是13位,bank地址是3位。

在核中有列地址(10位),行地址(13位)与bank地址(3位)。

在DDR2的芯片手册中,提到行地址与列地址是重合的。

在对DDR2芯片操作过程中,发现在地址超过16位时,读回的数据将会从0

地址重新开始读。

从这里可以看出,DDR2的有效地址只有16位,但是如果将app_af_addr的

16位之后的地址拉高,会出现pyh_init_done不拉高情况。

数据:

DDR2芯片引脚中数据线是16位,而核中数据线是32位。

在向DDR2中写入数据时,在时钟的上升沿与下降沿都会写入数据。 因为突发长度为4,所有需要连续写入2个32的数据,才会是4个16位的app_af_addr是无效位是列地址+行地址+bank地址之后的位无效。

数据。

读数据:

在读数据之前,需要写入地址与命令。

之后只需要等待rd_data_valid变为高,然后从rd_data_fifo_out中读取

数据即可。

DDR2所有空间读写正确性验证

第1就是查看chipscope,从chipscope查看数据,数据比较稳定,使用chipscope的触发器,查看一定范围的数据,结果数据正常。

读到的数据可能不稳定,此时需要做一些处理。

在时钟的上升沿与下降沿读数据时,下降沿读到的数据比较稳定。 使用时钟的上升沿再去读下降沿时读到的数据,数据是最稳定的。

以上的验证手段不能够完全证明数据是正常的。

第2写入的数据是依次递增的,从数据线上出来的数据是32位数据,高16位与低16位相差为1,如果高16位与低16位的数据相减如果为1,说明高16位与低16位组成的数据是正常的。接下来需要将前一个数据与后一个数据相减,如果结果为20002h,那么就可以证明读回的数据是连续的。这样的话就可以证明读回的数据是正常的。

第3就是将读出的数据,从串口发出,通过串口将数据进行比对。

这种验证方法,如果串口是完全正常的,可以验证DDR2的所有空间读写是否正常。

出现问题:

使用第二种方法进行验证的过程中,使用减法运算会使数据变得不稳定。 修改方法:将减法运算修改为异或运算,这样从chipscope查看到的数据会比较稳定。 极速验证

在全速的情况下写入数据,在全速的情况下读回数据。 判断数据的正确性。

方法:将之前的程序进行修改,将读写数据写到一个模块中。

只要地址FIFO与数据FIFO不为满,那么不断写数据与地址,直到所有地址都写入数据。

之后,只要地址FIFO不为满,那么不断写地址,直到所有地址都访问到。 验证方法:使用以上所述的第二种方法进行验证,数据正常。

因篇幅问题不能全部显示,请点此查看更多更全内容