PCIE_DMA实例二:xapp1052的EDK仿真

news2025/1/16 1:37:46

目录

一:前言

二:前期准备

三:操作步骤

四:仿真结果

五:总结


一:前言

     对于有的同学,想要学习基于FPGA的PCIe DMA控制器设计,但是手上没有合适的Xilinx开发板,而且xapp1052又没有提供仿真代码,学习陷入了困境。此文章用EDK搭建一个微小系统,然后用modelsim来仿真xapp1052的DMA收发控制,这样应该是最全面的理解PCIe_DMA了,希望对大家都有帮助。

二:前期准备

1、Xapp1052 Demo(http://download.csdn.net/download/yuzeren48/7723795)

2、ISE14.1套件

3、基本会使用EDK(主要是Xilinx Platform Studio,XPS 和 Software Development Kit,SDK)

三:操作步骤

1、编译库文件,将D:\Xilinx\14.1\ISE_DS\ISE\verilog\mti_se\10.1b\nt\modelsim.ini中选中部分复制粘贴到D:\modeltech_10.1b\modelsim.ini中

2、打开XPS,新建一个最小系统,使用microblaze和PLB总线,总线上挂载的硬件IP如图2所示,硬件的总线地址如图3所示

图2 硬件IP

图3 硬件IP总线地址

3、完成硬件系统搭建后,导出到SDK

4、打开SDK后,先新建一个BSP包,步骤请参考《Xilinx FPGA开发实用教程》

然后新建一个空的Xilinx C Project,命名为example。

在E:\xapp1052\dma_performance_demo\win32_sw\win32_driver\source下找到ioctrl.h,复制粘贴到E:\pcie_edk\EDK\workspace\example\src

在src中添加C文件,命名为RC_example.c。再将

D:\Xilinx\14.1\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers\pcie_v4_01_a\examples\xpcie_rc_enumerate_example.c中的代码复制到RC_example.c中

对RC_example.c做如下修改:

//#define PCIE_CFG_BAR_0_ADDR         0x11110000
#define PCIE_EP_CFG_BAR_0_ADDR       0x0000FFFF        // Remote EP BAR0
#define PCIE_RC_CFG_BAR_0_ADDR      0x0000EEEE         // RC BAR0

添加:

//-------------------BMD Mrd Test
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCR_OFFSET)             = Xil_EndianSwap32(0x00000001);      //1. DMA assert reset
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCR_OFFSET)             = Xil_EndianSwap32(0x00000000);        //
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_ADDR_OFFSET)       = PCIE_RC_CFG_BAR_0_ADDR;            //2. Read DMA TLP Address Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_SIZE_OFFSET)       = Xil_EndianSwap32(0x0000050/);     //3. Read DMA TLP Size Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_COUNT_OFFSET)      = Xil_EndianSwap32(0x00000100);      //4. Read DMA TLP Count Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_PATTERN_OFFSET)    = Xil_EndianSwap32(0xA3A2A1A0);      //5. Read DMA Data Pattern Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCSR_OFFSET)            = Xil_EndianSwap32(0x00010000);      //7. MWr start

或者

//-------------------BMD Mrd Test
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCR_OFFSET)             = Xil_EndianSwap32(0x00000001);      //1. DMA assert reset
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCR_OFFSET)             = Xil_EndianSwap32(0x00000000);        //
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_ADDR_OFFSET)       = PCIE_RC_CFG_BAR_0_ADDR;            //2. Read DMA TLP Address Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_SIZE_OFFSET)       = Xil_EndianSwap32(0x0000050/);     //3. Read DMA TLP Size Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_COUNT_OFFSET)      = Xil_EndianSwap32(0x00000100);      //4. Read DMA TLP Count Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + READ_PATTERN_OFFSET)    = Xil_EndianSwap32(0xA3A2A1A0);      //5. Read DMA Data Pattern Register
*(unsigned int*)(XPAR_PLBV46_PCIE_0_IPIFBAR_0 + DCSR_OFFSET)            = Xil_EndianSwap32(0x00010000);      //7. MWr start

在初始化RC端配置寄存器时,添加代码:

//---------------------------------------------------- Configure RC
//Write Address to PCIe BAR0
HeaderData = PCIE_RC_CFG_BAR_0_ADDR;
XPcie_WriteLocalConfigSpace(XlnxRootComplexPtr, PCIE_CFG_BAR_0_REG, HeaderData);

将RC端pcie_bar0设为0x0000EEEE (有大小端,故实际地址为0xEEEE0000)。

在枚举使需要初始化远端EP,修改代码,使能master enable bit:

ConfigData |= (PCIE_CFG_CMD_BUSM_EN | PCIE_CFG_CMD_MEM_EN | 0x80000000    //master enable bit ); 

修改EP端pcie_bar0为0x0000FFFF(有大小端,故实际地址为0xFFFF0000):

/* Write Address to PCIe BAR0 */
ConfigData = (PCIE_EP_CFG_BAR_0_ADDR | PCIeBusNum | PCIeDevNum | PCIeFunNum);

最后,去掉所有printf函数,打印太慢了,影响仿真。

编译后生成elf文件,打开XPS,设置sim executable:

在Edit中设置preference

然后点击Generate HDL Files,再Launch Simulator

在打开的modelsim脚本栏中输入c;

完成RC编译,再输入s; 开始对RC端仿真。

5、若要仿真整个PCIE DMA,则需要修改..\EDK\simulation\behavioral文件夹下的system_tb.v,在system_tb.v中加入EP端用户逻辑,修改如下:

// START USER CODE (Do not remove this line)
 
  // User: Put your stimulus here. Code in this
  //       section will not be overwritten.
 initial
    begin
      pcie_sysclk_p = 'b1;
      forever #(fpga_0_clk_1_sys_clk_p_pin_PERIOD)
        pcie_sysclk_p = ~pcie_sysclk_p;   //100MHz
    end
 
  initial
    begin
      pcie_sysclk_n = 'b0;
      forever #(fpga_0_clk_1_sys_clk_p_pin_PERIOD)
        pcie_sysclk_n = ~pcie_sysclk_n;   //100MHz
    end
 
reg EP_pcie_sysclk_p;
reg EP_pcie_sysclk_n;
 
  initial
    begin
      EP_pcie_sysclk_p = 'b1;
      forever #()
        EP_pcie_sysclk_p = ~EP_pcie_sysclk_p;   //125 MHz
    end
 
  initial
    begin
      EP_pcie_sysclk_n = 'b0;
      forever #()
        EP_pcie_sysclk_n = ~EP_pcie_sysclk_n;   //125 MHz
    end
 
wire ep_pci_exp_txp;
wire ep_pci_exp_txn;
 
    always@* begin
        plbv46_pcie_0_RXP_pin = ep_pci_exp_txp;
        plbv46_pcie_0_RXN_pin = ep_pci_exp_txn;
    end
 
xilinx_pcie_2_0_ep_v6 # (
 
      .PL_FAST_TRAIN("TRUE")
 
)
EP (
 
      // SYS Inteface
      .sys_clk_p(EP_pcie_sysclk_p),
      .sys_clk_n(EP_pcie_sysclk_n),
      .sys_reset(fpga_0_rst_1_sys_rst_pin),
 
`ifdef ENABLE_LEDS
      // Misc signals
      .led_0(led_0),
      .led_1(led_1),
      .led_2(led_2),
`endif
 
      // PCI-Express Interface
      .pci_exp_txn(ep_pci_exp_txn),
      .pci_exp_txp(ep_pci_exp_txp),
      .pci_exp_rxn(plbv46_pcie_0_TXN_pin),
      .pci_exp_rxp(plbv46_pcie_0_TXP_pin)
 
);
  // END USER CODE (Do not remove this line)

6、打开modelsim,输入以下脚本

cd E:/pcie_edk/EDK/simulation/behavioral

do system_setup.do

c;

do ../bmd_sim/simulate_mti.do

s;

do ../bmd_sim/wave.do

run all

四:仿真结果

这里只贴出DMA写操作的仿真结果

Ep端DMA发送

