关于DDR3的基本知识在这里我就不详细说了,只有在相关的地方会提上一嘴。本教程的目的只是教会大家如何使用MIG控制器,大家一定不要觉得MIG控制器有多难,其实很简单的,跟着我在心里默念“MIG就像BRAM一样简单”。确实哈,当你回过头来看,MIG控制器的使用基本和BRAM的使用方法很像。
话不多说了,那么这第一个系列,我就先交大家来例化一个MIG控制器。
VIVADO:2016.4
芯片:zynq7035
上一节已经介绍了如何配置一个MIG控制器 Xilinx MIG 控制器使用详解(一)
现在让我们来看看生成的MIG控制器模块。
mig_7series_0 u_mig_7series_0 (
// Memory interface ports
// 下面这些都是DDR3的物理管脚,这些已经约束好了,不需要我们自己约束,不用管。
.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 [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), // outp init_calib_complete
//这也是DDR3的一些物理管脚,我们也不需要管
.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开头的信号才是我们使用MIG控制器需要关注的
.app_addr(app_addr), // input [28:0] app_addr
.app_cmd(app_cmd), // input [2:0] app_cmd
.app_en(app_en), // input app_en
.app_wdf_data(app_wdf_data), // input [255:0] app_wdf_data
.app_wdf_end(app_wdf_end), // input app_wdf_end
.app_wdf_wren(app_wdf_wren), // input app_wdf_wren
.app_rd_data(app_rd_data), // output [255: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
//下面这三个再例化的时候直接给0就可以
.app_sr_req(app_sr_req), // input app_sr_req
.app_ref_req(app_ref_req), // input app_ref_req
.app_zq_req(app_zq_req), // input app_zq_req
//下面三个是输出,直接输出到三个wire信号即可
.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就是MIG输出给用户的时钟,在上一节中我们说的是100MHz
.ui_clk(ui_clk), // output ui_clk
//输出的这个复位信号不用管,接到一个wire信号上就可以
.ui_clk_sync_rst(ui_clk_sync_rst), // output ui_clk_sync_rst
//这个是掩码信号,直接赋0,不用管
.app_wdf_mask(app_wdf_mask), // input [31:0] app_wdf_mask
// System Clock Ports
//系统时钟,上一节说的是400MHz
.sys_clk_i(sys_clk_i),
// Reference Clock Ports
//参考时钟
.clk_ref_i(clk_ref_i),
//系统复位
.sys_rst(sys_rst) // input sys_rst
);
好,到这我们就来看看app打头的这些信号是什么意思。
首先,对DDR3应该有读写两种操作,我们先来看看写操作。
写操作相关信号:
app_cmd :操作命令,确定是读还是写。读: app_cmd = 3'b001; 写:app_cmd = 3'b000;
app_addr:操作地址(往哪写,从哪读)
app_en :操作地址app_addr的使能,只有它拉高的时候,对应的app_addr才是有效的
app_wdf_data:写入数据的接口(往DDR3里面写什么)
app_wdf_wren:写入的数据接口app_wdf_data的使能,只有它拉高的时候。对应的app_wdf_data才是有效的
app_wdf_end:这里不需要管他。只需要使app_wdf_end = app_wdf_wren。
所以写入数据的时候你只需要处理好这六个信号就可以
app_cmd
app_addr
app_en
app_wdf_data
app_wdf_wren
app_wdf_end
读操作相关信号:
读数据的时候只需要操作以下三个信号,是不是更简单呢?(这里的三个信号和上面是一样的)
app_cmd
app_addr
app_en
看完了相关的信号,我们就该来看看看读写操作是如何操作的了。
写操作:
写操作时序如下:(这个图示从别人的文档里面弄出来的不想去翻手册了)
可以看到写的时候可以有三种情况,分别对应1、2、3种情况。第一种是地址和数据严格对齐的,第二三种是数据和地址不对齐的,推荐曹勇第一种数据和地址对齐的方式。
在这个图里面,我们发现有两个信号之前没有说明。就是
app_rdy:这个信号由DDR3输出,告诉用户在app_rdy拉高的时候拉高app_en。地址app_addr才是有效的。
app_wdf_rdy:这个信号由DDR3输出,告诉用户在app_wdf_rdy拉高的时候拉高app_wdf_wren,写入的数据app_wdf_data才是有效的。
由上图的第一种情况可以看出,在app_rdy和app_wdf_rdy都拉高的时候,把app_en拉高、再给出相应的地址、再写入相应的数据、再给出对应的写使能就可以把相应的数据写入到DDR3中相应的地址。但是,需要注意的是,在app_rdy 或者app_wdf_rdy没有拉高的时候,需要把相应的数据和地址保持不变。
读操作:
读操作就更简单了,先把读操作时序贴出来。(这个图也是从别人的文档里面截取的)
在读的时候,只需要在app_rdy拉高的时候给出地址app_addr和使能app_en即可。然后就等着接数就可以,给几个周期的使能就出几个周期的数据。
所以,回到第一节Xilinx MIG 控制器使用详解(一),当时说的MIG的使用就像BRAM一样简单。
你看,我没说错吧。BRAM在写的时候也是给出写地址和写使能,MIG也是,不同的是MIG需要在app_rdy、app_wdf_rdy拉高的时候给出。BRAM在读的时候,也是给出一个地址就可以了,MIG还需拉高app_en。
现在让我们来算一下DDR3的带宽吧。
DDR3的物理位宽是32bit的,DDR3跑的时钟频率是400MHz, 又因为是上下沿都采样,所以带宽应该为:400MHz*2*32bit=800MHz * 32bit。那么MIG控制器的读写数据端口的位宽是多少呢?也就是app_wdf_data 和app_rd_data的位宽是多少呢?答案是:256bit。 怎么算出来的呢?800MHz * 32 bit = 100MHz *32*8bit, 所以是32*8=256bit。
下一篇就介绍如何使用MIG控制器进行读写。
---------------------
作者:maochuangan
来源:CSDN
原文: https://blog.csdn.net/MaoChuangAn/article/details/85269291