【DDR3 控制器设计】(2)DDR3 初始化测试

时间:2022-10-14 10:02:23

目录

实验任务

实验环境

实验介绍

程序设计

创建顶层文件

testbench 代码

仿真测试


实验任务

对 DDR3 进行初始化测试,通过前面调取的 MIG IP核共同完成测试。

实验环境

开发环境:Vivado 2018.2

FPGA 芯片型号:xc7a100tffg484-2

DDR3 型号:MT41J256M16HA-125

实验介绍

由于在使用 DDR3 控制器 MIG 时,在刚上电的时候不能立即进行读写操作,而是要等待一段时间(大概100us),等待 DDR3 控制器 MIG IP核初始化完成后,才可以开始进行读写操作,这个实验的目的就是对 DDR3 控制器进行初始化测试。

程序设计

创建顶层文件

需要注意的是,由于板子上提供的时钟为 50MHz,而在 MIG IP 配置时,输入的系统系统时钟为 200MHz,因此需要添加一个 PLL IP 核对输入的时钟进行倍频到 200MHz。

配置如下,调用并在顶层文件中对其进行例化。

【DDR3 控制器设计】(2)DDR3 初始化测试

具体代码如下:

暂时不用的信号比如读使能、地址等信号可以直接给赋值即可。

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Engineer    : Linest-5                                                         
/* File        : top_ddr3_init.v                                                         
/* Create      : 2022-09-15 09:58:59
/* Revise      : 2022-09-25 11:27:52                                                  
/* Module Name : top_ddr3_init                                                  
/* Description : ddr3初始化顶层模块                                                                         
/* Editor : sublime text3, tab size (2)                                                                                
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module top_ddr3_init(
	// Inouts
  	inout [15:0]       ddr3_dq,
  	inout [1:0]        ddr3_dqs_n,
  	inout [1:0]        ddr3_dqs_p,
  	// Outputs
  	output [14:0]      ddr3_addr,
  	output [2:0]       ddr3_ba,
  	output             ddr3_ras_n,
  	output             ddr3_cas_n,
  	output             ddr3_we_n,
  	output             ddr3_reset_n,
  	output [0:0]       ddr3_ck_p,
  	output [0:0]       ddr3_ck_n,
  	output [0:0]       ddr3_cke,
  	output [0:0]       ddr3_cs_n,
  	output [1:0]       ddr3_dm,
  	output [0:0]       ddr3_odt,
	  // Inputs
	  // Differential system clocks
	  input              sys_clk,
	  input              rst_n
    );
	
wire                   init_calib_complete;
wire                   ui_clk;
wire                   ui_clk_sync_rst;

ddr3_clock ddr3_clock_inst(
    // Clock out ports
    .clk_out1(sys_clk_in),     // output clk_out1
   // Clock in ports
    .clk_in1(sys_clk)
);      // input clk_in1

ddr3_init u_ddr3_init (

    // 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 [15:0]		ddr3_dq
    .ddr3_dqs_n                     (ddr3_dqs_n),  // inout [1:0]		ddr3_dqs_n
    .ddr3_dqs_p                     (ddr3_dqs_p),  // inout [1: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 [1: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                         (1'b0),  // input				app_en
    .app_wdf_data                   (app_wdf_data),  // input [127:0]		app_wdf_data
    .app_wdf_end                    (1'b0),  // input				app_wdf_end
    .app_wdf_wren                   (1'b0),  // input				app_wdf_wren
    .app_rd_data                    (app_rd_data),  // output [127: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                     (1'b0),  // input			app_sr_req
    .app_ref_req                    (1'b0),  // input			app_ref_req
    .app_zq_req                     (1'b0),  // 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 [15:0]		app_wdf_mask
    // System Clock Ports
    .sys_clk_i                      (sys_clk_in),  // input			sys_clk_i
    .sys_rst                        (rst_n) // input sys_rst
    );

endmodule

testbench 代码

在 example design 中 调用 DDR3 的仿真模型,将这两个文件放到仿真文件中,并在 Vivado 添加调用。

【DDR3 控制器设计】(2)DDR3 初始化测试

以下为测试代码,主要就是例化顶层文件,产生时钟和复位激励,并需要例化 DDR3 的仿真模型,否则仿真无法实现!

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Engineer    : Linest-5                                                             
// File        : tb_top_ddr3_init.v                                                              
// Create      : 2022-09-25 15:20:55                                                   
// Revise      : 2022-09-25 15:20:57                                                  
// Module Name : tb_top_ddr3_init                                                                 
// Description : ddr3初始化顶层测试模块                                                                         
// Editor : sublime text3, tab size (4)                                                                                                 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
`timescale 1ns / 1ps

module tb_top_ddr3_init();

reg                sys_clk;
reg                rst_n;

wire  [15:0]       ddr3_dq;
wire  [1:0]        ddr3_dqs_n;
wire  [1:0]        ddr3_dqs_p;
wire  [14:0]       ddr3_addr;
wire  [2:0]        ddr3_ba;
wire               ddr3_ras_n;
wire               ddr3_cas_n;
wire               ddr3_we_n;
wire               ddr3_reset_n;
wire  [0:0]        ddr3_ck_p;
wire  [0:0]        ddr3_ck_n;
wire  [0:0]        ddr3_cke;
wire  [0:0]        ddr3_cs_n;
wire  [1:0]        ddr3_dm;
wire  [0:0]        ddr3_odt;

initial begin
	sys_clk  = 'd1;
	rst_n   <= 'd0;
	#200
	rst_n   <= 'd1;
end

always #10 sys_clk = ~sys_clk;

top_ddr3_init inst_top_ddr3_init (
		.ddr3_dq      (ddr3_dq),
		.ddr3_dqs_n   (ddr3_dqs_n),
		.ddr3_dqs_p   (ddr3_dqs_p),
		.ddr3_addr    (ddr3_addr),
		.ddr3_ba      (ddr3_ba),
		.ddr3_ras_n   (ddr3_ras_n),
		.ddr3_cas_n   (ddr3_cas_n),
		.ddr3_we_n    (ddr3_we_n),
		.ddr3_reset_n (ddr3_reset_n),
		.ddr3_ck_p    (ddr3_ck_p),
		.ddr3_ck_n    (ddr3_ck_n),
		.ddr3_cke     (ddr3_cke),
		.ddr3_cs_n    (ddr3_cs_n),
		.ddr3_dm      (ddr3_dm),
		.ddr3_odt     (ddr3_odt),
		.sys_clk      (sys_clk),
		.rst_n        (rst_n)
	);

ddr3_model u_comp_ddr3 (
		.rst_n   (ddr3_reset_n),
		.ck      (ddr3_ck_p),
		.ck_n    (ddr3_ck_n),
		.cke     (ddr3_cke),
		.cs_n    (ddr3_cs_n),
		.ras_n   (ddr3_ras_n),
		.cas_n   (ddr3_cas_n),
		.we_n    (ddr3_we_n),
		.dm_tdqs ({ddr3_dm[1],ddr3_dm[0]}),
		.ba      (ddr3_ba),
		.addr    (ddr3_addr),
		.dq      (ddr3_dq[15:0]),
		.dqs     ({ddr3_dqs_p[1],
		           ddr3_dqs_p[0]}),
		.dqs_n   ({ddr3_dqs_n[1],
		           ddr3_dqs_n[0]}),
		.tdqs_n  (),
		.odt     (ddr3_odt)
	);

endmodule

仿真测试

利用 Vivado 自带的仿真对初始化进行测试,进行行为仿真测试,将top模块的信号添加到波形窗口中。

【DDR3 控制器设计】(2)DDR3 初始化测试

下图为仿真波形,可以看到 init_calib_complete 信号拉高就表示 DDR 控制器 MIG 核初始化成功,就可以进行读写操作了。其他信号可以暂时不管。

【DDR3 控制器设计】(2)DDR3 初始化测试