读写时序:
(1)命令路径:
写命令路径:
1-77:上面是dq=8bit;BL=8表示8突发;那么每次最多只能写64bit------->app_wdf_data(64bit);一个时钟写一个64bit。说明这每写入一次,既是第一个数据也是最后一个数据------>所以app_wdf_end每写一个就拉高一次。
4:1的含义是传输速率的比值关系:64bit,BL=8,ddr(双沿)只需要4个时钟周期,而64bit(app_wdf_data)用户只用1个时钟写数据(写入ddr3的时钟ddr3_ck_p,ddr3_ck_n为400MHz,则ui_clk = 100M)
1-76:app_wdf_data(32bit),而dq=8bit,BL=8,每次突发要写入64bit,则需要一个命令写两次。
app_wdf_end则在第二个数据据写入才拉高。
2:1的含义是传输速率的比值关系:64bit,BL=8,ddr(双沿)只需需要4个时钟周期写入到ddr3,而64bitt(app_wdf_data)用户只用2个时钟写数据(写入ddr3的时钟ddr3_ck_p,ddr3_ck_n为400MHz,则ui_clk = 200M)
下图是:dq=16bit(一次写入ddr的位数);
写数据仿真:
可以看出写入两次数据,app_addr每次加8;
读数据仿真:
可以看到app_cmd由0变为1,并且在rd_trig信号拉高后,app_en拉高,app_rdy在app_en拉低前拉高,写入有效命令。
读一次,读出数据为256‘d1;
module ddr3_drive(
//system signals
input sys_clk_p ,
input sys_clk_n ,
input s_rst_n ,
//DDR3 Interference
output wire[14:0] ddr3_addr ,
output wire[2:0] ddr3_ba ,
output wire ddr3_cas_n ,
output wire [0:0] ddr3_ck_n ,
output wire [0:0] ddr3_ck_p ,
output wire [0:0] ddr3_cke ,
output wire ddr3_ras_n ,
output wire ddr3_reset_n ,
output wire ddr3_we_n ,
inout wire[31:0] ddr3_dq ,
inout wire[3:0] ddr3_dqs_n ,
inout wire[3:0] ddr3_dqs_p ,
output wire[0:0] ddr3_cs_n ,
output wire[3:0] ddr3_dm ,
output wire[0:0] ddr3_odt ,
input wire wr_trig ,
input wire rd_trig
);
//=====================================================================
//============Define parameter and Interference signal======
//=====================================================================
localparam CMD_WR = 3'h0 ;//写命令
localparam CMD_RD = 3'h1 ;//读命令
wire init_calib_complete ;
wire ui_clk ;
wire ui_clk_sync_rst ;
reg app_en ;
wire app_rdy ;
reg[2:0] app_cmd ;
wire[28:0] app_addr ;
reg[28:0] rd_addr ;
reg[28:0] wr_addr ;
reg app_wdf_wren ;
wire app_wdf_rdy ;
wire app_wdf_end ;
reg[255:0] app_wdf_data ;
wire[31:0] app_wdf_mask ;
//=====================================================================
//=======================main code=====================================
//=====================================================================
//assign app_cmd = 3'd0 ;
//assign app_addr = 'd0 ;
//assign app_wdf_data= 256'h00_01_03_04_05_06_07_08_09;
assign app_wdf_end = app_wdf_wren;
assign app_wdf_mask= 32'h0 ;
assign app_addr = (app_rdy == 1'b1 && app_cmd == CMD_WR)?wr_addr:rd_addr;
//app_cmd
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
app_cmd <= CMD_WR;
else if(wr_trig == 1'b1)
app_cmd <= CMD_WR;
else if(rd_trig == 1'b1)
app_cmd <= CMD_RD;
//app_en
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
app_en <= 1'b0;
else if(wr_trig == 1'b1)
app_en <= 1'b1;
else if(rd_trig == 1'b1)
app_en <= 1'b1;
else if(app_rdy == 1'b1)
app_en <= 1'b0;
//wr_addr
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
wr_addr <= 'd0;
else if(app_rdy == 1'b1 && app_en == 1'b1 && app_cmd == CMD_WR)
wr_addr <= wr_addr + 'd8;
//rd_addr
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
rd_addr <= 'd0;
else if(app_rdy == 1'b1 && app_en == 1'b1&& app_cmd == CMD_RD)
rd_addr <= rd_addr + 'd8;
//app_wdf_wren
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
app_wdf_wren <= 1'b0;
else if(wr_trig == 1'b1)
app_wdf_wren <= 1'b1;
else if(app_rdy == 1'b1)
app_wdf_wren <= 1'b0;
//app_wdf_data
always @(posedge ui_clk or negedge ui_clk_sync_rst)
if(ui_clk_sync_rst==1'b1)
app_wdf_data <= 256'h1;
else if(app_rdy == 1'b1 && app_en == 1'b1)
app_wdf_data <= app_wdf_data + 1'b1;
mig_7series_0 u_mig_7series_0 (
// Memory interface ports
.ddr3_addr (ddr3_addr), // output [14:0] ddr3_addr
.ddr3_ba (ddr3_ba), // output [2:0] ddr3_ba
.ddr3_cas_n (ddr3_cas_n), // output ddr3_cas_n
.ddr3_ck_n (ddr3_ck_n), // output [0:0] ddr3_ck_n
.ddr3_ck_p (ddr3_ck_p), // output [0:0] ddr3_ck_p
.ddr3_cke (ddr3_cke), // output [0:0] ddr3_cke
.ddr3_ras_n (ddr3_ras_n), // output ddr3_ras_n
.ddr3_reset_n (ddr3_reset_n), // output ddr3_reset_n
.ddr3_we_n (ddr3_we_n), // output ddr3_we_n
.ddr3_dq (ddr3_dq), // inout [31:0] ddr3_dq
.ddr3_dqs_n (ddr3_dqs_n), // inout [3:0] ddr3_dqs_n
.ddr3_dqs_p (ddr3_dqs_p), // inout [3:0] ddr3_dqs_p
.init_calib_complete (init_calib_complete), // output init_calib_complete
.ddr3_cs_n (ddr3_cs_n), // output [0:0] ddr3_cs_n
.ddr3_dm (ddr3_dm), // output [3:0] ddr3_dm
.ddr3_odt (ddr3_odt), // output [0:0] ddr3_odt
// Application interface ports
.app_addr (app_addr), // input [28:0] app_addr
.app_cmd (app_cmd), // input [2:0] app_cmd
.app_en (app_en), // input app_en
.app_wdf_data (app_wdf_data), // input [255:0] app_wdf_data
.app_wdf_end (app_wdf_end), // input app_wdf_end
.app_wdf_wren (app_wdf_wren), // input app_wdf_wren
.app_rd_data (app_rd_data), // output [255:0] app_rd_data
.app_rd_data_end (app_rd_data_end), // output app_rd_data_end
.app_rd_data_valid (app_rd_data_valid), // output app_rd_data_valid
.app_rdy (app_rdy), // output app_rdy
.app_wdf_rdy (app_wdf_rdy), // output app_wdf_rdy
.app_sr_req (app_sr_req), // input app_sr_req
.app_ref_req (app_ref_req), // input app_ref_req
.app_zq_req (app_zq_req), // input app_zq_req
.app_sr_active (app_sr_active), // output app_sr_active
.app_ref_ack (app_ref_ack), // output app_ref_ack
.app_zq_ack (app_zq_ack), // output app_zq_ack
.ui_clk (ui_clk), // output ui_clk
.ui_clk_sync_rst (ui_clk_sync_rst), // output ui_clk_sync_rst
.app_wdf_mask (app_wdf_mask), // input [31:0] app_wdf_mask
// System Clock Ports
.sys_clk_p (sys_clk_p), // input sys_clk_p
.sys_clk_n (sys_clk_n), // input sys_clk_n
.sys_rst (s_rst_n) // input sys_rst
);
endmodule
`timescale 1ps / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/06/17 15:07:19
// Design Name:
// Module Name: tb_ddr3_drive
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_ddr3_drive();
parameter CLKIN_PERIOD = 5000;
localparam RESET_PERIOD = 200000; //in pSec
parameter CS_WIDTH = 1;
parameter DQ_WIDTH = 32;
localparam MEMORY_WIDTH = 16;
localparam NUM_COMP = DQ_WIDTH/MEMORY_WIDTH;
parameter DM_WIDTH = 4;
parameter DQS_WIDTH = 4;
reg sys_clk_i;
wire sys_clk_p;
wire sys_clk_n;
reg s_rst_n;
reg wr_trig;
reg rd_trig;
initial begin
s_rst_n <= 1'b0;
wr_trig <= 1'b0;
rd_trig <= 1'b0;
#RESET_PERIOD
s_rst_n <= 1'b1;
@(posedge ddr3_drive_inst.init_calib_complete)
#100_000
wr_trig <= 1'b1;
#10_000
wr_trig <= 1'b0;
#10_000
wr_trig <= 1'b1;
#10_000
wr_trig <= 1'b0;
#100_000
rd_trig <= 1'b1;
#10_000
rd_trig <= 1'b1;
end
initial
sys_clk_i = 1'b0;
always
sys_clk_i = #(CLKIN_PERIOD/2.0) ~sys_clk_i;
assign sys_clk_p = sys_clk_i;
assign sys_clk_n = ~sys_clk_i;
//--------------------------------------------------
wire ddr3_ck_p_sdram;
wire ddr3_ck_n_sdram;
wire ddr3_cke_sdram;
wire [(CS_WIDTH*1)-1:0] ddr3_cs_n_sdram;
wire ddr3_ras_n_sdram;
wire ddr3_cas_n_sdram;
wire ddr3_we_n_sdram;
wire [DM_WIDTH-1:0] ddr3_dm_sdram;
wire [2:0] ddr3_ba_sdram;
wire [14:0] ddr3_addr_sdram;
wire [DQ_WIDTH-1:0] ddr3_dq_sdram;
wire [3:0] ddr3_dqs_p_sdram;
wire [3:0] ddr3_dqs_n_sdram;
wire ddr3_odt_sdram;
wire ddr3_reset_n;
ddr3_drive ddr3_drive_inst(
//system signals
.sys_clk_p (sys_clk_p ),
.sys_clk_n (sys_clk_n ),
. s_rst_n ( s_rst_n ),
//DDR3 Interference
.ddr3_addr (ddr3_addr_sdram ),
.ddr3_ba (ddr3_ba_sdram ),
.ddr3_cas_n (ddr3_cas_n_sdram ),
.ddr3_ck_n (ddr3_ck_n_sdram ),
.ddr3_ck_p (ddr3_ck_p_sdram ),
.ddr3_cke (ddr3_cke_sdram ),
.ddr3_ras_n (ddr3_ras_n_sdram ),
.ddr3_reset_n (ddr3_reset_n),
.ddr3_we_n (ddr3_we_n_sdram ),
.ddr3_dq (ddr3_dq_sdram ),
.ddr3_dqs_n (ddr3_dqs_n_sdram ),
.ddr3_dqs_p (ddr3_dqs_p_sdram ),
.ddr3_cs_n (ddr3_cs_n_sdram ),
.ddr3_dm (ddr3_dm_sdram ),
.ddr3_odt (ddr3_odt_sdram ),
.wr_trig (wr_trig ),
.rd_trig (rd_trig )
);
genvar i;
generate
for (i = 0; i < NUM_COMP; i = i + 1) begin: gen_mem
ddr3_model u_comp_ddr3
(
.rst_n (ddr3_reset_n),
.ck (ddr3_ck_p_sdram),
.ck_n (ddr3_ck_n_sdram),
.cke (ddr3_cke_sdram),
.cs_n (ddr3_cs_n_sdram),
.ras_n (ddr3_ras_n_sdram),
.cas_n (ddr3_cas_n_sdram),
.we_n (ddr3_we_n_sdram),
.dm_tdqs (ddr3_dm_sdram[(2*(i+1)-1):(2*i)]),
.ba (ddr3_ba_sdram),
.addr (ddr3_addr_sdram),
.dq (ddr3_dq_sdram[16*(i+1)-1:16*(i)]),
.dqs (ddr3_dqs_p_sdram[(2*(i+1)-1):(2*i)]),
.dqs_n (ddr3_dqs_n_sdram[(2*(i+1)-1):(2*i)]),
.tdqs_n (),
.odt (ddr3_odt_sdram)
);
end
endgenerate
endmodule