学习环境

win10 64bit

vivado 2017.4

modelsim 10.6d

KC705开发板

学习目的

1)理解 AXI Memory Mapped to PCI Express IP 用法

2)理解 AXI Central Direct Memory Access (CDMA) 用法

3)理解 AXI4 Interconnect 用法

工程恢复

1.修改tcl脚本

从官方下载的xapp1171压缩包,解压后只有tcl脚本文件,需要用tcl脚本文件来生成工程文件。解压出来的tcl脚本是对应 Vivado Design Suite 2013.3 版本的, 目前我用的是vivado 2017.4版本, tcl脚本里面的ip版本不对应,生成工程时会报错,所以需要将tcl里面的ip版本与自己使用的vivado版本适配。

以 kintex举例,打开“kintexGenerationScript.tcl” 文件,文本高亮 “xilinx.com:ip ”, 可以看到工程使用了很多ip,

打开vivado 2017.4, 在 ip catalog 搜索相应的ip,修改tcl脚本为ip catalog中显示的版本。

2.生成工程

利用vivado的tcl console 执行tcl脚本,生成工程。

我的tcl脚本

打开vivado,然后在 tcl console 窗口,输入source命令,例如

source E:/work_dir/kintexSubsystemFiles/kintexGenerationScript.tcl, 如果tcl文件修改正确,工程就会恢复出来。注意工程路径。

系统框架

简化后的系统框图如下, pcie root 通过 pcie_cdma_subsystem 对 ddr3_mem 做DMA操作。

pcie_cdma_subsystem 系统框图如下。

pcie_cdma_subsystem 包含5个模块

1)axi_cdma 模块,DMA控制器模块, 详细介绍可以参考 AXI-CDMA学习笔记。

2)axi_interconnect_block , AXI总线互联模块

3)axi_pcie 模块, axi memory map to pcie模块

4)translation_bram , transfer discriptors  AXI-RAM控制器

5)translation_bram_mem , RAM存储器

pcie地址转换

AXI地址空间

pcie downstream方向地址转换

axi_pcie 模块接收 root/host 发过来的 downstream 报文, 根据 axi_pcie 的 PCIE:BARS 配置,换算得到AXI接口的实际访问地址。 PCIE:BARS配置如下,地址位宽支持64bit, 深度64Kbyte, base addr = 0x8100_0000.

64Kbyte的空间,划分为3块,

translation_BRAM : 地址空间 0x8100_0000 ~ 0x8100_7fff , 共计 32K byte

AXI_PCIE_CTL(AXI_PCIE) : 地址空间 0x8100_8000 ~ 0x8100_bfff , 共计 16K byte

AXI_CDMA_LITE(AXI_CDMA) : 地址空间 0x8100_c000 ~ 0x8100_ffff , 共计 16K byte

不需要多余的 PCIe AXI Master 端口去读写 AXI_PCIe_SG, AXI_PCIe_DM 和 AXI_DDR3_MEM 端口, 因为CDMA控制器可以直接读写这些 AXI slave 端口。 如果还有额外的连接,可以在AXI_PCIe的PCIE:BARS最多在增加2个bar配置。

pcie upstream方向地址转换

AXI:BARS 配置用于 AXI_PCIE的 AXI接口发送给root/host的upstream数据流,提供 AXI接口  到 root/host的 动态的地址转换功能。

这里使能了两个bar,

AXI:BAR0 定义为用于scatter/gather DMA 交易的AXI_PCIe_SG端口,通过这个端口,DMA读取和处理来自PCI Express根设备的描述符, 8Mbyte地址空间。

AXI:BAR1定义为data mover DMA交易的AXI_PCIe_DM端口,通过这个端口,DMA从root/host 读取数据, 或者向root/host写入数据,8Mbyte地址空间。

每个AXI:BAR都具有64bit的动态地址转换能力,意味着 读写AXI_BAR0(AXI地址0x8080_0000),经过转换后,实际是对root/host 的地址 0x0000_0000_a000_0000 做读写操作。