RC端接收

写入BRAM

五:总结

从搭建系统到最后仿真,工作量还是比较大的。一篇博客很难把每一步都讲得仔仔细细,小编把里面最重要的几个点都给出来了,希望能够帮到有需要的朋友。

对于初学者,可能看了这篇博客觉得不够详细,没法真正理解PCIe DMA的使用,所以小编在最后留下一个支付宝账号【账户:bubble_fish@yeah.net  姓名:俞则人】,10元/份出售以上全部EDK工程文件以及modelsim仿真文件,这样做的目的一是为了激发您学习的动力(花钱买来的东西终究比免费得来的更加珍惜),二是为了赞助我的泡泡鱼团队基金,尊重每一位码农的劳动成果!

✧⁺⸜(●˙▾˙●)⸝⁺✧都看到这了,就劳烦大侠动动你发财的小手点个赞吧!✧⁺⸜(●˙▾˙●)⸝⁺✧

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ETCD(五)写请求执行过程

写请求过程 客户端执行写请求指令 etcdctl put hello world —endpoints 192.168.1.1:12379执行流程: 首先客户端通过负载均衡选择一个etcd节点发起gRPC put方法调用;服务器收到请求后经过gRPC拦截器、Quota模块校验,进入KV Server模块&am…

「物联网时代的新选择」漫途科技推出装配式物联网服务,轻松实现项目落地

随着物联网技术的不断发展,越来越多的企业开始重视物联网系统的应用。然而,在物联网时代,鱼龙混杂,小品牌厂商层出不穷,质量参差不齐,这为系统集成商寻找靠谱的供应商伙伴带来了极大的挑战。 一、如何找靠谱…

Nacos配置中心的配置是怎么加载到spring容器的?

首先看到 org.springframework.boot.SpringApplication#applyInitializers 这个方法。 protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType G…

单链表C语言实现

链表就是许多节点在逻辑上串起来的数据存储方式 是通过结构体中的指针将后续的节点串联起来 typedef int SLTDataType;//数据类型 typedef struct SListNode//节点 {SLTDataType data;//存储的数据struct SListNode* next;//指向下一个节点地址的指针 }SLTNode;//结构体类型的…

设计模式(GOF)之我见(0)——UML

这里直接梳理画类图时的几个类关系。 类图的语法和功能 关系说明举例依赖&#xff08;Dependency) 偶然的&#xff0c;陌生的。 对类B进行修改会影响到A。 例如&#xff1a;问路时&#xff0c;路人甲给路人乙带路&#xff0c;路人甲的指引必然会影响到路人乙&#xff0c;但是…

在ROS2中使用奥比中光(ORBBEC)的AstraPro深度相机

0.效果演示 1.下载SDK 到官网下载OpenNI2_SDK 记得是下载这个OpenNI2_SDK,而不是下载那个Orbbec_SDK. 2.拷贝至自定义目录 拷贝到你的ubuntu的一个文件夹中&#xff0c;并解压得到 ros2_astra_camera 文件夹 然后新建一个ros2_ws文件夹&#xff0c;再在ros2_ws文件夹中新建…

矩阵链相乘的乘法次数(动态规划)

Description 设 A1, A2, …, An 为矩阵序列&#xff0c;Ai 是阶为 Pi − 1 * Pi 的矩阵 i  1, 2, …, n.试确定矩阵的乘法顺序&#xff0c;使得计算 A1A2…An 过程中元素相乘的总次数最少.Input 多组数据第一行一个整数 n(1≤n≤300) &#xff0c;表示一共有 n 个矩…

真题详解(计算机知识)-软件设计(五十四)

真题详解&#xff08;归并&#xff09;-软件设计&#xff08;五十三)https://blog.csdn.net/ke1ying/article/details/130254861 若无条件转移汇编指令采用直接寻址&#xff0c;则该指令功能是将指令中的地址码送入_____? PC&#xff08;程序计数器&#xff09; 程序计数器&…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试&#xff0c;识别网络安全漏洞&#xff0c;为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作&#xff0c;这就是为什么他们被称为道德黑客或网络安全…

