【实战经验】--Xilinx--IPcore--MCB(DDR3)运用
1.背景与介绍
1)在导师安排的新的任务中,用到了一块2G大小的DDR3(MT41K128M16JT-107)。本打算像之前用SDRAM一样自己写初始化,读写模块,但是师兄跟我说可以用Xilinx自带的MCB来进行控制,会方便很多,于是自己在网上找了一些资料,摸索了一番,然后在实际运用后,写下了这篇随笔。
2)我们先看MCB内部结构图,重点关注两个部分User Logic 与PHY。
PHY是外部IO接口,也就是和DDR3直接连接的接口;
User Logic 对应的部分则是需要我用户编写的部分,从图中可以看出:用户只需控制CMD与数据即可,而这里的CMD也不复杂,Xilinx将其做的十分简单,用户只需发送对应的读、写、带刷新写、带刷新读即可,相对来说使用还是很简单的。
2.生成IP核
1)如何产生IP核的过程就不说了,记住叫Memory Interface Generator就行,直接进入设置部分。
2)选择兼容平台,根据用户自己需求选择,我这里无需其他拓展,因此都没选择。
3)选择bank区域,根据用户数据手册上的介绍,优先选择左侧/左下侧。(用户数据在点击图中左下区域后可以得到)
4)选择DDR3的芯片型号,如果没有,可以自己定义一块,不过需要注意的是要选择接口相似的芯片作为模板。
5)定义自己的芯片,我的芯片是MT41K128M16JT-107 ,其中128M16代表128Meg*16,-107表示速度在芯片数据手册种得知可以向后兼容(-125、-15E、-187E)因此选择MT41J128M16XX-125,这样需要改动的东西就非常少了。
先附上我使用的芯片的部分参数
再附上我定义的芯片,可见几乎没有改动。
6)此处无需改动,保留默认值即可。
7)此处有几种选择,我选择是128bit,既一次写入/读取128bit数据,具体如何设置,可以查看用户手册ug388.pdf。
8)此处设置终端补偿电阻PIN脚(保持默认或者看自己板上怎么连接的),单时钟输入。
9)最后一路NEXT到底,点击Generate,一个MCB的IP核就生成了。
10)IP核生成后,我们会在其目录下看见三个文件夹,其中内容如图所示。
11)我们打开user_design文件夹,其中par与rtl最为重要,par中包含UCF文件,这会让我们定义端口容易很多,而rtl则包含设计的.v文件
3.使用
0)首先自然是要生成相应的时钟 333MHz!!!
1)将生成的MCB移出(右键--remove),再将uesr_design中rtl下文件手动添加至工程中(右键--add source)。(为的是使用PLL生成的时钟)
2)修改memc3_infrastructure_inst 中的时钟
先注释掉这一部分(这是MCB生成时钟的部分)
将这里的时钟换成sys_clk(原来是sys_clk_ibufg)
3)接下来我们来了解一下MCB DDR3的接口 ,接口的说明也在下面这段代码中;
MCB_TEST # (
.C3_P0_MASK_SIZE(),
.C3_P0_DATA_PORT_SIZE(),
.DEBUG_EN(),
.C3_MEMCLK_PERIOD(), //change
.C3_CALIB_SOFT_IP("TRUE"),
.C3_SIMULATION("FALSE"),
.C3_RST_ACT_LOW(),
.C3_INPUT_CLK_TYPE("SINGLE_ENDED"),
.C3_MEM_ADDR_ORDER("ROW_BANK_COLUMN"),
.C3_NUM_DQ_PINS(),
.C3_MEM_ADDR_WIDTH(),
.C3_MEM_BANKADDR_WIDTH()
)
u_MCB_MIG (
.c3_sys_clk (clk_ddr3_sys), //DDR3时钟333MHz对应3000ps
.c3_sys_rst_i (rst_ddr3_sys), //复位信号 高有效
//物理接口,不用管
.mcb3_dram_dq (mcb3_dram_dq), //读写数据
.mcb3_dram_a (mcb3_dram_a), //读写地址
.mcb3_dram_ba (mcb3_dram_ba), //bank选择
.mcb3_dram_ras_n (mcb3_dram_ras_n), //行使能 低有效
.mcb3_dram_cas_n (mcb3_dram_cas_n), //列使能 低有效
.mcb3_dram_we_n (mcb3_dram_we_n), //使能 低有效
.mcb3_dram_odt (mcb3_dram_odt), //PHYIO
.mcb3_dram_cke (mcb3_dram_cke), //PHYIO
.mcb3_dram_ck (mcb3_dram_ck), //PHYIO
.mcb3_dram_ck_n (mcb3_dram_ck_n), //PHYIO
.mcb3_dram_dqs (mcb3_dram_dqs), //PHYIO
.mcb3_dram_dqs_n (mcb3_dram_dqs_n), //PHYIO
.mcb3_dram_udqs (mcb3_dram_udqs), // for X16 parts
.mcb3_dram_udqs_n (mcb3_dram_udqs_n), // for X16 parts
.mcb3_dram_udm (mcb3_dram_udm), // for X16 parts
.mcb3_dram_dm (mcb3_dram_dm), //PHYIO
.mcb3_dram_reset_n (mcb3_dram_reset_n), //PHYIO
.c3_clk0 (c3_clk0), //PHYIO
.c3_rst0 (c3_rst0), //PHYIO
.c3_calib_done (c3_calib_done), //goes High to indicate that calibration has completed
.mcb3_rzq (mcb3_rzq),
.mcb3_zio (mcb3_zio), //command path signals
.c3_p0_cmd_clk (clk_ddr3), //用户读写MCB内部FIFO时钟
.c3_p0_cmd_en (mcb3_cmd_en), //high signal is the write-enable signal for command fifo
.c3_p0_cmd_instr (mcb3_cmd_instr), //CMD
.c3_p0_cmd_bl (mcb3_cmd_bl), //突发长度,大小为0-63,代表1-64的突发长度(即连续读/写多少次) (for example, 6'b00011 is a burst length 4 transaction). The user word width equals the port width (for example, a burst length of 3 on a 64-bit port transfers 3 x 64-bit user words = 192 bits total).
.c3_p0_cmd_byte_addr (mcb3_cmd_byte_addr),//MCB的读写地址,写的时候等于写地址,读的时候等于读地址
.c3_p0_cmd_empty (mcb3_cmd_empty), //MCB空
.c3_p0_cmd_full (mcb3_cmd_full), //MCB满
//write datapath
.c3_p0_wr_clk (clk_ddr3), //等于上面的时钟;
.c3_p0_wr_en (mcb3_wr_en), //Data is loaded on the rising edge of pX_wr_clk when pX_wr_en = 1 and pX_wr_full = 0.
.c3_p0_wr_mask (mcb3_wr_mask), //when a mask bit is high, the corresponding bte of data is masked.
.c3_p0_wr_data (mcb3_wr_data), //write data, size can be 32,64,128 bits, depending on port configuration.
.c3_p0_wr_full (mcb3_wr_full),
.c3_p0_wr_empty (mcb3_wr_empty),
.c3_p0_wr_count (mcb3_wr_count), //output indicates how many user words are in the FIFO(0-64)0 means fifo empty
.c3_p0_wr_underrun (mcb3_wr_underrun), //indicates there was not enough data in write data fifo to complete the transacion.
.c3_p0_wr_error (mcb3_wr_error),
//read datapath
.c3_p0_rd_clk (clk_ddr3),
.c3_p0_rd_en (mcb3_rd_en),
.c3_p0_rd_data (mcb3_rd_data),
.c3_p0_rd_full (mcb3_rd_full),
.c3_p0_rd_empty (mcb3_rd_empty),
.c3_p0_rd_count (mcb3_rd_count),
.c3_p0_rd_overflow (mcb3_rd_overflow),
.c3_p0_rd_error (mcb3_rd_error)
);
MCB_接口
从上面的注释可以看出,和用户编写读写程序紧密相关的是下面这些接口:
1*命令相关
//command path signals
.c3_p0_cmd_clk (clk_ddr3),
.c3_p0_cmd_en (mcb3_cmd_en),
.c3_p0_cmd_instr (mcb3_cmd_instr),
.c3_p0_cmd_bl (mcb3_cmd_bl),
.c3_p0_cmd_byte_addr (mcb3_cmd_byte_addr),
.c3_p0_cmd_empty (mcb3_cmd_empty),
.c3_p0_cmd_full (mcb3_cmd_full),
以en、instr、byte_addr为主,当进行读写操作时,这三个要同时变化;
2*读写相关
//write datapath
.c3_p0_wr_clk (clk_ddr3),
.c3_p0_wr_en (mcb3_wr_en),
.c3_p0_wr_mask (mcb3_wr_mask),
.c3_p0_wr_data (mcb3_wr_data),
.c3_p0_wr_full (mcb3_wr_full),
.c3_p0_wr_empty (mcb3_wr_empty),
.c3_p0_wr_count (mcb3_wr_count),
.c3_p0_wr_underrun (mcb3_wr_underrun),
.c3_p0_wr_error (mcb3_wr_error),
//read datapath
.c3_p0_rd_clk (clk_ddr3),
.c3_p0_rd_en (mcb3_rd_en),
.c3_p0_rd_data (mcb3_rd_data),
.c3_p0_rd_full (mcb3_rd_full),
.c3_p0_rd_empty (mcb3_rd_empty),
.c3_p0_rd_count (mcb3_rd_count),
.c3_p0_rd_overflow (mcb3_rd_overflow),
.c3_p0_rd_error (mcb3_rd_error)
以en、data、full为主;
4)简单举例:
1*先说指令
localparam MCB_CMD_WR = 3'b000; //mcb write cmd
localparam MCB_CMD_RD = 3'b001; //mcb read cmd
localparam MCB_CMD_WP = 3'b010; //mcb write with auto precharge cmd
localparam MCB_CMD_RP = 3'b011; //mcb read with auto precharge cmd
localparam MCB_CMD_RF = 3'b100; //mcb refresh cmd
2*简单举例(以写为例,代码不全,领会思路)
//先将数据存入MCB的FIFO中;
if(cnt_fifo_rd>='d64) begin //write 64 at one time 1KB
cnt_fifo_rd <= cnt_fifo_rd;
ad_fifo_rd_en_r <= 'b0; //去读本地fifo中的数据
end
else begin
cnt_fifo_rd <= cnt_fifo_rd + 'b1;
ad_fifo_rd_en_r <= 'b1;
end
assign mcb3_wr_en = ad_fifo_rd_en_r; //实际上要延迟一个时钟,这里做演示就不延迟了。
assign mcb3_wr_data = ad_fifo_rd_data; //同时传数据
//产生写命令的请求
if(!rst_n)
u_wr_cmd_en <= 'b0;
else if(u_wr_cmd_done) //检测到指令发送完成,清除标志信号?
u_wr_cmd_en <= 'b0; //clear
else if(cnt_fifo_rd=='d63) //写入63次后产生写命令请求(提前一个产生,等存够64次后刚好产生写请求
u_wr_cmd_en <= 'b1; //enable
else
u_wr_cmd_en <= u_wr_cmd_en;
end
//检测到写命令请求,发出写指令
if(u_wr_cmd_en) begin //write
mcb3_cmd_instr_r <= MCB_CMD_WP;
mcb3_cmd_byte_addr_r <= u_wr_addr;
mcb3_cmd_bl_r <= mcb3_wr_bl;
mcb3_cmd_wr_p <= 'b1;
mcb3_cmd_rd_p <= 'b0;
end
assign u_wr_cmd_done0 = mcb3_cmd_en&(mcb3_cmd_instr== MCB_CMD_WP); // 用户写指令发送完成,产生标志信号
MCB_WR_EXAMPLE
【实战经验】--Xilinx--IPcore--MCB(DDR3)运用的更多相关文章
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)
RAC 特殊问题和实战经验(五) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...
- (转)国内外三个不同领域巨头分享的Redis实战经验及使用场景
随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...
- MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验
原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师年一线实战经验,我当然不能和我的老师平起平坐,得到老师三分之一的 ...
- MySQL索引实战经验总结
MySQL索引对数据检索的性能至关重要,盲目的增加索引不仅不能带来性能的提升,反而会消耗更多的额外资源,本篇总结了一些MySQL索引实战经验. 索引是用于快速查找记录的一种数据结构.索引就像是数据库中 ...
- 第9期Unity User Group Beijing图文报道:《Unity实战经验分享》
时间来到了金秋九月,北京UUG活动也来到了第九期.本次活动的主题为<Unity实战经验分享>,为此我们邀请了3位资深的行业大神.这次我们仍然在北京市海淀区丹棱街5号微软大厦举行活动,在这里 ...
- ASP.NET Core & Docker 实战经验分享
一.前言 最近一直在研究和实践ASP.NET Core.Docker.持续集成.在ASP.NET Core 和 Dcoker结合下遇到了一些坑,在此记录和分享,希望对大家有一些帮助. 二.中间镜像 我 ...
- Jenkins高级用法 - Jenkinsfile 介绍及实战经验
系列目录 1.Jenkins 安装 2.Jenkins 集群 3.Jenkins 持续集成 - ASP.NET Core 持续集成(Docker&自由风格&Jenkinsfile) 4 ...
- HDFS配置参数及优化之实战经验(Linux hdfs)
HDFS优化之实战经验 Linux系统优化 一.禁止文件系统记录时间 Linux文件系统会记录文件创建.修改和访问操作的时间信息,这在读写操作频繁的应用中将带来不小的性能损失.在挂载文件系统时设置no ...
- Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)
Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码) 转 https://blog.csdn.net/lhl1124281072/article/details/800 ...
随机推荐
- 常用方法 Excel转换为DataSet
注意一下Excel格式,我平时导入的是xlsx /// <summary> /// Excel 转换为 DataSet /// </summary> /// <param ...
- A@G!C005
AGC005 A STring 不会,有没有老鸽蕉蕉我/kk/kel/dk https://agc005.contest.atcoder.jp/submissions/7926986 B Minimu ...
- 【CSP-S膜你考】即时战略(模拟)
Problem B. 即时战略 (rts.c/cpp/pas) 注意 Input file: rts.in Output file: rts.out Time Limit : 2 seconds Me ...
- 【CF765F】Souvenirs
[CF765F]Souvenirs 题面 洛谷 题解 我们可以发现,对于某个右端点\(i\),左端点\(j\)在由\(i\rightarrow 1\)的过程中,每一段的答案是单调不增的,由这个性质,我 ...
- unity:坐标变换 - 两个函数
在cocos中,我们知道有如下的坐标变换函数: CCPoint convertToNodeSpace(const CCPoint& worldPoint);CCPoint convertToW ...
- Java之创建文件并写入数据
应用场景:以OJ项目为例,创建对应的.in或.out文件,并将相关的数据写入. 核心代码如下: /** * 创建文件 * @param data * @param basedir * @param n ...
- GlusterFS 安装
一.简介 GlusterFS 是近年兴起的一个高性能开源分布式文件系统,其目标是全局命名空间.分布式前端的高性能文件系统,目前已被 RedHat 看中,GlusterFS 具有高扩展.高可性.高性能. ...
- Spring实现多数据源配置
一.前言 对于小型项目,服务器与数据库是可以在同一台机子上的,但随着业务的庞大与负责,数据库和服务器就会分离开来.同时随着数据量的增大,数据库也要分开部署到多台机子上. 二.Spring配置文件修改 ...
- poi导出word表格
代码如下: package com.ksource.pwlp.util; import java.io.FileOutputStream; import java.math.BigInteger; i ...
- hue创建的hdfs数据在hdfs无法删除的问题。
在linux时删除时出现: rmr: Permission denied: user=root, access=ALL, inode="/user/root/.Trash/191128080 ...