每个AXI:BAR的地址翻译可以被单独配置, 配置的方式为通过AXI_PCIe_CTRL端口,对如下寄存器做读写操作。

由于AXI:BAR0, AXI:BAR1都被设置为8M byte的地址空间,所以上述低位地址寄存器的bit[22:0]必须固定为0.

PCIe传输示例

scatter/gather 机制说明

scatter gather 是一种高效的数据传输机制,通过预先编程的指令表(transfer descriptors)来实现自动化的DMA传输调度。这些指令表按照格式存放在PCIE连接的Root complex设备上。这个指令列表被组织成一个传输描述符链。每个描述符描述一个数据传输并有一个地址指针到下一个要处理的连续描述符。最后一个描述符通常会指向回第一个描述符,但非必要。

CDMA scatter gather engine 按照链表顺序处理 descriptors 直到 tail descriptor 。用户通过自己的驱动和应用,将描述符链表创建在root complex的存储空间中。

scatter gather transfer descriptor 定义

每个描述符定义一次DMA传输,最多一次传输8,388,607(0x7f_ffff) byte 数据。

xapp1171 中用两种descriptors : address translation descriptors 和 target data transfer descriptor 。需要注意的是,描述符中的地址都是从DMA引擎角度看的地址空间。 也就是说,传输描述符地址的是 AXI interconnect address mapping ,而不是root/host的地址空间.

Address Translation Descriptors

这种描述符通过写AXI_PCIE_CTRL端口,从而更新 AXI 到 PCIE 转换矢量, 

DMA engine 从 translation BRAM中复制8byte的传输向量到  AXI:PCIE寄存器中去,通过 AXI_PCIE_CTRL接口。

Target Data Transfer Descriptors

描述符用于在 PCIE Root complex 和目标外设之间传输数据,传输的源和目的地址为 AXI_PCIE_DM(0X8000_0000)或者 DDR3 memory(0x0000_0000).

DMA Scatter Gather 操作流程

  1. 设置CDMA为 scatter gather mode , 通过写 AXI_CDMA_LITE控制寄存器0(AXI地址0x8100_c000 或者PCIe:BAR0偏移地址0x0000_c000),使能相应的中断。
  2. 在root/host 的内存中创建一个描述符链表,链表包括 ”地址翻译描述符”  +  “目标数据传输描述符”。
  3. 通过写AXI:BAR0地址翻译寄存器(AXI地址 0x8100_8208~0x8100820c, AXI_PCIE_CTL接口),为AXI_PCIE_SG 接口更新 地址转换矢量。写入AXI:BAR0地址翻译寄存器的值必须 和 host内存中存放描述符链表的基地址相关联,空间大小限制为8Mbyte
  4. 向 translation BRAM中写入合适的地址翻译向量寄存器(AXI地址范围0x8100_0000 ~ 0x8100_7fff 或者 PCIE:BAR0偏移地址 0x0000_0000 ~ 0x0000_7fff), 写入的值指向 host 内存中一个8Mbyte 区域, 存放着被DMA engine传输的数据。
  5. 向DMA CURDESC_PNTR 寄存器写入一个正确的指针(AXI 地址0x8100_c008 or PCIE:BAR0偏移地址 0x0000_c008).
  6. 向DMA TAILDESC_PNTR 寄存器写入一个正确的指针(AXI地址0x8100_c010 or PCIE:BAR0 偏移地址0x0000_c010), 写这个寄存器将触发 DMA  engine 开始获取和处理描述符链表
  7. DMA scatter gather 顺序处理描述符链表,直到TAILDESC_PNTR被处理完,或者一个已经处理完成的描述符。

DMA Scatter Gather 操作示例

操作步骤

