使用Vivado 2015.4在Nexys4 DDR开发板上实现DDR的读写例程.doc

上传人:白大夫 文档编号:3382103 上传时间:2019-08-20 格式:DOC 页数:6 大小:29KB
返回 下载 相关 举报
使用Vivado 2015.4在Nexys4 DDR开发板上实现DDR的读写例程.doc_第1页
第1页 / 共6页
亲,该文档总共6页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《使用Vivado 2015.4在Nexys4 DDR开发板上实现DDR的读写例程.doc》由会员分享,可在线阅读,更多相关《使用Vivado 2015.4在Nexys4 DDR开发板上实现DDR的读写例程.doc(6页珍藏版)》请在三一文库上搜索。

1、使用Vivado 2015.4在Nexys4 DDR开发板上实现DDR的读写例程最近项目需要用到DDR,于是在网上找相关资料,发现网上关于Xilinx DDR的资料不多,而且比较老,官方文档又是纯英文,且超级长。所以笔者写了这篇文章,为像笔者一样的初学者介绍一下DDR的使用。在此不介绍DDR是什么了,请自行查资料。(相信用到这篇文章的人不会不知道DDR是啥吧。)好了,闲话休提言归正传。本文使用Vivado 2015.4在Nexys4 DDR(以下简称N4DDR)开发板上实现DDR的读写。FPGA如果需要对DDR进行读写,则需要一个DDR的控制器。根据官方的文档(UG586,下载链接在文末),D

2、DR控制器的时序主要有三:(1)首先是控制信号,如下图:从上图可以看出,只有当app_rdy信号有效时,程序所发出的读写命令才会被控制器接收。这点必须注意。(2)然后是写操作时序,如下图:由图可知,在向DDR写数据时,需要提供写命令app_cmd、地址app_addr、数据app_wdf_data等信号,且写入的数据最多可以比app_cmd提前一个时钟周期有效,最迟可以比app_cmd晚两个时钟周期有效。【特别注意】在写数据的时候必须检测app_rdy和app_wdf_rdy信号是否同时有效,否则写入命令无法成功写入到DDR控制器的命令FIFO中,从而导致写操作失败。(3)最后是读操作时序,如

3、下图所示:读操作的时序比较简单,只需要注意app_rdy是否有效即可,其余不再赘述。Xilinx在Vivado中提供的Memory Interface Generator的IP核就是我们需要的DDR控制器,如下图所示。这里我们可以直接双击上面的MIG的IP核,开始例化我们所需的DDR控制器。(此时Win7以后的Windows版本(不含Win7)打开此IP核会报错,解决方法见 )打开后是如下图所示的界面,点Next。给模块起个名字,根据实际情况选择控制器数量(这里笔者选择1),继续Next,如下图所示。在开发板芯片型号所对应的方框前打勾,如下图所示。根据开发板上的DDR芯片选择DDR的种类,如N

4、4DDR的开发板上的DDR芯片是DDR2的,因此如下图选择。然后在Clock Period中输入合适的时钟周期长度(N4DDR的官方文档建议DDR的时钟为325MHz,故此处填3077ps);接着在Memory Part中选择开发板上的DDR芯片的具体型号(N4DDR官方文档上说明为MT47H64M16HR-25E);然后输入Data Width,此处以16为例。如下图所示。选择Input Clock Period,这里填开发板的系统时钟(N4DDR为100MHz)。根据应用需要选择地址映射方式(这里保持默认的Bank-Row-Column)。然后,这里的System Clock、Refere

5、nce Clock建议选择No Buffer,System Reset Polarity则根据应用需要灵活选择(这里设置为低电平有效),如下图所示。Internal Termination Impedence的选取应当参考开发板的官方文档说明,这里选50欧姆即可,继续Next。选择Fixed Pin Out。接下来是DDR芯片的引脚分配。官网应该能找到,这里直接给出。文末会给出与此对应的引脚约束文件(n4ddr_ddr2_io_assign.ucf)。耐心填完之后点击Validate按钮,没有错误的话会弹出一个对话框提示“Current Pinout is valid.”然后的3个信号建议选择

