基本上要先看 DDR IP Cores User`s Guide.
文档 的下载地址(http://www.latticesemi.com/~/media/Documents/Solutions/Technology%20Solutions/ipug35_DDR_DDR2_SDRAM_Cont_PLinedUG.pdf)
在 操作DDR 之前, 需要把 init_start 拉高, 等 init_done 被core 拉高之后, 就可以把 init_start 拉低。
always @(posedge clk or negedge rst_n) begin if (~rst_n) begin init_start <= 1'b0; inited <= 1'b0; end else if ((~init_start) & (~inited)) init_start <= 1'b1; else if (init_done & init_start) begin init_start <= 1'b0; inited <= 1'b1; end end
当 inited 被拉高之后, 就可以 操作 DDR了。
一、写 DDR:
等cmd_rdy 被拉高之后, 同时,cmd 赋值为 4’d2,拉高cmd_valid,把地址赋值.
4'd0: begin /// 555 write_req <= 1'b1; if (write_req & cmd_rdy) begin // 44 // data_rdy if ((col_addr_wr == MAX_COL - BST) && (row_addr_wr[12: 0] != MAX_ROW)) row_addr_wr <= row_addr_wr + 13'h1; if (col_addr_wr == MAX_COL -BST) col_addr_wr <= 9'h0; else col_addr_wr <= col_addr_wr + BST; end//// 44 if (row_addr_wr == 13'd7) begin // 33 state <= 4'h1; bank_addr_wr <= 2'b0; row_addr_wr <= 13'b0; col_addr_wr <= 9'b0; write_req <= 1'b0; #(200*c) ; end /// 33 end/////// 555等到 data_rdy 被拉高之后, 就可以把数据 发给 ddr了。
二、 读DDR:
等cmd_rdy 被拉高之后, 同时,cmd 赋值为 4’d1,拉高cmd_valid,把地址赋值.
4'd1: begin // 22 read_req <= 1'b1; if (cmd_rdy) begin // 11 if ((col_addr_wr == MAX_COL - BST) && (row_addr_wr[12: 0] != MAX_ROW)) row_addr_wr <= row_addr_wr + 13'h1; if (col_addr_wr == MAX_COL -BST) col_addr_wr <= 9'h0; else col_addr_wr <= col_addr_wr + BST; /// BST.. end // 11 end // 22等到 read_data_valid被拉高,就代表有数据出来。
这几天来一直都在折腾一件小事, 为什么 可以把数据 写进 DDR_IP, 在读DDR的时候, read_data_valid 一直为低电平, 不被拉高。 我就把 IP自带的test_mem_ctrl.v改写,一直不停滴改, 改到和我自己写的 tb 基本一致的时候,我写的 tb还是有问题, 读不出 数据。就在 绝望时刻, 问了下网友军仔,感谢他。
要在 testbench中加上 `include "tb_config_params.v" 才可以,原因不详。 可能和 mem_db_width_32 这个模块有关系。 还望路过的大神 指点一二。
最后 附上我的源码。
http://download.csdn.net/detail/angelbosj/7823189