VIVADO 中mig IP的调用与仿真环境的搭建
项目简介简述
学完了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 仿真现象
从上面我们可以看出,初始化完成信号成功拉高,证明了我们仿真环境的正确性。
结束语
对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: