Xilinx XDMA 例程代码分析与仿真结果

本文详细介绍了PCIe的基础知识,包括数据链路与拓扑结构,以及Xilinx 7Series FPGA中PCIe IP核的配置和使用。内容涵盖配置参数、DMA引擎、BAR映射、描述符设置和传输过程。通过实例分析了PCIe DMA传输的完整流程,包括H2C和C2H的数据传输,以及传输完成后状态的验证。

PCIe学习笔记系列:

  1. PCIe基础知识及Xilinx相关IP核介绍
    概念了解:简单学习PCIe的数据链路与拓扑结构,另外看看有什么相关的IP核。
  2. 【PG054】7 Series Integrated Block for PCI Express IP核的学习
    基础学习:关于Pcie IP核的数据手册,学习PCIe相关的IP核的配置参数及其对应的含义。
  3. Xilinx PCIe IP核示例工程代码分析与仿真
    基础学习:关于PCIe IP核的仿真,学习PCIe的配置流程以及应用过程。
  4. Xilinx XDMA 例程代码分析与仿真结果
    应用学习:关于Xilinx PCIe DMA IP核的仿真,学习 PCIe DMA 的配置过程以及具体的数据传输流程。
  5. XDMA linux平台调试过程记录
    应用学习:关于XDMA的实际调试过程,可在此基础上定制自己的需求。

1 IP核的配置

1.1 Basic

在这里插入图片描述

1.2 PCIe ID

在这里插入图片描述

1.3 PCIe:BARs

在这里插入图片描述

1.4 PCIe:MISC

在这里插入图片描述

1.5 PCIe:DMA

在这里插入图片描述

2 生成IP核的例程

2.1 例程结构

配置好IP核后右击IP核选择Open Ip Exanple Design...打开例程
在这里插入图片描述

例程的结构:
在这里插入图片描述

当然,右边的接口根据自己是否使能会有变化。因为用于仿真,所以我们在BAR中同时勾选了AXI4-Lite master interface和DMA Bypass interface,所以仿真工程同时会有这三个接口。

2.2 例程的仿真

生成的例程的TestBench环境中有一个PCI Express Root Port 模型,可以与提供的PIO(Programmed Input/Output ,PIO)设计或与个人设计一起使用。模型的目的是为下游提供源机制的TLP流激励用户的设计,以及在仿真环境中从用户设计接收上游PCI Express TLP流的机制。初始化核心配置空间、创建TLP事务、生成TLP日志以及提供创建和验证测试的接口的所有重要工作都已完成。不需要自己搭建testbench。

Root Port 模型包括:

  • 测试编程接口(TPI),激励端点设备PCI Express。
  • 演示如何使用测试程序TPI的示例测试。
  • 所有 Root Port模型组件的Verilog源代码,允许自定义test bench。

模型结构及与PCIe DMA Subsystem 的连接:

在这里插入图片描述

在这里插入图片描述

大致的结构是usrapp_tx usrapp_rx通过dsport与DUT进行TLP包的收发。DUT中包含PCIe DMA Subsystem。

dsport则模拟数据链路层以及物理层在数据通信过程中的相关处理。

usrapp_com模块中则是一些共享的逻辑,比如TLP处理以及log文件的输出。

因为先安装的Vivado 2017.1(XDMA IP核版本为3.1),后安装的2018.3(对应版本为4.1),导致我的2018.3和Modelsim联合仿真环境有问题,所以使用2017.1版本进行仿真。

2.2.1 测试用例

DMA Subsystem for PCIe 可以配置成AXI4 内存映射(AXI-MM)或者AXI4-Stream(AXI_ST)接口。仿真测试用例通过读取配置寄存器来判断是配置的哪个接口。然后基于AXI的设置,执行对应的仿真。

测试用例名称 描述
Dma_test0 AXI-MM接口的仿真,读取Host的内存进行然后写入道block RAM中(H2C)。然后读取block RAM中的数据然后写入到Host内存(C2H)。这个测试用例最后会比较数据的正确性
Dma_stream0 AXI4-Stream接口仿真。从Host内存读取数据并发送到AXI4-Stream用户接口(H2C),然后数据被环回到主机内存(C2H)。

H2C和C2H的仿真模型有64字节的传输大小限制。

2.2.2 仿真过程

官方手册描述的仿真步骤:

AXI4内存映射接口

