【实战经验】--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 ...
随机推荐
- windows cmd编辑文本
echo创建一个空的txt文件:echo.>1.txt这里>表示输出到...echo.表示输出一个空行(即换行)>命令可以扩展为>>表示的意思为附加到...例子:1.tx ...
- 「HNOI2015」亚瑟王
传送门 Description 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟 ...
- BIND配置
一,简介 相对于存储和大数据领域,CDN是一个相对小的领域,但行行出状元,BIND就是CDN领域的蝉联N届的状元郎.BIND是一款非常常用的DNS开源服务器,全球有90%的DNS用BIND实现.值得一 ...
- qt5 源码编译
源码 qt-everywhere-src-5.11.3 依赖 apt-get install bison build-essential gperf flex ruby python libasoun ...
- js判断字符串是否以指定字符串开头或是否包含指定字符串
1. 用js判断一个字符串是否是以某个子字符串开头如:ssss001是否以ssss开头, 可以这样做: 1 2 3 4 5 6 var fdStart = strCode.indexOf(" ...
- Android Studio 3.4 修改 .android 和.gradle缺省目录-windows7x64专业版环境。
说明:缺省会在用户目录建立.android和.gradle目录.会挤满C盘.可以改变缺省目录. 改变.gradle目录路径示例,修改到D:\android目录,步骤: 1.建立d:\android目录 ...
- vs2015 项目调试出现未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
今天在调试项目不知道怎么了,突然就报未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项.找到的程序集清单定义与程序集引用不匹配. (异常来自 HRESULT:0x80131040) ...
- [转]iview render函数常用总结(vue render函数)
原文地址:https://blog.csdn.net/weixin_43206949/article/details/89385550 iview 的render函数就是vue的render函数ivi ...
- JMeter压测上对于并发的认识误区
1.误区 在JMeter压测过程中,我们通常认为1s内100的并发量(即:QPS为100)的设置如下: 此时,没有再添加额外的控制器.上述中的参数设置解释:Number of Threads(user ...
- Java读取CSV数据并写入txt文件
读取CSV数据并写入txt文件 package com.vfsd; import java.io.BufferedWriter; import java.io.File; import java.io ...