【实战经验】--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 ...
随机推荐
- 《ELK Stack权威指南》读书笔记
Logstack: 1.Logstack介绍:Logstash is an open source data collection engine with real-time pipelining c ...
- 洛谷 P1972 [SDOI2009]HH的项链-二维偏序+树状数组+读入挂(离线处理,思维,直接1~n一边插入一边查询),hahahahahahaha~
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演
题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...
- Spring概念详解
1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2E ...
- mysql优化查找执行慢的sql
想要进行sql优化,肯定得先找出来需要优化的sql语句 一.mysql有一个自带的sql执行慢记录日志文件,所记录的日志取决于参数long_query_time控制,默认情况下long_query_t ...
- element UI中的select选择器的change方法需要传递多个值
如果直接调用change事件,不传任何参数,则可以获取到当前选中的值(因为默认会将event参数传递过去) 场景: 你需要将select选择器 ”选中的当前元素“ 和 ”其他你需要的值“ 一起传递过去 ...
- oc界面开发整理
oc界面开发整理 ViewController.h from test82 #import <UIKit/UIKit.h> @interface ViewController : UIVi ...
- 【重庆师范大学】PHP博客训练-Thinkphp
设计数据库 CREATE TABLE `user` ( `user_id` int unsigned NOT NULL AUTO_INCREMENT, `username` varchar() COM ...
- docker 镜像制作(jupyter)
docker pull centosdocker run -it -d --name test-centos1 centosdocker exec -it test-centos1 /bin/bash ...
- sumdoc t411 dir.txt
C:\Users\zhoufeiyue\Documents\sumdoc t411\(9+条消息)redis Jedis存取list对象和map - shenjianxz的博客 - CSDN博客.mh ...