以下示例假设 HOST 枚举到 PCIE:BAR0, 并映射到内存地址 0x0000_0000_def0_0000.描述符链表在HOST 内存中起始地址为0x0000_0001_0000_0000.

  1. 设置DMA 为 scatter gather 模式,通过 ROOT complex执行一次 32bit 的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_c000 (AXI 地址 0x8100_c000)写入0x0a00_0100??????
  2. 为AXI_PCIE_SG接口更新PCIE翻译向量,通过ROOT complex执行一次64bit的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_8208 写入 0x0000_0001_0000_0000. 这个值指向 ROOT complex设备中存放DMA 描述符链表的内存偏移地址。
  3. 向 translation BRAM中写入合适的翻译向量

    a. 通过ROOT complex执行一次64bit的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_0000 写入                                         0x0000_ccc0_c000_0000. 这个值对应的地址转移向量,在描述符1器件被更新 并作用于 描述符2.

    b. 通过ROOT complex执行一次64bit的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_0008 写入                                         0x0000_ddd0_d000_0000. 这个值对应的地址转移向量,在描述符3器件被更新 并作用于 描述符4.

  4. 向DMA CURDESC_PNTR 寄存器写入一个正确的指针, 通过 ROOT complex执行一次 32bit 的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_c008 写入0x8080_0000, 这个值对应着 AXI_PCIE_SG基地址 + ROOT complex描述符链表偏移地址(0x0000_0001_0000_0000),这个AXI地址被翻译成ROOT complex的地址。 使得CDMA scatter gather 接口可以直接从HOST内存中(地址0x0000_0001_0000_0000)获取描述符链表。
  5. 向DMA TAILDESC_PNTR 寄存器写入一个正确的指针, 通过 ROOT complex执行一次 32bit 的PCIE 写操作,向PCIE:BAR0地址0x0000_0000_def0_c010 写入0x8080_00C0, 这个值对应着 AXI_PCIE_SG基地址 + ROOT complex描述符链表偏移地址(0x0000_0001_0000_0000),与上一步类似,此AXI地址对应着HOST地址的 0x0000_0001_0000_00c0.写此寄存器使能 DMA scatter gather 操作开始。
  6. DMA scatter gather 顺序处理描述符链表,直到TAILDESC_PNTR(host 内存地址0x0000_0001_0000_00c0)被处理完。

操作图示

描述符链表被创建在ROOT complex 设备的内存中,Descriptors 1-4 存放在基地址为0x0000_0001_0000_000,偏移地址分别为0x00, 0x40, 0x80, 0xc0中,这些描述符不一定非要地址连续,只要包含在 AXI_PCIE_SG对应8Mbyte空间中。AXI地址为0x8080_0000~0x80ff_ffff, 对应在PCIE root complex地址为 0x0000_0001_0000_0000 ~ 0x0000_0001_007f_ffff ,  下图 figure 6 所示, Descriptor 1和3 是 地址转移描述符, Descriptor 2和4 是目标数据传输描述符。

  1. PCIE root写完 DMA TAILDESC_PNTR 寄存器后, DMA scattergather engine开始从 AXI 地址0x8080_0000对应的 ROOT complex地址(0x0000_0001_0000_0000)中读取地址转移描述符。
  2. DMA engine获取并处理 Descriptor1 , 从 translation BRAM的地址0x8100_0000 中复制8byte 到 AXI_PCIE_CTL寄存器d对应的地址0x8100_8210 中。 这些寄存器对应着 AXI_PCIE_DM 地址传输向量。因此,访问AXI_PCIe_DM端口的后续事务被转换为访问PCIe ROOT complex地址0x0000ccc0_c0000000。
  3. Descriptor1 被处理完之后, 描述符状态寄存器的完成标志被更新, DMA DATA Mover 接口准备处理Descriptor 2 .
  4. DMA engine获取并处理 Descriptor2, 从ROOT complex 设备的地址0x0000_ccc0_c000_0000搬运64Kbyte数据到DDR memory的 0x0010_0000 空间中。(下图数据流向仅供参考,非实际数据交互流向)。
  5. Descriptor2 的数据搬运完成之后, 描述符状态寄存器的完成标志被更新,接着处理Descriptor 3和4.
  6. 与Descriptor1,2类似,Descriptor3 更新AXI_PCIE_DM传输向量到 0x0000_ddd0_d000_0000, 因此,Descriptor4 从DDR3 memory 搬运64Kbyte数据到ROOT complex设备的 0x0000_ddd0_d000_0000起始的内存中。(下图数据流向仅供参考,非实际数据交互流向)。