6、No connect,后面由我们自己根据需要连接到板上的相应引脚。后面一直Next下去,点Accept,然后就可以点击Generate了。后面会再弹出一个对话框,直接点默认选中的按钮即可。好了,下面是笔者自己编写的测试DDR2读写的程序。文末将提供对应工程的下载链接。/*/ Author : Z.M.J. CSE, SEU/ Application : MIG v2.4/ Filename : example_top.v/ Date Created : Fri Dec 30 2016/ Device : 7 Series (Nexys 4 DDR)/ Design Name : DDR2 SD

7、RAM/ Purpose : A demo of DDR2s read and write/ Reference : ug586_7Series_MIS_v2.4.pdf/*timescale 1ps/1psmodule example_top (/ system signalsinput sys_rst,input sys_clk_i,/ application signalsinput 15:0 switch_i,output 15:0 led,output 7:0 an,output 7:0 select_seg,/ DDR2 chip signalsinout 15:0 ddr2_dq

8、,inout 1:0 ddr2_dqs_n,inout 1:0 ddr2_dqs_p,output 12:0 ddr2_addr,output 2:0 ddr2_ba,output ddr2_ras_n,output ddr2_cas_n,output ddr2_we_n,output 0:0 ddr2_ck_p,output 0:0 ddr2_ck_n,output 0:0 ddr2_cke,output 0:0 ddr2_cs_n,output 1:0 ddr2_dm,output 0:0 ddr2_odt);parameter DQ_WIDTH = 16;parameter ECC_TE

9、ST = OFF;parameter ADDR_WIDTH = 27;parameter nCK_PER_CLK = 4;localparam DATA_WIDTH = 16;localparam PAYLOAD_WIDTH = (ECC_TEST = OFF) ? DATA_WIDTH : DQ_WIDTH;localparam APP_DATA_WIDTH = 2 * nCK_PER_CLK * PAYLOAD_WIDTH;localparam APP_MASK_WIDTH = APP_DATA_WIDTH / 8;/ Wire declarationsreg app_en, app_wd

10、f_wren, app_wdf_end;reg 2:0 app_cmd;reg ADDR_WIDTH-1:0 app_addr;reg APP_DATA_WIDTH-1:0 app_wdf_data;wire APP_DATA_WIDTH-1:0 app_rd_data;wire APP_MASK_WIDTH-1:0 app_wdf_mask;wire app_rdy, app_rd_data_end, app_rd_data_valid, app_wdf_rdy;/*wire 7:0 an;wire 7:0 select_seg;reg 31:0 digit_data;always (pos

11、edge sys_clk_i) beginif (switch_i3)digit_data = app_addr;else case (switch_i1:0)2b00 : digit_data = read_data31:0;2b01 : digit_data = read_data63:32;2b10 : digit_data = read_data95:64;2b11 : digit_data = read_data127:96;endcaseenddigit U2(.wb_clk_i(sys_clk_i),.wb_rst_i(sys_rst),.wb_dat_i(digit_data)

12、,.an(an),.select_seg(select_seg);reg 1:0 read_valid = 2b0;reg 127:0 read_data = 128h0;always (posedge app_rd_data_valid) beginread_data = app_rd_data;read_valid0 = (app_rd_data = data0);read_valid1 = (app_rd_data = data1);endassign led15 = app_en;assign led14 = init_calib_complete;assign led13 = app

13、_rdy;assign led12 = app_wdf_rdy;assign led4 = sys_rst ? read_valid1 : 1b0;assign led3 = sys_rst ? read_valid0 : 1b0;assign led2 = stop_w1;assign led1 = stop_w0;assign led0 = app_cmd0;reg 15:0 counter = 16h0;parameter cnt_init = 16h1; / minimum: 1reg 26:0 addr0 = 27h000_0008;reg 26:0 addr1 = 27h003_0

14、100;reg 127:0 data0 = 128h1111_2222_3333_4444_5555_6666_7777_8888;reg 127:0 data1 = 128h9999_0000_aaaa_bbbb_cccc_dddd_eeee_ffff;reg 1:0 stop_w = 2b00;always (posedge sys_clk_i or negedge sys_rst) beginif (sys_rst = 1b0) begincounter = 12b0;stop_w = 2b0;app_en = 1b0;app_addr = 27h0;app_cmd = 3b1;app_

15、wdf_data = 128h0;app_wdf_end = 1b0;app_wdf_wren = 1b0;end else beginif (counter = cnt_init app_addr = addr0;app_cmd = 3b0;app_wdf_wren = 1b1;app_wdf_end = 1b1;app_en = 1b1;end else / Hold specific signals until app_wdf_rdy is asserted.counter = counter - 16h1;else if (counter = cnt_init + 1 b0;app_w

16、df_wren = 1b0;app_en = 1b0;app_cmd = 3b1;stop_w0 = 1b1;end else / Hold specific signals until app_wdf_rdy is asserted.counter = counter - 16h1;else if (counter = cnt_init + 8 app_addr = addr1;app_cmd = 3b0;app_wdf_wren = 1b1;app_wdf_end = 1b1;app_en = 1b1;end else / Hold specific signals until app_w

17、df_rdy is asserted.counter = counter - 16h1;else if (counter = cnt_init + 9 b0;app_wdf_wren = 1b0;app_en = 1b0;app_cmd = 3b1;stop_w1 = 1b1;end else / Hold specific signals until app_wdf_rdy is asserted.counter = counter - 16h1;else if (counter = cnt_init + 88) beginapp_addr = switch_i2 ? addr1 : add

18、r0;app_en = 1b1;if (app_rdy) counter = counter - 16h1;end else if (counter = cnt_init + 89)app_en = 1b0;counter = counter + 16h1;endend/ Start of User Design top instance/*/ The User design is instantiated below. The memory interface ports are/ connected to the top-level and the application interfac

