Xilinx VIVADO中DDR3 IP核的使用(1)

项目简介简述

学完了ISE软件对应MIG的使用,接下来我们学习vivado软件对应MIG的使用,因为两个软件对应MIG的使用并不相同,vivado软件的MIG留给用户的接口比较底层,并没有ISE的那么简单易用。所以接下来的文章,我们将利用DDR3做两个实验:
1、DDR3的循环检验,通过该实验我们学会7系列MIG的读写时序。
2、基于DDR3、USB3.0的图像显示,在1的基础上我们做一个适当的工程,加深对相关操作的理解。
本次实验我们用到的软硬件环境如下:
软件环境:vivado 2019.1
硬件环境:米联客 MA7035FA开发板

MIG IP建立的步骤

这里关于vivado如何建立工程,我们便省略跳过,相信学到DDR3的同学们都会软件的使用。
在这里插入图片描述
1、首先在1处输入MIG
2、双击标号2的MIG IP核
在这里插入图片描述
1、首先对比以下1处的设置信息,防止出错
2、点击2出的Next
在这里插入图片描述
1、其中上面1为建立一个新的MIG IP核,另一个为更改一个已存在的MIG IP,在本次实验中我们选择1建立一个新的MIG IP核
2、MIG IP核的名字
3、MIG 内部控制器的数目,我们选择一个
4、基于AXI协议控制还是app控制,我们这里先讲解app控制,接下来也会学习AXI控制,会在之后的文章中讲解,这里不选中
5、点击Next
在这里插入图片描述
1、其中1中的选项勾选了代表我们的这个IP不光只对该型号有用,也适用于选中的型号
2、这里我们不勾选1中的选项,直接点击2Next
在这里插入图片描述
1、选中DDR3,也就是该芯片支持的DDR类型
2、点击Next
在这里插入图片描述
1、DDR3芯片工作的时钟,这里我们选择最大时钟400MHz
2、控制DDR的数据流是按照2:1还是4:1的数据流,因为DDR是双沿采样,又必须是8突发:,4:1的数据位宽是2:1的两倍,而且app_end信号每两个数据给一次,用户时钟速率2:1是4:1的两倍。
3、选择响应的DDR芯片的型号,也可以进行定制
4、选择DDR的位宽,这里我们使用了两片DDR,每一个是16位,所以这里是32位。
5、使用数据掩码
其余的不太重要,就是控制器内部的一些策略问题,详细的可以查看技术手册
6、点击Next
在这里插入图片描述
1、用户提供给DDR的系统时钟,用来生成前面400MHz的时钟,这里选择200MHz,因为可以与后面的参考时钟公用一个时钟。
2、这里选择连续模式,sdram公国又两种模式连续模式与中断模式,一般选择连续模式
3、使能自动刷新模式
4、终端电阻相关,通常默认即可
5、用户地址与DDR的实际地址的映射方式
6、点击Next
在这里插入图片描述
1、生成时钟的类型,这里面NO Buffer代表是FPGA内部产生的时钟,其余两个是外部时钟引脚直接连接的选项,分别对应着单端与差分时钟信号
2、参考时钟,使用参考时钟生成数据路径与命令路径的时钟,对于A7芯片范围是199MHz到201MHz
在这里插入图片描述
3、低电平复位MIG IP核
4、不使用系统自带的debug,想要调试使用ila即可
其余的默认即可
5、点击Next
在这里插入图片描述
1、终端电阻相关,点击默认即可
在这里插入图片描述
1、A7的MIG与S6的MIG不同,S6的MIG是使用硬核MCB,一旦选定了MCB的位置,那么所有DDR的引脚便 确定了,而A7的MIG是使用硬件逻辑搭建,具体的引脚不确定,所以我们最好在生成MIG的时候固定引脚位置及电平属性,所以选择第二个
2、点击Next
在这里插入图片描述
1、找到对应开发板的DDR引脚文件,一般FPGA开发板都有相配套的ucf或xdc文件
2、点击验证一下文件的有效性
3、点击Next
在这里插入图片描述
1、我们没将上面信号引出开发板,默认即可,点击Next
在这里插入图片描述
1、我们选择的详细信息,点击Next即可
在这里插入图片描述
1、选择接受该协议
2、点击Next
然后一路Next,最后生成MIG IP核即可。到此为止,我们建立了一个完整新的MIG IP,并且知道了MIG IP核调用过程中每个选项所代表的意义。

MIG自带示例工程的搭建

我们班接下来要对该我们的MIG IP核搭建仿真环境,为了掌握仿真环境的搭建,我们先对MIG生成的示例工程进行搭建,然后再搭建我们的MIG仿真环境,因为其中的代码都是借鉴的示例工程中的代码,这里我们也给出了学习一个新的IP的完整流程。
在这里插入图片描述
右击对应的IP核,然后选自Open IP Example Design,打开一个示例工程,这里要比ISE新建一个工程简单的多,如下图:
在这里插入图片描述
接下来仿真该示例工程,用Modelsim仿真,如下图
在这里插入图片描述
在这里插入图片描述

从上图中我们可以看到对应的init_calib_complete信号拉高,说明我们的示例工程成功仿真,接下来我们将利用这个示例工程搭建相应的我们自己创建的MIG仿真环境。

MIG 仿真环境的搭建

