zedboard如何从PL端控制DDR读写(五)
有了前面的一堆铺垫。现在终于开始正式准备读写DDR了,开发环境:VIVADO2014.2 + SDK。
一、首先要想在PL端通过AXI去控制DDR,我们必须要有一个AXI master,由于是测试,就不自己写了,直接用package IP生成,方法如下:
1.选择package IP工具

2.创建新的AXI外设

3.接口类型选择Full,模式选择master,如果你不关心里面的详细实现过程,那么直接finish就好了。(后面我们会继续分析里面的过程)

二、创建好了IP,自然要加入到IP库里,如图,在IP Catalog空白处右键,设置,把刚刚生成IP的路径放进去:

三、接下来创建BD块,把整个硬件系统搭建好:

需要指出的是,由于我们需要用到HP,所以在zynq的配置里面把HP勾选上,任选一个通道就行

四、然后校验正确性,产生输出文件,创建BD块顶层,这都是套路,一路走下来就行。如果你想在调试里看到产生的AXI信号,那么需要对AXI标记一下debug

五、综合,set up debug,然后生成比特流,并将其导入到SDK;在SDK里跑个hello world 就行,主要目的是用CPU去把DDR控制器初始化。
到这里整个过程基本就结束了,接下来看仿真波形:

放大一点,可以看到每次地址的步进长度是十进制的64,这是因为我们的突发长度设置的是16,位宽为32bit。

但是问题来了,我们在上一节里面说过,有一部分地址是连到了OCM的,那么这一部分地址是多少呢?UG585里给出了如下说明:

我们是从全0地址开始写数据的,然而全0的地址刚好分配到了OCM,这TM就很尴尬了。一开始想让程序运行的时间长一点,这样地址是不是就可以跑到0x0008_0000了?然而并没有什么用,因为地址只跑到00001000就停止了,如图:

还记得前面打包AXI IP时候我们说过要分析其过程吗?其实那里就已经挖了一个坑了,具体见代码:

这是AXI的写数据状态机,(可以看到,官方也是用一段式状态机来实现整个时序的,印证了前面三段式状态机不好实现的说法),从写状态到读状态的跳变是由writes_done信号来控制的,那么这个writes_done又是怎么产生的呢?继续看代码:

writes_done是由write_burst_counter的高位进位来控制的,再继续找write_burst_counter:

在这个计数器里有一个很关键的位C_NO_BURSTS_REQ ,在代码的低179行,它的定义如下:
localparam integer C_NO_BURSTS_REQ = C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/)-);

C_M_AXI_BURST_LEN我们设置的是16,C_M_AXI_DATA_WIDTH是32,clogb2可以理解为计算以2为底的某个数的对数,那么最后得到的C_NO_BURSTS_REQ = 6;也就是说write_burst_counter的位宽是7为,当最高位为1时,写数据停止。也就是只会发生64次写数据,之后计数器和写地址就会归零。那么64次写数据乘以每次突发长度16再乘以位宽4个字节,最后得到的数值是4096,换算成16进制刚好是0x00001000。
所以要想真正的往DDR里面写数据,我们还需要对代码进行修改。
到这里离成功就已经不远了
zedboard如何从PL端控制DDR读写(五)的更多相关文章
- zedboard如何从PL端控制DDR读写(七)
前面已经详细介绍了从PL端如何用AXI总线去控制DDR的读写,并且从AXI_BRESP的返回值来看,我们也是成功写入了的.但是没有通过别的方式来验证写入的数据的话,总是感觉差了点什么. 今天试了一把从 ...
- zedboard如何从PL端控制DDR读写(六)
上一节说到了DDR寻址的问题,如下图: 从官方文档上我们看到了DDR的地址是从0008_0000开始的,那么我们开始修改Xilinx给我们提供的IP核代码.其实很简单,上一节已经分析了地址停留在000 ...
- zedboard如何从PL端控制DDR读写(四)
PS-PL之间的AXI 接口分为三种:• 通用 AXI(General Purpose AXI) — 一条 32 位数据总线,适合 PL 和 PS 之间的中低速通信.接口是透传的不带缓冲.总共有四个通 ...
- zedboard如何从PL端控制DDR读写(一)
看了一段时间的DDR手册,感觉大体有一点了解了,想要实际上板调试,然而实验室可用的开发板不多,拿了一块zynq板看了看,DDR确实有,但是已经集成了控制器,而且控制器还放到了PS端,PL只能通过AXI ...
- zedboard如何从PL端控制DDR读写(三)——AXI-FULL总线调试
之前的项目和培训中,都只用到了AXI-Lite或者AXI-Stream,对于AXI-FULL知之甚少,主要是每次一看到那么多接口信号就望而却步了. 现在为了调试DDR,痛下决心要把AXI-FULL弄懂 ...
- zedboard如何从PL端控制DDR读写(二)——AXI总线
虽然Xilinx已经将和AXI时序有关的细节都封装起来,给出了官方IP和向导生成自定义IP,用户只需要关注自己的逻辑实现,但是还是有必要简单了解一下AXI的时序,毕竟咱是做硬件设计的. AXI(Ad ...
- 第十二章 ZYNQ-MIZ702 PS读写PL端BRAM
本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将 ...
- 第十一章 ZYNQ-MIZ701 PS读写PL端BRAM
本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将 ...
- MIG IP控制DDR3读写测试
本文设计思想采用明德扬至简设计法.在高速信号处理场合下,很短时间内就要缓存大量的数据,这时片内存储资源已经远远不够了.DDR SDRAM因其极高的性价比几乎是每一款中高档FPGA开发板的首选外部存储芯 ...
随机推荐
- UIkit框架之uUInavigationController
1.继承链:UIviewcontroller:uiresponder:NSObject 2.如果你想使用一些动画转换,可以遵守 UINavigationControllerDelegate 3.创建导 ...
- .Net MVC框架 + WCF 搭建 集群开发
http://www.cnblogs.com/zhijianliutang/archive/2012/01/28/2258844.html
- BZOJ 1500 Splay 全操作
好久没写splay了,写一发(写了一节课,调了一节课) #include <iostream> #include <cstring> #include <cstdio&g ...
- C语言共用体内存计算
其实union(共用体)的各个成员是以同一个地址开始存放的,每一个时刻只可以存储一个成员,这样就要求它在分配内存单元时候要满足两点: 1.一般而言,共用体类型实际占用存储空间为其最长的成员所占的存储空 ...
- nat转换
实验目的: (1) 了解nat转换 (2) 了解nat转换配置命令 (3) 了解哪些是私有ip地址哪些不是私有ip地址 实验工具: 华为eNSP模拟器和Wireshar 实验拓 ...
- python数据结构与算法——图的基本实现及迭代器
本文参考自<复杂性思考>一书的第二章,并给出这一章节里我的习题解答. (这书不到120页纸,要卖50块!!,一开始以为很厚的样子,拿回来一看,尼玛.....代码很少,给点提示,然后让读者自 ...
- Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- poj 1363
这是一道数据结构的问题,用到了栈的知识.题目大意讲的是每一次有N辆车从A到B,但是要将车辆的顺序重新排列,可以通过中转站C来辅助排列,但是C符合先进后出的原则,这一点和栈的特性相同. 整个重新排序的过 ...
- QTableWidget实用技巧(转)
http://blog.csdn.NET/mingxia_sui/article/details/7681863 在使用Qt不多的日子里,已经两次用到了QTableWidget这个控件,也慢慢的习惯和 ...
- 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询
前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...