程序设计方案.docx
《程序设计方案.docx》由会员分享,可在线阅读,更多相关《程序设计方案.docx(17页珍藏版)》请在冰豆网上搜索。
程序设计方案
DDR2程序设计方案
程序设计目标
实现DDR2的读写功能,并且读写正常。
程序设计思路
考虑到直接写DDR2读写时序有困难,所以使用DDR2IP核。
调用DDR2IP核,并且为DDR2IP核生成相应的时钟,根据模块化思想,将读写操作进行封装成模块,在顶层模块为读写模块提供地址与数据。
程序具体设计
根据以上思路需要做到以下几点:
1)生成DDR2IP核
2)基于DDR核的读写模块
3)顶层模块设计
4)使用PLL生成时钟
DDR2IP核的生成过程
打开核生成器
创建一个新的工程
根据工程需要指定工程路径,并且给工程取名。
点击Part选择芯片型号,点击Generation选择语言,点击ok。
找到mig核,并双击,进入DDR2核生成过程。
进入DDR2IP核的配置界面,核对建立工程时的信息,点击下一步
重新定义”ComponentPart”,点击下一步
点击下一步
选择DDR2_SDRAM,点击下一步
设置时钟为200M,数据位宽为16
点击此页的”CreatCustomPart”,设置器件名称为k4t1g164qf,此名称可以自由定义并作为DDR2芯片名,在最下方根据芯片手册选择相应的列地址,行地址以与BANK地址,点击保存,回到之前的页面,点击下一步
选择”BurstLength”为4,点击下一步
“SystemClock”选择”Single-Ended”,单端时钟比较好操作,点击下一步。
接下来是DDR2引脚的配置,此时的配置需要明确DDR2在FPGA上的引脚,同时这一步也是检验DDR2引脚在FPGA上分配是否正确的方法。
选择”FixedPinOut:
...”这一选项,点击下一步
将FPGA的引脚标识添加到对应DDR2信号名称的引脚上。
多余引脚,先找一些无用的引脚填上,之后再修改ucf文件即可。
如果ucf已经存在,也可以使用”ReadUCF”来进行加载,如果引脚有不正确的分配,进行”Valide”时会提示错误。
如果无错误,点击下一步
点击下一步
选择”Accept”,点击下一步,之后一直点击下一步,直到最后点击”Generate”,生成DDR2IP核。
到此DDR2IP核生成完成。
打开DDR2IP核所在文件,ucf文件在par目录下,下图是路径,此ucf文件中有之前配置的引脚,其中一些引脚需要修改或删除。
基于DDR2核的读写模块设计
DDR2IP核信号介绍
DDR2读写需要操作的信号如下:
信号
位宽
定义
phy_init_done
1
此信号为DDR2初始化信号,此信号为高有效
rst0_tb
1
DDR2操作时的复位信号,此信号高电平有效
clk0_tb
1
DDR2操作时的时钟信号
app_wdf_afull
1
写数据时FIFO满标志,为1时表示满
app_af_afull
1
写地址时FIFO满标志,为1时表示满
rd_data_valid
1
读数据时,数据输出有效标志
app_wdf_wren
1
写数据使能
app_af_wren
1
写地址使能
app_af_addr
31
地址线,无效的位写1(建议)
app_af_cmd
3
命令信号,000为写数据,001为读数据
rd_data_fifo_out
32
数据输出端口
app_wdf_data
32
写数据时的数据输入线
app_wdf_mask_data
4
写入数据时的数据屏蔽信号
DDR2IP核读写时序分析
写时序分析
此图中的写数据是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:
编译失败,锁相环出现问题。
原因:
顶层模块调用了锁相环,DDR2IP核内部也使用了锁相环,两个锁相环之间的时钟连接有问题。
解决办法:
将DDR2IP核内部锁相环的时钟输入处的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不拉高情况。
app_af_addr是无效位是列地址+行地址+bank地址之后的位无效。
数据:
DDR2芯片引脚中数据线是16位,而核中数据线是32位。
在向DDR2中写入数据时,在时钟的上升沿与下降沿都会写入数据。
因为突发长度为4,所有需要连续写入2个32的数据,才会是4个16位的数据。
读数据:
在读数据之前,需要写入地址与命令。
之后只需要等待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不为满,那么不断写地址,直到所有地址都访问到。
验证方法:
使用以上所述的第二种方法进行验证,数据正常。