这里我们将给出代码,大家可以对比一下代码与上面示例工程的代码,在仿真模型的处理上几乎一样。
ddr3_top模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : ddr3_top.v
// Create Time  : 2020-02-27 23:16:16
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module ddr3_top(
    //System Interfaces
    input                       sclk                    ,
    input                       rst_n                   ,
    //DDR3 Interfaces           
    output  wire    [13:0]      ddr3_addr               ,
    output  wire    [ 2:0]      ddr3_ba                 ,
    output  wire                ddr3_cas_n              ,
    output  wire                ddr3_ck_n               ,
    output  wire                ddr3_ck_p               ,
    output  wire                ddr3_cke                ,
    output  wire                ddr3_ras_n              ,
    output  wire                ddr3_reset_n            ,
    output  wire                ddr3_we_n               ,
    inout           [31:0]      ddr3_dq                 ,
    inout           [ 3:0]      ddr3_dqs_n              ,
    inout           [ 3:0]      ddr3_dqs_p              ,
    output  wire                init_calib_complete     ,
    output  wire    [ 0:0]      ddr3_cs_n               ,
    output  wire    [ 3:0]      ddr3_dm                 ,
    output  wire    [ 0:0]      ddr3_odt
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
wire                            locked                  ;
wire                            clk_200m                ;   

 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/

clk_wiz_0 instance_name(
    // Clock out ports
    .clk_out1                       (clk_200m                       ),     // output clk_out1
    // Status and control signals
    .reset                          (~rst_n                         ), // input reset
    .locked                         (locked                         ),       // output locked
    // Clock in ports
    .clk_in1                        (sclk                           )
);      // input clk_in1

mig_7series_0 mig_7series_0_inst (
    // Memory interface ports
    .ddr3_addr                      (ddr3_addr                      ),  // output [13: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                       (                               ),  // input [27:0]        app_addr
    .app_cmd                        (                               ),  // input [2:0]      app_cmd
    .app_en                         (                               ),  // input             app_en
    .app_wdf_data                   (                               ),  // input [255:0]       app_wdf_data
    .app_wdf_end                    (                               ),  // input                app_wdf_end
    .app_wdf_wren                   (                               ),  // input               app_wdf_wren
    .app_rd_data                    (                               ),  // output [255:0]       app_rd_data
    .app_rd_data_end                (                               ),  // output           app_rd_data_end
    .app_rd_data_valid              (                               ),  // output         app_rd_data_valid
    .app_rdy                        (                               ),  // output           app_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                  (                               ),  // output         app_sr_active
    .app_ref_ack                    (                               ),  // output           app_ref_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_i                      (clk_200m                       ),
    .sys_rst                        (locked                         ) // input sys_rst


    );



endmodule

MIG 仿真测试模块的代码

tb_ddr3模块:

`timescale 1ns / 1ps
`define     CLOCK   20

// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : tb_ddr3.v
// Create Time  : 2020-02-27 23:36:46
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************


module tb_ddr3;

parameter  DQ_WIDTH             = 32;
localparam MEMORY_WIDTH         = 16;
localparam NUM_COMP             = DQ_WIDTH/MEMORY_WIDTH ;

reg                             sclk                    ;
reg                             rst_n                   ;

wire                [13:0]      ddr3_addr               ;
wire                [ 2:0]      ddr3_ba                 ;
wire                            ddr3_cas_n              ;
wire                            ddr3_ck_n               ;
wire                            ddr3_ck_p               ;
wire                            ddr3_cke                ;
wire                            ddr3_ras_n              ;
wire                            ddr3_reset_n            ;
wire                            ddr3_we_n               ;
wire                [31:0]      ddr3_dq                 ;
wire                [ 3:0]      ddr3_dqs_n              ;
wire                [ 3:0]      ddr3_dqs_p              ;
wire                            init_calib_complete     ;
wire                [ 0:0]      ddr3_cs_n               ;
wire                [ 3:0]      ddr3_dm                 ;
wire                [ 0:0]      ddr3_odt                ;

initial begin
    sclk            =           1'b0;
    rst_n           <=          1'b0;
    #(100*`CLOCK);
    rst_n           <=          1'b1;
end
always  #(`CLOCK/2)     sclk        =       ~sclk;

ddr3_top ddr3_top_inst(
    //System Interfaces
    .sclk                       (sclk                       ),
    .rst_n                      (rst_n                      ),
    //DDR3 Interfaces           
    .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_reset_n               (ddr3_reset_n               ),
    .ddr3_we_n                  (ddr3_we_n                  ),
    .ddr3_dq                    (ddr3_dq                    ),
    .ddr3_dqs_n                 (ddr3_dqs_n                 ),
    .ddr3_dqs_p                 (ddr3_dqs_p                 ),
    .init_calib_complete        (init_calib_complete        ),
    .ddr3_cs_n                  (ddr3_cs_n                  ),
    .ddr3_dm                    (ddr3_dm                    ),
    .ddr3_odt                   (ddr3_odt                   )
);

genvar i;

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                          ),
        .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[(2*(i+1)-1):(2*i)]         ),
        .ba                     (ddr3_ba                            ),
        .addr                   (ddr3_addr                          ),
        .dq                     (ddr3_dq[16*(i+1)-1:16*(i)]         ),
        .dqs                    (ddr3_dqs_p[(2*(i+1)-1):(2*i)]      ),
        .dqs_n                  (ddr3_dqs_n[(2*(i+1)-1):(2*i)]      ),
        .tdqs_n                 (                                   ),
        .odt                    (ddr3_odt                           )
    );
    end

endmodule

这里的仿真模型文件与参数文件在生成IP的示例工程中有,目录如下,自己添加到工程中去即可:
在这里插入图片描述

MIG 仿真现象

在这里插入图片描述
从上面我们可以看出,初始化完成信号成功拉高,证明了我们仿真环境的正确性。

结束语

对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

发布了42 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhangningning1996/article/details/104546146