Xilinx DDR3学习总结——2、MIG exmaple直接上板查看初始化状态


前言

上一篇,我们生成了一个example,example的测试激励看起来都比较复杂,仿真先不看,实际上,这个example稍加改动就可以直接上板了。这里我们就是查看MIG IP输出的init_calib_complete信号

修改内容

init_calib_complete是DDR3初始化成功的指示信号,所有的读写操作都必须等待该信号拉高。因此,我们example的内容什么都不改,只改必要的接口时钟,直接上板是否init_calib_complete能够拉高,如果直接上板能够拉高,那么表示DDR3正常工作了,给自己树立极大的信心。

只要改 mig_7series_0模块的两个输入
一个sys_clk_i
一个sys_rst

简单吧,一个系统时钟,需要输入200M,一个复位。
因为板载是100M时钟,这里需要一个PLL把它变成200M,然后把PLL lock信号作为sys_rst不就O了么,很简单呢

example_top文件,注释掉sys_rst,将剩下三个端口绑定管脚,tg_compare_error和init_calib_complete直接连接到两个灯上面

   input                                        sys_clk_i,
   output                                       tg_compare_error, // LED1
   output                                       init_calib_complete  // LED2
    // input                                        sys_rst
create_clock -period 10.000 -name sys_clk_i -waveform {0.000 5.000} [get_ports sys_clk_i]
set_property PACKAGE_PIN AD12 [get_ports sys_clk_i]
set_property IOSTANDARD SSTL135 [get_ports sys_clk_i]

set_property PACKAGE_PIN AB28 [get_ports tg_compare_error]  
set_property IOSTANDARD LVCMOS18 [get_ports tg_compare_error]
set_property PACKAGE_PIN AA27 [get_ports init_calib_complete]
set_property IOSTANDARD LVCMOS18 [get_ports init_calib_complete]

DDR3的管脚不需要在进行约束了,因为在创建MIG的时候就已经约束好了,约束文件在IP核的文件夹里面

然后添加一个PLL

wire sys_rst;
wire clk_200m;
  clk_wiz_0 clk_wiz_0
   (
    // Clock out ports
    .clk_out1(clk_200m),     // 连接到mig_7series_0.sys_clk_i
    // Status and control signals
    .locked(sys_rst),       // 连接到mig_7series_0.sys_rst
   // Clock in ports
    .clk_in1(sys_clk_i));      // input clk_in1

就这么简单

但在编译的过程中,会出现一个错误,提示需要加这个约束

CLOCK_DEDICATED_ROUTE = BACKBONE

查阅了资料,也有这么处理,也可以避免错误,sys_clk_i输入先经过一个 BUFG,然后在输入到PLL,PLL中source 需要选Global Buffer。之前选的是pin输入,就会有错误

wire sys_clk_d;
   BUFG BUFG_inst (
      .O(sys_clk_d), // 1-bit output: Clock output
      .I(sys_clk_i)  // 1-bit input: Clock input
   );

wire sys_rst;
wire clk_200m;
  clk_wiz_0 clk_wiz_0
   (
    // Clock out ports
    .clk_out1(clk_200m),     // output clk_out1
    // Status and control signals
    .locked(sys_rst),       // output locked
   // Clock in ports
    .clk_in1(sys_clk_i));      // input clk_in1

上板

修改完成之后,编译可以生成bit文件,下载到FPGA中,init_calib_complete对应的灯点亮了,说明DDR3初始化成功了。说明我们操作无误,尽管我们抢先进行了上板测试,并且证明了DDR3初始化成功。

但里面的测试例程 mig_7series_v4_2_traffic_gen_top比较复杂,作为初学者我也不太像去了解,我直接将其删除

整个工程就剩下如下内容:


