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开发板的首选外部存储芯 ...
随机推荐
- C++复习-练习-1
上周做多媒体技术的作业,JPEG编码问题:FDCT.量化.逆量化和IDCT,只是简单套公式,但还是感觉自己C++好渣...太久没做,手生了,可怕可怕. 所以复习了下文件操作和..基础操作.这里贴一些当 ...
- [原创] 用两个stack实现queue的功能
#include <iostream> #include <stack> using namespace std; class doubleStackToQueue { pri ...
- Linux版网易云音乐播放音乐时无限显示“网络错误”的解决办法
安装 gstreamer0.10-plugins-good debian类系统: -plugins-good
- Bean
1. Bean配置项 1.1. ID 在整个IOC容器中Bean的唯一标识 1.2. Class 具体要实例化的类 1.3. Scope 范围,作用域 1.4. Constructor argumen ...
- Sea.js学习4——Sea.js的配置
可以对 Sea.js 进行配置,让模块编写.开发调试更方便. seajs.config seajs.config(options) 用来进行配置的方法. seajs.config({ // 别名配置 ...
- morhia解决BigDecimal映射问题
错误信息:morphia No usable constructor for java.math.BigDecimal 解决办法:增加自定义类型转换器,代码如下 package cn.huilink. ...
- CentOS7 登陆密码遗忘和修改
在虚拟机当中我们设置的linux密码可能会遗忘,那么我们怎么来找回密码,并且重置密码呢? 1:我们需要进入单用户模式才能修改密码 1:重启linux,进入grub界面,敲击空格键暂停 2:按 ...
- 从 Bootstrap 2.x 版本升级到 3.0 版本
摘自http://v3.bootcss.com/migration/ Bootstrap 3 版本并不向后兼容 v2.x 版本.下面的章节是一份从 v2.x 版本升级到 v3.0 版本的通用指南.如需 ...
- 学习laravel之路由问题 404
今天配置路由的时候,只有原来的自带路由可用: Route::get('/', function(){ return View::make('hello');}); 再网上搜索了办法:来自:htt ...
- [solr] - 环境搭建2
前面使用Tomcat搭建solr,参考文章: http://www.cnblogs.com/HD/p/3977799.html 原来solr可以不使用tomcat/jboss等服务器,它自身已经集成了 ...