zedboard如何从PL端控制DDR读写(三)——AXI-FULL总线调试

2024-04-09 15:32

本文主要是介绍zedboard如何从PL端控制DDR读写(三)——AXI-FULL总线调试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文主要是总结一下使用AXI-FULL调试的过程。

  

  首先想到的是用RAM IP核来测试,方法是通过AXI接口向RAM写入一组数据并读出,看起来很简单,然而试了好久都没能出结果。如下图所示,其实AXI RAM就是在本地RAM接口的基础上套了一个AXI的壳

  

  在使用modelsim仿真的时候总是会抛出一个警告,具体的警告类型忘了,下次有机会再尝试。试了好多次都这样,无解

  于是转用FIFO来测试,结果一下子就跑通了。

  FIFO的自定义如下图:

  

  

  一直没搞懂这个ID是用来干嘛的,按理说应该是当系统中存在多个master或者slave的时候,用来标识不同的设备号的,但是也没找到在哪里可以配置这个ID号啊,求解。

 

  然后就是写状态机了,最初打算是用三段式状态机来实现下图的时序,结果发现三段式好像不太适合这种太紧凑的时序

  

  具体的表现如图中箭头所示,当写时序从AW(写地址通道)切换到W(写数据通道)的时候,我是通过判断valid和ready同时拉高(1)则进入下一个状态即W状态(2)的,但是从(1)到(2)的跳变必须经历一个时钟,紧接着在第三段状态机中检测到(2)并且产生实际的输出(3)这个过程中,又会经历一个时钟,这就会导致图中的T1和T2之间多出来了一个周期,时序不满足了。无奈,又换成一段式状态机继续。

 

  由于是对FIFO进行操作,burst类型自然选择是固定长度突发,写地址直接给0不变。这里说一下个人对wstrb的理解,前面也说了,这个信号是表示写阀门,也就是规定WDATA的哪些字节有效。实际上无论把wstrb写成全0还是全1,读出来的数据都是一样的,那么FIFO内部自然没有判断某些字节有效的逻辑,所以在后续读出的时候,需要由我们自行掩码。

  除此之外,个人感觉看着这一大堆的接口,首先不要怕,把所有的接口信号按不同的通道分成5组,一次只操作其中的一组,慢慢的就能完成整个时序的编写了。

 

  最后附上读写的仿真结果:

 

  数据用$random产生,再加上状态机,整个时序如行云流水般的运作起来了,想想还有点小兴奋呢

 

  既然已经看了RAM的xilinx文档,那么FIFO的也得看,这样才能显得雨露均沾。

  先来一张正常本地端口FIFO结构图

  

  所有的信号都还蛮熟悉,结构也还算了解,无非就是同一个FIFO的两个时钟域。

  接着再看AXI接口的FIFO:

  

  这都什么鬼啊,红线蓝线,那么多独立的模块,这是要干嘛?

  自习阅读官方文档,有这么一段话:

  For AXI memory mapped interfaces, AXI specifies Write Channels and Read Channels. Write Channels include a Write Address Channel, Write Data Channel and Write Response Channel. Read Channels include a Read Address Channel and Read Data Channel. The FIFO Generator core provides the ability to generate either Write Channels or Read Channels, or both Write Channels and Read Channels for AXI memory mapped. Three FIFOs are integrated for Write Channels and two FIFOs are integrated for Read Channels. When both Write and Read Channels are selected, the FIFO Generator core integrates five independent FIFOs. 

  For AXI memory mapped interfaces, the FIFO Generator core provides the ability to implement independent FIFOs for each channel, as shown in Figure 1-6. For each channel, the core can be independently configured to generate a block RAM or distributed memory or built-in based FIFO. The depth of each FIFO can also be independently configured.

  也就是说,每一个AXI通道最后都会生成成一个独立的跨时钟域FIFO,我们一开始将FIFO的类型配置成了读写,也就是五个通道全开,那么自然就是五个独立的FIFO了。

  这得占用多少资源啊,还好只是测试,不用考虑那么多。


本文转自:http://www.cnblogs.com/christsong/p/5682697.html


这篇关于zedboard如何从PL端控制DDR读写(三)——AXI-FULL总线调试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888532

相关文章

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

C# 读写ini文件操作实现

《C#读写ini文件操作实现》本文主要介绍了C#读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、INI文件结构二、读取INI文件中的数据在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

C#实现文件读写到SQLite数据库

《C#实现文件读写到SQLite数据库》这篇文章主要为大家详细介绍了使用C#将文件读写到SQLite数据库的几种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录1. 使用 BLOB 存储文件2. 存储文件路径3. 分块存储文件《文件读写到SQLite数据库China编程的方法》博客中,介绍了文

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

10. 文件的读写

10.1 文本文件 操作文件三大类: ofstream:写操作ifstream:读操作fstream:读写操作 打开方式解释ios::in为了读文件而打开文件ios::out为了写文件而打开文件,如果当前文件存在则清空当前文件在写入ios::app追加方式写文件ios::trunc如果文件存在先删除,在创建ios::ate打开文件之后令读写位置移至文件尾端ios::binary二进制方式

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get