`timescale 1ps/1ps



module example_top
  (



   // Inouts

   inout [15:0]                         ddr3_dq,
   inout [1:0]                        ddr3_dqs_n,
   inout [1:0]                        ddr3_dqs_p,
   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,

   // Single-ended system clock
   input                                        sys_clk_i,
   output                                       tg_compare_error, // LED1
   output                                       init_calib_complete  // LED2


   );
wire sys_clk_d;
   BUFG BUFG_inst (
      .O(sys_clk_d), // 1-bit output: Clock output
      .I(sys_clk_i)  // 1-bit input: Clock input
   );


wire sys_rst;
wire clk_200m;
  clk_wiz_0 clk_wiz_0
   (
    // Clock out ports
    .clk_out1(clk_200m),     // output clk_out1
    // Status and control signals
    .locked(sys_rst),       // output locked
   // Clock in ports
    .clk_in1(sys_clk_d));      // input clk_in1





  reg [28:0]                 app_addr = 0;
  reg [2:0]                            app_cmd = 0;
  reg                                  app_en = 0;
  wire                                  app_rdy;
  wire [127:0]             app_rd_data;
  wire                                  app_rd_data_end;
  wire                                  app_rd_data_valid;
  reg [127:0]             app_wdf_data = 128'h0;
  reg                                  app_wdf_end = 0;
  reg [15:0]             app_wdf_mask = 0;
  wire                                  app_wdf_rdy;
  wire                                  app_sr_active;
  wire                                  app_ref_ack;
  wire                                  app_zq_ack;
  reg                                  app_wdf_wren = 0;



  wire [11:0]                           device_temp;

  

wire clk;
wire rst;



  mig_7series_0 u_mig_7series_0
      (

// Memory interface ports

       .ddr3_addr                      (ddr3_addr),
       .ddr3_ba                        (ddr3_ba),
       .ddr3_cas_n                     (ddr3_cas_n),
       .ddr3_ck_n                      (ddr3_ck_n),
       .ddr3_ck_p                      (ddr3_ck_p),
       .ddr3_cke                       (ddr3_cke),
       .ddr3_ras_n                     (ddr3_ras_n),
       .ddr3_we_n                      (ddr3_we_n),
       .ddr3_dq                        (ddr3_dq),
       .ddr3_dqs_n                     (ddr3_dqs_n),
       .ddr3_dqs_p                     (ddr3_dqs_p),
       .ddr3_reset_n                   (ddr3_reset_n),
       .init_calib_complete            (init_calib_complete),
       .ddr3_cs_n                      (ddr3_cs_n),
       .ddr3_dm                        (ddr3_dm),
       .ddr3_odt                       (ddr3_odt),
// Application interface ports

       .app_addr                       (app_addr),
       .app_cmd                        (app_cmd),
       .app_en                         (app_en),
       .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_wdf_rdy                    (app_wdf_rdy),
       .app_sr_req                     (1'b0),
       .app_ref_req                    (1'b0),
       .app_zq_req                     (1'b0),
       .app_sr_active                  (app_sr_active),
       .app_ref_ack                    (app_ref_ack),
       .app_zq_ack                     (app_zq_ack),
       .ui_clk                         (clk),
       .ui_clk_sync_rst                (rst),
       .app_wdf_mask                   (app_wdf_mask),

// System Clock Ports
       .sys_clk_i                       (clk_200m),
       .device_temp            (device_temp),
       .sys_rst                        (sys_rst)

       );

// End of User Design top instance






endmodule


注意,MIG的输入需要赋值,否则编译的时候会报错

  reg [28:0]                 app_addr = 0;
  reg [2:0]                            app_cmd = 0;
  reg                                  app_en = 0;
  wire                                  app_rdy;
  wire [127:0]             app_rd_data;
  wire                                  app_rd_data_end;
  wire                                  app_rd_data_valid;
  reg [127:0]             app_wdf_data = 128'h0;
  reg                                  app_wdf_end = 0;
  reg [15:0]             app_wdf_mask = 0;
  wire                                  app_wdf_rdy;
  wire                                  app_sr_active;
  wire                                  app_ref_ack;
  wire                                  app_zq_ack;
  reg                                  app_wdf_wren = 0;

修改完成之后,重新编译可以生成bit文件,下载到FPGA中,init_calib_complete对应的灯点亮了,说明DDR3功能不受影响。
接下来我就可以基于这个简化的工程添加一些读写功能了。但如果还需要添加更多的功能的话,还是首先需要进行仿真的,接下来,我们就进行DDR3参考例程的仿真工作。

08-13 16:55