首先,测试用例启动H2C引擎,H2C引擎从Host内存中读取数据然后写到用户端的Block RAM。然后,测试用例启动C2H引擎,从Block RAM 中读取数据然后写到Host 内存中。仿真的步骤:

  1. 测试用例为H2C引擎设置一个描述符。
  2. H2C描述符给出数据长度64字节、源地址(Host)和目的地址(Card)。
  3. 将数据(增量数据)写入源地址空间。
  4. 测试用例也为C2H引擎设置了一个描述符。
  5. C2H描述符提供数据长度64字节、源地址(Card)和目的地址(Host)。
  6. PIO写入H2C描述符启动寄存器。
  7. PIO写入H2C控制寄存器以启动H2C传输。
  8. DMA传输将数据从host源地址传输到block RAM目的地址。
  9. 然后测试用例启动C2H传输。
  10. PIO写入C2H描述符启动寄存器。
  11. PIO写入C2H控制寄存器以启动C2H传输。
  12. DMA传输将数据从block RAM源地址传输到host目的地址。
  13. 测试用例比较数据的正确性。
  14. 测试用例检查 H2C和C2H描述符完成计数(值为1)。

AXI-Stream 接口

对于 AXI-Stream,示例设计是一个环回设计。首先,测试用例启动C2H引擎。C2H引擎等待H2C引擎传输的数据。然后,测试用例启动H2C引擎。H2C引擎从host读取数据并发送到Card, Card被循环回给C2H引擎。然后,C2H引擎获取数据,并将数据写回host内存。下面是仿真步骤:

  1. 测试用例为H2C引擎设置一个描述符。
  2. H2C描述符提供数据长度64字节、源地址(Host)和目的地址(Card)。
  3. 将数据(增量数据)写入源地址空间。
  4. 测试用例也为C2H引擎设置了一个描述符。
  5. C2H描述符给出数据长度64字节、源地址(Card)和目的地址(host)。
  6. PIO写入C2H描述符启动寄存器。
  7. PIO写入C2H控制寄存器,首先启动C2H传输。
  8. C2H引擎启动,等待来自H2C端口的数据。
  9. PIO写入H2C描述符启动寄存器。
  10. PIO写入H2C控制寄存器以启动C2H传输。
  11. H2C引擎从主机源地址获取数据到Card目的地址。
  12. 数据环回到C2H引擎。
  13. C2H引擎从Card获取数据,然后发送和写入host内存目标地址。
  14. 测试用例检查H2C和C2H描述符完成计数(值为1)。

2.2.3 Descriptor Bypass 模式

当H2C和C2H的Channel 0 选择为描述符旁路选项时,可以进行描述符旁路模式的Vivado仿真。示例设计产生了一个描述符准备泵在描述符旁路模式接口。
当传输开始时,一个H2C和一个C2H描述符在描述符旁路接口中传输,然后按照上面章节的解释执行DMA传输。描述符仅为64字节的传输设置。

2.4 测试任务

名称 描述
TSK_INIT_DATA_H2C 这个任务为H2C引擎生成一个描述符,并在主机内存中初始化源数据。
TSK_INIT_DATA_C2H 这个任务为C2H引擎生成一个描述符。
TSK_XDMA_REG_READ 这个任务读取DMA子系统的PCIe寄存器。
TSK_XDMA_REG_WRITE 这个任务写DMA子系统的PCIe寄存器。
COMPARE_DATA_H2C 这个任务比较host内存中的源数据和写入到block RAM的目标数据。这个任务在AXI4 Memory Mapped仿真中使用。
COMPARE_DATA_C2H 该任务将hose内存中的原始数据与C2H引擎写入host的数据进行比较。这个任务在AXI4 Memory Mapped仿真中使用。
TSK_XDMA_FIND_BAR 该任务在不同启用的bar之间查找XDMA配置空间。(BAR0 BAR6)
TSK_WRITE_CFG_DW 对RP的配置空间进行写操作

值得一提的是,我们在Xilinx PCIe IP核示例工程代码分析与仿真中已经了解过,TSK_TX_TYPE0/1_CONFIGURATION_WRITE是对EP的配置空间进行写操作。而TSK_WRITE_CFG_DW是对RP的配置空间进行写操作,同理,读操作TSK命名格式也是类似的。

3 仿真结果

3.1 tx_usrapp:pci_exp_usrapp_tx中的初始化

Xilinx PCIe IP核示例工程代码分析与仿真关于7 Series FPGAs Integrated Block for PCI Express IP核的仿真分析过程类似。分析验证一下上述的仿真步骤。