Kyligence Zen 产品体验 --- 初识庐山真面目

简介 Kyligence Zen 是一款数据分析工具&#xff0c;其市场定位是一站式云端指标平台。它基于 Kyligence 核心 OLAP&#xff08;On-Line Analytical Processing&#xff09; 能力打造&#xff0c;提供集业务模型、指标管理、指标加工、数据服务于一体的一站式服务。 其基本的…

Linux: SPI 驱动

文章目录 1. 前言2. SPI 总线驱动2.1 SPI 总线拓扑2.2 SPI 总线工作模式2.3 SPI 总线驱动编写 3. SPI 从设驱动4. SPI 用户空间接口4.1 创建 SPI 总线用户空间字符设备节点4.2 操作 SPI 总线用户字符设备节点 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0…

百趣代谢组学分享,三阴性乳腺癌铁死亡异质性的揭示

百趣代谢组学分享文章标题&#xff1a;Ferroptosis heterogeneity in triple-negative breast cancer reveals an innovative immunotherapy combination strategy 发表期刊&#xff1a;Cell Metabolism 影响因子&#xff1a;31.373 作者单位&#xff1a;复旦大学附属肿瘤医…

DFS与BFS|树与图的遍历:拓扑排序

深度优先搜索DFS DFS每次往最深处搜&#xff0c;搜到叶子节点就返回&#xff0c;然后继续搜&#xff0c;特点&#xff1a;走到头才返回&#xff0c;返回并不是返回最开始&#xff0c;而是每次返回上一层之后&#xff0c;再看这一层能不能往下搜 DFS有回溯和剪枝。返回上一层的过…

维基百科收录企业或品牌词条的规则解析

作为一家知名企业&#xff0c;开展国外市场营销的前提需要做好海外网络口碑营销&#xff0c;解决品牌信任的问题。小马识途营销顾问近来接到很多关于维基百科的咨询&#xff0c;其实做海外营销的企业倒是很有营销意识&#xff0c;主动寻求创建维基百科的很多&#xff0c;但并不…

138. 复制带随机指针的链表

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7

编辑&#xff1a;ll ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7 型号&#xff1a;ADCMP600BKSZ-REEL7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;SC-70-5 批号&#xff1a;2023 引脚数量&#xff1a;5 工作温度&#xff1a;-40C~125C 安装类型&am…

【从零开始学Skynet】实战篇《球球大作战》(四):分布式登录系统

处理玩家的登录&#xff0c;是服务端框架的主要功能之一。分布式系统涉及多个服务&#xff0c;让它们相互配合不产生冲突是一大难点。 1、登录流程 分布式服务端的登录功能要处理好如下两个问题&#xff1a; 问题一&#xff1a;完成角色对象的构建和销毁。如下图所示&#xf…

虹科Panorama SCADA平台连接OPC UA服务器操作详解

一、前言 虹科Panorama SCADA平台支持丰富的通信传输协议&#xff0c;其中包括OPC UA/DA、SNMP、Modbus、BACnet、IEC 61850、MQTT等多种常用的协议类型。OPC UA 采用简单的客户端/服务器的机制进行通信&#xff0c;服务器可在网络中提供大量信息&#xff0c;如有关 CPU、OPC …

pyecharts从入门到精通-地图专题Map-带时间轴与网格的复杂绘图

文章目录 参考安装与查看pyecharts地图实现-Geo导入依赖生成数据集生成2013-2018年的各个省份GDP数据生成2013-2018年的时间列表生成2013-2018年的总GDP设置visulmap的最大最小值范围 生成2013年的网格组合图提取2013年的数据测试绘制map地图绘制折线图line绘制折线图bar绘制折…

图片加水印的简单方法

图片加水印的简单方法~许多小伙伴都习惯在需要对外发布的图片上添加水印&#xff0c;添加水印后就不必担心图片被盗用或被用于其它不良目的&#xff0c;给我们造成不好的影响。然而&#xff0c;许多用户不知道如何为图片添加水印&#xff0c;也不知道应该选择哪种软件来进行操作…