参考文献

1. xapp1171-pcie-central-dma-subsystem.pdf

2. pg034-axi-cdma.pdf

3. pg055-axi-bridge-pcie.pdf

疑问记录

1)AXI MAP中 AXI_PCIe_SG的基地址为0x8080_0000,  AXI_PCIe_DM的基地址为0x8000_0000, 这个地址未在 AXI_PCIe ip中指定,搞不清楚怎么得来的?

2)  AXI_PCIE的 AXI:BARS配置中,使能了两个BAR, BAR0 : 0xa000_0000, BAR1:0xc000_0000 , 这两个BAR地址和AXI_PCIE_SG(0x8080_0000), AXI_PCIE_DM(0x8000_0000), 还有后面示例中的 0x0000_ccc0_c000_0000, 0x0000_ddd0_d000_0000 之间有啥关系。

3)操作示例中 设置DMA scatter gather模式,写入的值为0x0a00_0100, 这个值和AXI_CDMA_LIST寄存器CDMACR对应不上?

xapp1171学习笔记相关推荐

  1. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  2. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  3. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  4. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  5. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

  6. 知识图谱学习笔记(1)

    知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...

  7. 计算机基础知识第十讲,计算机文化基础(第十讲)学习笔记

    计算机文化基础(第十讲)学习笔记 采样和量化PictureElement Pixel(像素)(链接: 采样的实质就是要用多少点(这个点我们叫像素)来描述一张图像,比如,一幅420x570的图像,就表示 ...

  8. Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)

    Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...

  9. MongoDB学习笔记(入门)

    MongoDB学习笔记(入门) 一.文档的注意事项: 1.  键值对是有序的,如:{ "name" : "stephen", "genda" ...

最新文章

  1. Django模板之jinja2模板和CSRF
  2. 在Cisco路由器中配置DHCP服务器
  3. Linux中最方便的管理员获取方法
  4. C语言求积标识符,《C语言程序设计》模拟试卷四.doc
  5. ai保存web格式没有html,存储技巧,讲解AI存储为WEB所用格式的一些知识
  6. java流写入数据库_Java 8:在2分钟内将智能流与数据库一起使用
  7. 优化美国服务器,美国服务器性能优化
  8. 从10秒到2秒!ElasticSearch性能调优实践
  9. Java 序列化与主流编解码技术框架介绍
  10. 软件系统现场服务单(模板)
  11. Linux下使用QQ
  12. 管理文件夹,批量重命名排序
  13. 微软借云重振中国市场希望渺茫
  14. 腾达fh307没有显示服务器名,腾达(Tenda)FH307路由器无线WiFi密码和名称设置
  15. mysql wresp_mysql
  16. springMvc中的校验框架@valid和@validated
  17. 一年读完100本书(1/100)《微习惯》2021-01-18
  18. python里的map是什么意思_map在python中什么意思
  19. OEM版Win7激活原理
  20. 计算机应用领域中CAL代表,计算机应用领域.doc

热门文章

  1. 自动化新闻写作机器人:会不会导致记者失业
  2. matlab2014 整数规划,整数规划模型的Matlab程序实现
  3. web页面注册验证,实现从后端动态获取证码,到前端页面显示
  4. python lackey
  5. Zkeys主机管理系统模板风格
  6. js-函数的prototype
  7. Solidworks装配体打包/Pack and Go和另存为两种方法的区别
  8. java获取输入和运用scanner
  9. android跳转界面动画,Android Activity跳转动画效果
  10. QGIS实现tiff文件转png、jpg等