首先查看测试用例的名称,文件层次为board/RP/tx_usrapp:

在这里插入图片描述

其中有一个initial块:

initial begin
  dmaTestDone         = 0;
  pfIndex             = 0;
  pfTestIteration     = 0;

  expect_status       = 0;
  expect_finish_check = 0;
  testError           = 1'b0;
  // Tx transaction interface signal initialization.
  pcie_tlp_data       = 0;
  pcie_tlp_rem        = 0;

  EP_BUS_DEV_FNS      = EP_BUS_DEV_FNS_INIT;
  // Payload data initialization.
  TSK_USR_DATA_SETUP_SEQ;

  board.RP.tx_usrapp.TSK_SIMULATION_TIMEOUT(10050);
  board.RP.tx_usrapp.TSK_SYSTEM_INITIALIZATION;
  board.RP.tx_usrapp.TSK_BAR_INIT;

  // Find which BAR is XDMA BAR and assign 'xdma_bar' variable
  board.RP.tx_usrapp.TSK_XDMA_FIND_BAR;

  if ($value$plusargs("TESTNAME=%s", testname))
      $display("Running test {%0s}......", testname);
  else begin
|
      // decide if AXI-MM or AXI-ST
      board.RP.tx_usrapp.TSK_XDMA_REG_READ(16'h00);
      if (P_READ_DATA[15] == 1'b1) begin
|  testname = "dma_stream0";
          $display("*** Running XDMA AXI-Stream test {%0s}......", testname);
      end
      else begin
         testname = "dma_test0";
         $display("*** Running XDMA AXI-MM test {%0s}......", testname);
      end
  end

  //Test starts here
  if (testname == "dummy_test") begin
      $display("[%t] %m: Invalid TESTNAME: %0s", $realtime, testname);
      $finish(2);
  end
  `include "tests.vh"
  else begin
      $display("[%t] %m: Error: Unrecognized TESTNAME: %0s", $realtime, testname);
      $finish(2);
  end


end

line15: TSK_USR_DATA_SETUP_SEQ 负载数据初始化

将DATA_STORE中的数据初始化位0~4095。

line17: TSK_SIMULATION_TIMEOUT

设置board.RP.rx_usrapp.sim_timeout的值为10050

line18: TSK_SYSTEM_INITIALIZATION 对RP进行配置,等待系统初始化完成以及建立链路

  • 等待复位完成
  • 等待链路建立

在同一个源文件找到TSK_SYSTEM_INITIALIZATION 的定义进行分析:

  1. 首先TSK_WRITE_CFG_DW(32’h01, 32’h00000007, 4’h1),对RP配置空间地址32’h01写32’h00000007,4’h1是字节选通,含义是选通低字节。

首先回顾一下Xilinx type0(桥设备为type1,非桥设备为type0)PCIe设备的配置空间:

在这里插入图片描述

注意一下,数据位宽是32位,地址与EP写配置空间命令一样,指的是DW地址。

所以指令的作用是:

在这里插入图片描述

最主要的作用是配置为主设备。

  1. TSK_READ_CFG_DW(12’h068/4)

读取字节地址为0x68的配置空间寄存器,字段为Device Control Register

其他字节可以看Xilinx PCIe IP核示例工程代码分析与仿真的“2.2.2 PCIe配置空间”,这里就不重复贴图了。

读出的值cfg_rd_data为32’h0。

  1. cfg_usrapp.TSK_WRITE_CFG_DW(DEV_CTRL_REG_ADDR/4,( board.RP.cfg_usrapp.cfg_rd_data | (DEV_CAP_MAX_PAYLOAD_SUPPORTED * 32)) , 4’h1)

其中board.RP.cfg_usrapp.cfg_rd_data | (DEV_CAP_MAX_PAYLOAD_SUPPORTED * 32)=32’h0 | 32’40 = 32’h40

作用:在原配置的基础上设置Max_Payload_Size的值。

在这里插入图片描述

可见,设置Max_Payload_Size = 512Byte

以上3步的波形:

在这里插入图片描述

  1. TSK_SYSTEM_CONFIGURATION_CHECK

这一步使用TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12’h070, 4’hF);读取字节起始地址为12’h070的DW,字段为Link ControlLink Status。读取到的数据为32’h10410000。

在这里插入图片描述

此DW的bit[19:16]代表链路速度(我们设置的为2.5GT/s)。bit[23:20]代表链路宽度(我们设置为4)。

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChipWeaver

觉得有用的话点个赞吧 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值