• DDR3_旧版(2):初始化


      调取 DDR3 IP核后,是不能直接进行读写测试的,必须先进行初始化操作,对 IP 核进行校验。本篇采用 Modelsim 软件配合 DDR3 IP核生成的仿真模型,搭建出 IP核的初始化过程。

    一、顶层文件

    1、生成 DDR3 IP 核后,在 Source 界面空白处右键点击 Add Source,添加顶层文件。

    2、在 DDR3_HDMIDDR3_HDMI.srcssources_1ipddr3_ctrlddr3_ctrluser_design tlddr3_ctrl.v 可得到 top_ddr3_hdmi 需要的输入输出端口,将其复制过来。

    //========================< 端口 >==========================================
    (
    //system ----------------------------------------
    input   wire                sclkin              , //50Mhz
    input   wire                srst_n              , //复位,低电平有效
    //DDR3 ------------------------------------------
    inout   wire  [15:0]        ddr3_dq             ,
    inout   wire  [ 1:0]        ddr3_dqs_n          ,
    inout   wire  [ 1:0]        ddr3_dqs_p          ,
    output  wire  [13:0]        ddr3_addr           ,
    output  wire  [ 2:0]        ddr3_ba             ,
    output  wire                ddr3_ras_n          ,
    output  wire                ddr3_cas_n          ,
    output  wire                ddr3_we_n           ,
    output  wire                ddr3_reset_n        ,
    output  wire  [ 0:0]        ddr3_ck_p           ,
    output  wire  [ 0:0]        ddr3_ck_n           ,
    output  wire  [ 0:0]        ddr3_cke            ,
    output  wire  [ 0:0]        ddr3_cs_n           ,
    output  wire  [ 1:0]        ddr3_dm             ,
    output  wire  [ 0:0]        ddr3_odt              
    );

    3、对顶层模块进行编写,可以进入 IP Source 的 ddr3_ctrl.veo文件找到接口复制过来例化,并根据需求更改部分信号,仿真时希望app接口不工作,所有输入接口连接为 0

     

    //DDR3_IP核 -----------------------------------------------------------------
    ddr3_ctrl u_ddr3_ctrl //输入为200Mhz,芯片需400Mhz,内部速率为4:1 = 100Mhz
    (
        // Memory interface ports ----------------------------------------
        .ddr3_addr              (ddr3_addr                               ), // output [13:0]
        .ddr3_ba                (ddr3_ba                                 ), // output [ 2:0]
        .ddr3_cas_n             (ddr3_cas_n                              ), // output        
        .ddr3_ck_n              (ddr3_ck_n                               ), // output 
        .ddr3_ck_p              (ddr3_ck_p                               ), // output
        .ddr3_cke               (ddr3_cke                                ), // output
        .ddr3_ras_n             (ddr3_ras_n                              ), // output        
        .ddr3_reset_n           (ddr3_reset_n                            ), // output        
        .ddr3_we_n              (ddr3_we_n                               ), // output        
        .ddr3_dq                (ddr3_dq                                 ), // inout  [15:0]  
        .ddr3_dqs_n             (ddr3_dqs_n                              ), // inout  [ 1:0]   
        .ddr3_dqs_p             (ddr3_dqs_p                              ), // inout  [ 1:0]   
        .init_calib_complete    (init_calib_complete                     ), // output        
        .ddr3_cs_n              (ddr3_cs_n                               ), // output 
        .ddr3_dm                (ddr3_dm                                 ), // output [ 1:0]  
        .ddr3_odt               (ddr3_odt                                ), // output
        // Application interface ports -----------------------------------
        .app_addr               (                                        ), // input  [27:0]  
        .app_cmd                (                                        ), // input  [ 2:0]   
        .app_en                 (                                        ), // input         
        .app_wdf_data           (                                        ), // input  [127:0] 
        .app_wdf_end            (                                        ), // input         
        .app_wdf_wren           (                                        ), // input         
        .app_rd_data            (                                        ), // output [127:0]
        .app_rd_data_end        (                                        ), // output        
        .app_rd_data_valid      (                                        ), // output        
        .app_rdy                (                                        ), // output        
        .app_wdf_rdy            (                                        ), // output        
        .app_sr_req             (                                        ), // input         
        .app_ref_req            (                                        ), // input         
        .app_zq_req             (                                        ), // input         
        .app_sr_active          (                                        ), // output        
        .app_ref_ack            (                                        ), // output        
        .app_zq_ack             (                                        ), // output        
        .ui_clk                 (                                        ), // output 100Mhz       
        .ui_clk_sync_rst        (                                        ), // output        
        .app_wdf_mask           (                                        ), // input  [15:0]
        // System Clock Ports --------------------------------------------
        .sys_clk_i              (sysclk                                  ), // input  200Mhz       
        .sys_rst                (srst_n                                  )  // input  系统复位
    );

    4、调取 DDR3 IP 核时,选择了对此 IP 核输入一个200 Mhz 的时钟,由于板卡晶振生成的时钟为 50Mhz,所以还得用一个 IP 核来生出 200 Mhz 时钟。

    5、生成时钟后同样找到 .veo 文件接口复制过来例化。

    //时钟_IP核 ----------------------------------------------------------------
    ddr3_clk_gen u_ddr3_clk_gen
    (
        .clk_in1                (sclkin                 ),  // input            clk_in1
        .clk_out1               (sysclk                 )   // output           clk_out1
    );

    7、有几个信号是我们需要观察的,用 wire 引出来吧。

    //========================< 连线 >==========================================
    //PLL -------------------------------------------
    wire                        sysclk              ;
    // ddr3 ip --------------------------------------
    wire                        app_rdy             ;
    wire                        app_wdf_rdy         ;
    wire                        app_en              ;
    wire  [27:0]                app_addr            ;
    wire  [ 2:0]                app_cmd             ;
    wire  [15:0]                app_wdf_mask        ;
    wire                        app_wdf_wren        ;
    wire [127:0]                app_wdf_data        ;
    wire                        app_wdf_end         ;
    wire [127:0]                app_rd_data         ;
    wire                        app_rd_data_valid   ;
    wire                        app_rd_data_end     ;
    wire                        ui_clk              ;
    wire                        ui_clk_sync_rst     ;
    wire                        init_calib_complete ;

    二、测试文件

    1、在 Simulation Sources 右键选择 Add Sources,创建 testbench 文件。

    2、首先还是把输入输出接口和 top 模块接口在 testbench 中写好。

     1 `timescale 1ns/1ps  //时间精度
     2 `define    Clock 20 //时钟周期
     3 
     4 module top_ddr3_hdmi_tb;
     5 //========================< 端口 >==========================================
     6 reg                         clk                             ;
     7 reg                         rst_n                           ;
     8 wire  [15:0]                ddr3_dq                         ;
     9 wire  [ 1:0]                ddr3_dqs_n                      ;
    10 wire  [ 1:0]                ddr3_dqs_p                      ;
    11 wire  [13:0]                ddr3_addr                       ;
    12 wire  [ 2:0]                ddr3_ba                         ;
    13 wire                        ddr3_ras_n                      ;
    14 wire                        ddr3_cas_n                      ;
    15 wire                        ddr3_we_n                       ;
    16 wire                        ddr3_reset_n                    ;
    17 wire  [ 0:0]                ddr3_ck_p                       ;
    18 wire  [ 0:0]                ddr3_ck_n                       ;
    19 wire  [ 0:0]                ddr3_cke                        ;
    20 wire  [ 0:0]                ddr3_cs_n                       ;
    21 wire  [ 1:0]                ddr3_dm                         ;
    22 wire  [ 0:0]                ddr3_odt                        ;
    23 
    24 //==========================================================================
    25 //==    模块例化
    26 //==========================================================================
    27 //顶层模块
    28 top_ddr3_hdmi u_top_ddr3_hdmi
    29 (
    30     .ddr3_dq                (ddr3_dq                        ),
    31     .ddr3_dqs_n             (ddr3_dqs_n                     ),
    32     .ddr3_dqs_p             (ddr3_dqs_p                     ),
    33     .ddr3_addr              (ddr3_addr                      ),
    34     .ddr3_ba                (ddr3_ba                        ),
    35     .ddr3_ras_n             (ddr3_ras_n                     ),
    36     .ddr3_cas_n             (ddr3_cas_n                     ),
    37     .ddr3_we_n              (ddr3_we_n                      ),
    38     .ddr3_reset_n           (ddr3_reset_n                   ),
    39     .ddr3_ck_p              (ddr3_ck_p                      ),
    40     .ddr3_ck_n              (ddr3_ck_n                      ),
    41     .ddr3_cke               (ddr3_cke                       ),
    42     .ddr3_cs_n              (ddr3_cs_n                      ),
    43     .ddr3_dm                (ddr3_dm                        ),
    44     .ddr3_odt               (ddr3_odt                       ),
    45     .sclkin                 (clk                            ),
    46     .srst_n                 (rst_n                          )
    47 );

    3、DDR3 控制器非常复杂,手写 testbench 是非常困难的。我们上一讲调取 DDR3 IP 核时说过,它已经生成了仿真模型供我们测试。位置在 DDR3_HDMIDDR3_HDMI.srcssources_1ipddr3_ctrlddr3_ctrlexample_designsim,ddr3_model.sv 和 ddr3_model_parameters.vh 即是我们需要的仿真模型,将其复制到 DDR3_HDMIDDR3_HDMI.srcssim_1 ew 中,和 top_ddr3_hdmi_tb 文件放在一起。此外还可以看到刚刚那个文件夹中有一个 sim_tb_top 文件,打开它翻到500多行,即可看到该仿真模型的接口模块,我们将其复制到 testbench 中,并根据此次设计情况,更改部分参数。

     1 //仿真模型
     2 ddr3_model u_ddr3_model
     3 (
     4     .rst_n                  (ddr3_reset_n                   ),
     5     .ck                     (ddr3_ck_p                      ),
     6     .ck_n                   (ddr3_ck_n                      ),
     7     .cke                    (ddr3_cke                       ),
     8     .cs_n                   (ddr3_cs_n                      ),
     9     .ras_n                  (ddr3_ras_n                     ),
    10     .cas_n                  (ddr3_cas_n                     ),
    11     .we_n                   (ddr3_we_n                      ),
    12     .dm_tdqs                ({ddr3_dm[1],ddr3_dm[0]}        ), //ddr3_dm为2位
    13     .ba                     (ddr3_ba                        ),
    14     .addr                   (ddr3_addr                      ),
    15     .dq                     (ddr3_dq[15:0]                  ), //ddr3_dq为16位
    16     .dqs                    ({ddr3_dqs_p[1],ddr3_dqs_p[0]}  ), //ddr3_dqs_p为2位
    17     .dqs_n                  ({ddr3_dqs_n[1],ddr3_dqs_n[0]}  ), //ddr3_dqs_n为2位
    18     .tdqs_n                 (                               ),
    19     .odt                    (ddr3_odt                       )
    20 );

    3、此外还需要产生一个 50 Mhz 时钟和低电平有效的复位信号。

     1 //==========================================================================
     2 //==    时钟信号和复位信号
     3 //==========================================================================
     4 initial begin
     5     clk = 0;
     6     forever
     7         #(`Clock/2) clk = ~clk;
     8 end
     9 
    10 initial begin
    11     rst_n = 0; #(`Clock*20+1);
    12     rst_n = 1;
    13 end

    4、回到 Vivado,发现仿真模型文件已经出现了,但是处于问号状态,我们选中它,右键 Add Sources,将 ddr3_model.sv 和 ddr3_model_parameters.vh 添加进来即可。

    三、启动 Modelsim 验证 DDR3 IP核

    1、使用 Modelsim 进行仿真前,需要先编译 Vivado 和 Modelsim 之间的关联库,具体步骤请另行搜索。

    2、点击 Vivado 的 Setting 进行设置,Target simulator 选择 ModelSim Simulator,仿真顶层文件选择第二步的仿真文件,仿真库则自动定位好了。

    3、点击 Vivado 左侧菜单 Run Simulation --- Run Behavioral Simulation,Modelsim 就自动打开仿真了。

    4、选取信号,跑一段时间,可以看到时钟信号和复位信号正常,  init_calib_complete 信号在拉低一段时间后拉高,表面本次 DDR3 IP核验证成功。

    以上。

    参考资料:威三学院FPGA教程

  • 相关阅读:
    Minimum Inversion Number(归并排序)
    Ultra-QuickSort(归并排序)
    求逆序数(归并排序)
    Hat's Fibonacci(大数,好)
    Baskets of Gold Coins
    Permutation Recovery(模拟)
    反恐训练营(LCS)
    I Hate It(线段树)
    敌兵布阵
    Django报错:提交表单报错---RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and you have APPEND_SLASH set.
  • 原文地址:https://www.cnblogs.com/xianyufpga/p/11784493.html
Copyright © 2020-2023  润新知