19、e ports are/ connected to the traffic generator module. This provides a reference/ for connecting the memory controller to system./*my_ddr u_my_ddr (/ Memory interface ports.ddr2_cs_n (ddr2_cs_n),.ddr2_addr (ddr2_addr),.ddr2_ba (ddr2_ba),.ddr2_we_n (ddr2_we_n),.ddr2_ras_n (ddr2_ras_n),.ddr2_cas_n (d

20、dr2_cas_n),.ddr2_ck_n (ddr2_ck_n),.ddr2_ck_p (ddr2_ck_p),.ddr2_cke (ddr2_cke),.ddr2_dq (ddr2_dq),.ddr2_dqs_n (ddr2_dqs_n),.ddr2_dqs_p (ddr2_dqs_p),.ddr2_dm (ddr2_dm),.ddr2_odt (ddr2_odt),/ Application interface ports.app_addr (app_addr),.app_cmd (app_cmd),.app_en (app_en),.app_wdf_rdy (app_wdf_rdy),

21、.app_wdf_data (app_wdf_data),.app_wdf_end (app_wdf_end),.app_wdf_wren (app_wdf_wren),.app_rd_data (app_rd_data),.app_rd_data_end (app_rd_data_end),.app_rd_data_valid (app_rd_data_valid),.app_rdy (app_rdy),.app_sr_req (1b0),.app_ref_req (1b0),.app_zq_req (1b0),.app_wdf_mask (16h0000),.init_calib_comp

22、lete (init_calib_complete),/ System Clock Ports.sys_clk_i (sys_clk_i),/ Reference Clock Ports.clk_ref_i (sys_clk_i),.sys_rst (sys_rst);endmodule保存后直接生成比特流就可以下板验证了。在摸索过程中笔者发现,写入了数据之后最快要到发出写命令的第8个系统时钟才能读出所写入的数据,且读操作必须在写操作后经过8的整数倍个时钟后进行。有时将比特流下载到N4DDR上面之后读写的数据有误,但是重启开发板再重新下载即可解决问题,知道个中缘由的朋友欢迎在评论中告知笔者,笔者在此先行谢过。需要说明的是,此处突发长度(BL)为8,因此app_addr必须是8对齐的地址。同时,由于前面选择的Data Width为16,因此每次读写数据的长度为8*16bit=128bit。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1