Xilinx PCIE CORE学习

 

目录

前言

1、概述

1.1PCIE 学习入门概述

1.2 本文内容概述

2、IP CORE user interface接口说明

3、TLP包格式

3.1 、3DW/4DW相关说明

3.2 、TLP报文格式

3.3、CplD报文格式

3.4、TLP包解析示例

4、Example PIO 示例

4.1 Example  PIO 架构

4.2 接收/发送引擎代码分析

参考文献


 

前言

首先说明一下,本文是个人的学习和理解,为了方便自己时长温习而进行整理。

在本文最后,附上了参考的博客和书籍。参考文献 1-6 写的非常详细、很有深度,强烈建议逐一阅读原文!

推荐阅读《PCI Express 系统体系结构标准教材》[美]Ravi Budruk 等人著,田玉敏 等人译。

至于我写的博文,但当涉猎、浅尝辄止即可,还请读者多看看参考文献吧!

鉴于我也是一名初学者,本文在一些方面可能表述的不是很完整,还请谅解。以后,会不定期对本文进行补充和完善。

感谢读者的期待,学习之余互相分享、互相借鉴吧!

相关博客推荐阅读:

六、Xilinx PCIE DMA--Sparten6/Kintex-7 BMD

七、Xilinx PCIE DMA 仿真环境搭建

八、win10 jungo windriver

 

1、概述

1.1 PCIE 学习入门概述

首先,关于如何入门PCIE做简单介绍吧。下面仅是笔者自己的学习经验,仅供参考!!!!

然后,明确一下PCIE的学习目标吧!

阶段一:理解掌握TLP报文格式;

阶段二:自己建工程,使用ISE14.4 generate一个PCIE IP core,分析其example PIO工程的状态转移等,并运行do sim.do运行modelsim仿真;

阶段三:基于xapp1052,分析其提供的128示例工程,分析其接收、发送、存储模块;并运行do sim.do,看看其PIO仿真。

阶段四:基于xapp1052提供的BMD文件,自己搭建DMA工程;搭建DMA仿真环境之后,运行do sim.do,看看其PIO仿真。若pio仿真pass,则说明DMA工程工程搭建基本正确。

阶段五:基于xapp1052提供的PC端软件驱动,基于阶段四搭建的DMA工程,进行板卡测试;

                板卡依次测试PIO功能,测试DMA功能。

                在该阶段,需要自己写写PC端的PCIE驱动程序,这一过程或许是痛苦的,但是很有必要!

 

最后,详细学习过程如下:

(1)理解掌握TLP报文格式:3DW/4DW报文头格式;完成报文CplD报文格式。这部分资料,网上有很多。

(2)自己建一个工程,分析一下其example_design 中的PIO设计。可以参考本文最后的参考文献1.。这部分难度不大。

(3)使用modelsim 运行do sim.do,分析一下具体的PIO传输;分析一下官方的PIO仿真是如何搭建仿真环境的。这部分有点难度,也很有用,挺重要的。花点时间认真分析吧!

   在深入理解PIO代码及testbench仿真环境搭建之后,可以开始学习DMA操作。

(4)以xilinx官方的xapp1052作为学习材料,分析其DMA代码,状态转移。这部分,仅是分析代码和状态机,难度不大。

(5)基于xapp1052 BMD文件自己搭建一个DMA工程,使用modelsim运行PIO仿真。若是过了的话,则说明DMA工程搭建基本正确。

(6)搭建DMA的仿真环境,使用modelsim 进行DMA仿真。这部分有难度,不好弄。弄不出来就可以跳过了。

(7)基于xapp1052提供的PC调试驱动软件,以及步骤5搭建的DMA工程,进行板卡测试。

           在进行DMA的学习时,PC端的软件驱动,还是有必要写写的!在PC端实现如何开辟缓存、与PCIE卡进行通信等。

 

上述,仅是个人的学习计划安排,本文不会全部介绍。

 

1.2 本文内容概述

关于PCIE的基础理论概念,可以参考文献2、4、5。

本文以Xilinx ISE K7芯片 PCIE IP core 生成的user design 作为学习例程

vivado里关于PCIE 的IP CORE与ISE里 PCIE的IP core,其user design 逻辑一致。

 

本文主要内容包括:

(1)PCIE IP CORE 用户接口说明;

(2)TLP报文格式,包含:3DW/4DW的区别、TLP报文格式、TLP完成报文格式、TLP报文解析示例;

(3)IP CORE自带的example 工程简要分析。

          IP CORE的generate过程,参考百度等即可,本文不做介绍。

          IP core 的实例化,本文不做介绍。

  本文主要目的,是在了解上述1-3的基础上,让读者对PCIE通信有个大致的概念和了解,对数据流的传输有个整体的概念。

  想要对PCIE更加深入的了解的话,请认真阅读文后的参考文献!

  本文正在整理中,有些说明不到位,望理解。

 

 

 事务层包(TLP),数据链路层包(DLLP),物理层(PLP)产生于各自所在层,最后通过电或光等介质和另一方通讯。其中数据链路层包(DLLP),物理层(PLP)的包平常不需要关心,在 IP 核中封装好了。

在 FPGA 上做 PCIe 的功能,变成完成事务层包(TLP)的处理,即可! 

 PCIe板卡访问PC内存时,板卡向 PC 发送 TLP 包,例如 MWr 包,地址信息就是PC 的物理地址;如果是 MRd 包,那 PC 收到后回复一个完成包,板卡从完成包分析出数据即得到 MRd 读取地址的数据。这是PCIe板卡访问PC.

PC访问PCIe板卡,简单的解释,PC 启动是,BIOS 探测所有的外设。对 PCIe (PCI)设备来说,BIOS 检测到板卡有多少个 BAR 空间,每个空间有多大,然后对应为这些 BAR 空间分配地址。对 PC 设备来说,它能“看”到 PCIe 板卡的空间只有 BAR 空间,也就只能访问这些 BAR 空间。也就是说,板卡可以发送合法的 PCIe TLP 包,并得到 PC 端的相应;但是 PC 端访问板卡被局限在 BAR 空间。 
 

下面举例(参考https://zhuanlan.zhihu.com/p/34096340)

CPU读取一个PCIE设备的memory
在PCIE的拓扑结构中,有一个非常重要的结构,它就是Root Complex(RC)结构。顾名思义,它负责将几个不同的总线协议聚合在一起,如内存的DDR总线处理器的前端总线Front Side Bus(FSB)。在PCIE中,CPU的操作实际是由RC代替完成的,所以一定程度上也可以讲RC代表CPU。
所以当CPU想要访问Endpoint时
Step1:CPU让RC产生一个MRd,经过Switch A,Switch B(第一篇讲到过Switch),到达Endpoint。
Step2: Endpoint 接受数据包,进行数据读取。
Step3:Endpoint返回一个带有数据的Completion.
Step4: RC接受数据包,给CPU。 

Xilinx PCIE CORE学习_第1张图片

 

Xilinx PCIE PIO user design 举例的是CPU对PCIE设备的MEM读写访问事务和IO事务;PCIE设备也可以发起对PC存储器的MEM访问事务,下面暂未介绍。

2、IP CORE user interface接口说明

下面介绍的是采用AXI总线传输TLP包的一些接口信号和时序图。

信号说明:

**_tdata[63:0]:是传输的有效数据。

**_tready:表示,IPCORE 已经准备好接收发送**_tdata[63:0]上的数据。

**_tvalid:表示,**_tdata[63:0]上的数据是有效数据。

**_tlast:表示,一个TLP数据包的结束。该信号在**tvalid有效期间,该信号有效。

**_tkeep[7:0]:表示,发送数据字节使能,指示**_tdata[W-1:0]中数据的字节有效。该功能在**_tvalid和**_tready置位时有效。第0位对应**_tdata[W-1:0]的最低位,最高位对应**_tdata[W-1:0]中的最高位。例如,**_tkeep[0]==1b,则**_tdata[7:0]有效。**_tkeep[7]==0b,则**_tdata[63:56]无效。当**_tlast无效时,该值唯一的有效值是0xFF(6bit)或0xFFFF(128bit)。当**_tlast有效时,0xFF/0x0F(64bit)有效,或者0xFFFF/0x0FFF/0x00FF/0x000F(128bit)有效。

**_tuser[21:0]

Xilinx PCIE CORE学习_第2张图片Xilinx PCIE CORE学习_第3张图片

Xilinx PCIE CORE学习_第4张图片Xilinx PCIE CORE学习_第5张图片

Xilinx PCIE CORE学习_第6张图片

Xilinx PCIE CORE学习_第7张图片

 

3、TLP包理论基础

3.1 、3DW/4DW相关说明

3DW (DW:双字)和4DW,主要是用来区分存储器的地址位宽。

32位宽的存储器,采用3DW;64位宽的存储器,采用4DW。

比如,下图是3DW存储器读请求TLP包头,即在下图中存储器地址位宽是32位的。

Xilinx PCIE CORE学习_第8张图片

与上图对比,下图是 4DW存储器读请求TLP包头,即下图中存储器地址位宽是64位的。

Xilinx PCIE CORE学习_第9张图片

在PCIE IP CORE 配置过程中,如若不勾选64bit,在默认BAR地址位宽是32位的,即对应3DW包头;

若勾选64bit,则BAR地址位宽是64位的,即对应4DW包头;

BAR地址配置界面如下图所示:

Xilinx PCIE CORE学习_第10张图片

上面介绍了3DW、4DW头包与Base Address Registers基地址寄存器之间的关系。

下面区分一下用户接口的数据位宽,一般在GUI配置界面第一页会配置用户接口的数据位宽,一般可以选择64bit或者128bit。如下图所示。

Xilinx PCIE CORE学习_第11张图片

3.2 TLP事务类型和路由基础

Xilinx PCIE CORE学习_第12张图片

Xilinx PCIE CORE学习_第13张图片

 

3.3、TLP报文格式

 

Xilinx PCIE CORE学习_第14张图片

 

一个TLP包(事物层),是由头标、数据和摘要组成,如下图所示。

下图举例的是3DW的包头,即存储器地址位宽是32位。

 PCIe事务可以分为四大类:

a)        存储器事务

b)        IO事务

c)        配置事务

d)        消息事务

下图附上常见的几种TLP包类型:

Xilinx PCIE CORE学习_第15张图片

Xilinx PCIE CORE学习_第16张图片

       1、FMT[1:0]和TYPE[4:0],决定当前TLP报文的事务类型。

Xilinx PCIE CORE学习_第17张图片

 

1 Length字段

在存储器读请求TLP中并不包含Data Payload,在该报文中,Length字段表示需要从目标设备数据区域读取的数据长度;而在存储器写TLP中,Length字段表示当前报文的DataPayload长度。Length字段的最小单位为DW。当该字段为n时,表示需要获得的数据长度或者当前报文的数据长度为n个DW,其中0£n£0x3FF。值得注意的是,当n等于0时,表示数据长度为1024个DW。

2 DWBE字段

PCIe总线以字节为基本单位进行数据传递,但是Length字段以DW为最小单位。为此TLP使用Last DW BE和First DW BE这两个字段进行字节使能,使得在一个TLP中,有效数据以字节为单位。

这两个DW BE字段各由4位组成,其中Last DW BE字段的每一位对应数据Payload最后一个双字的字节使能位;而First DW BE字段的每一位对应数据Payload第一个双字的字节使能位。

Xilinx PCIE CORE学习_第18张图片

LastDW BE和First DW BE这两个字段的使用规则如下。

·         如果传送的数据长度在一个对界的双字(DW)之内,则Last DW BE字段为0b0000,而First DW BE的对应位置1;如果数据长度超过1DW,Last DW BE字段一定不能为0b0000。PCIe总线使用LastDW BE字段为0b0000表示所传送的数据在一个对界的DW之内。

·         如果传送的数据长度超过1DW,则First DW BE字段至少有一个位使能。不能出现First DW BE为0b0000的情况。

·         如果传送的数据长度大于等于3DW,则在First DW BE和Last DW BE字段中不能出现不连续的置1位。

·         如果传送的数据长度在1DW之内时,在First DW BE字段中允许有不连续的置1位。此时PCIe总线允许在TLP中传送1个DW的第1,3字节或者第0,2字节。

·         如果传送的数据长度为2DW之内时,则First DW BE字段和Last DW BE字段允许有不连续的置1位。

值得注意的是,PCIe总线支持一种特殊的读操作,即“Zero-Length”读请求。此时Length字段的长度为1DW,而First DW BE字段和LastDW BE字段都为0b0000,即所有字节都不使能。此时与这个存储器读请求TLP对应的读完成TLP中不包含有效数据。再次提醒读者注意“Zero-Length”读请求使用的Length字段为1,而不是为0,为0表示需要获得的数据长度为1024个DW。

“Zero-Length”读请求的引入是为了实现“读刷新”操作,该操作的主要目的是为了确保之前使用Posted方式所传送的数据,到达最终的目的地,与“Zero-Length”读对应的读完成报文中不含有负载,从而提高了PCIe链路的利用率。在PCIe总线中,使用Posted方式进行存储器写时,目标设备不需要向主设备发送回应报文,因此主设备并不知道这个存储器写是否已经达到目的地。而主设备可以使用“读刷新”操作,向目标设备进行读操作来保证存储器写最终到达目的地。

3 RequesterID字段

RequesterID字段包含“生成这个TLP报文”的PCIe设备的总线号(Bus Number)、设备号(Device Number)和功能号(Function Number),其格式如图5‑9所示。对于存储器写请求TLP,Requester ID字段并不是必须的,因为目标设备收到存储器写请求TLP后,不需要完成报文作为应答,因此Requester ID字段对于存储器写请求TLP并没有实际意义。
 

3.4、CplD报文格式

下图是3DW完成的头格式

Xilinx PCIE CORE学习_第19张图片

Xilinx PCIE CORE学习_第20张图片

 

3.5、TLP包解析示例

下图是一个简单的TLP 包,即包含两个64位的数据。clock0时刻,采样的,64位宽的数据1,clock1时刻,采样的是64位宽的数据2。需要注意,下面的TLP报文是:01a0090f40000001+0403020100000010,这个字节发送顺序,是采用AXI Bit的顺序。因此,举例,若需要解析TLP保温里的Request ID,则其对应的TLP报文是第一个64位宽的数据的高16位,即“01a0=0000_0001_1010_0000”.

这是一个,由于一次发送64位,因此这个报文的前64位是标头,后64位是数据和地址。 

按照上图的数据格式可知 
    Request ID:16’b0000_0001_1010_0000 
    Tag:8’b0000_1001 
    Last DW BE:4’b0000 
    First DW BE:4’b1111 
    Fmt:2’b10 
    Type:5’b0_0000 
    Length:10’b00_0000_0001 
    Data:32’h04030201 
    Address:32’h00000010(低两位无效)
 

特别说明:

上图中的Data:32’h04030201,这个仅是AXI的interface 接口顺序,实际PC写FPGA MEM的数据是32’h01020304.。

只有传输的数据data是颠倒的,其他的如 Request ID、 Length、 Address等,都是按照上图的字节顺序

所以 ,要是需要对数据进行解析的话,是需要将data的顺序颠倒一下。比如DMA操作,可能就需要对data进行高低位颠倒一下。

下图中是PIO的仿真波形,RX_CTRL是PIO的APP模块数据接口。

具体分析如下:

接收到的TLP包为 : 01a0090f40000001+0403020100000010

Xilinx PCIE CORE学习_第21张图片

下图是仿真报告,仿真报告里说写MEM的数据是32’h01020304,与上图显示的AXI用户接口传输的数据位是颠倒的

Xilinx PCIE CORE学习_第22张图片

下图是 PIO 的testcase,测试的写MEM数据是32’h01020304

Xilinx PCIE CORE学习_第23张图片

进入TSK_TX_MEMORY_WRITE_32这个写函数,可以看到TRN接口类型的数据拼接过程。

在TRN数据接口里,高32位存储的是address地址信号,低32位存储的是数据信息;

但是在低32位数据信息拼接过程中,其将要发送数据的data[0]位,放在TRN数据接口的trn_td[3],其他位也是依次对应。如下图所示。

然后PCIE IP CORE接收到给64'h的数据包后,

首先,将TRN数据接口里高32位数据放到AXI数据接口里的低32位;所以,AXI的用户数据接口64'h0403020100000010低32位是地址位。

其次,将TRN数据接口里低32位数据放到AXI数据接口里的高32位;所以,AXI的用户数据接口64'h0403020100000010高32位是数据位,并且,数据的顺序是颠倒的

这样,就可以理解,为何modelsim里看到的m_axis_rx_data[63:0]里,唯有数据位的顺序是颠倒的,而其他位不是颠倒的了。

Xilinx PCIE CORE学习_第24张图片

 

说明:上面仿真图、工程代码、testbench ,均是PCIE IP core 生成后的example的事例文件,即PIO。

读者可自行generate一个IP core看看里面的pio代码。这里不做过多分析了。

 

4、Example PIO 示例

本文仅以PCIE IP核自带的example作为示例,进行学习分析

 

4.1 Example  PIO 架构

电脑与PCIE之间通过差分总线进行数据交互,这部分不需要用户太多关心。PCIE IP会自动将接受到的TLP包组合成并行数据,并通过AXI总线、或者BMD总线,发送给用户逻辑。用户逻辑如何对接受到的TLP包进行解析,这部分是需要关心的。

Xilinx PCIE CORE学习_第25张图片

当PCIE IP CORE接收到一个TLP数据包时,其需要做的是, 首先,根据标头判断这个TLP是读存储器还是写存储器。

若是写存储器,就将下一个TLP中的地址和数据解析出来(因为这里一次发送64bit,所以第一个TLP中不包含地址和数据,第二个TLP中包含地址和数据),然后通过PIO_EP_MEM_ACCESS 模块将数据写入指定的地址中;

若是读存储器,就将下一个TLP中包含的地址解析出来,再通过PIO_EP_MEM_ACCESS 模块将数据从指定的地址中读取出来,然后经过发送引擎(PIO_TX_ENGINE )进行完成包拼接,最后通过事务层、数据链路层、物理层封装之后,通过差分发送接口(txn、txp)将数据发送出去。
 

下面两张图是Xilinx ISE 软件生成的example design PIO的架构连接情况。

Xilinx PCIE CORE学习_第26张图片

Xilinx PCIE CORE学习_第27张图片

4.2 接收/发送引擎代码分析

这部分,暂不进行更新。

请读者参考下面的参考文献[1]即可!

文献[1]里关于PCIE Verilog代码讲解的很到位,不过其提供的代码下载与其博客内容完全一致,积分少的童鞋可以不用下载那个代码了。

 

>>点击这里返回导航页<<

 

 

参考文献

 

作者 博客
1、CLGo  PCIe学习(一):PCIe基础及生成PIO例程分析
2、Spring PCI-E协议
3、 Xilinx FPGA 高速串行传输技术与应用
4、meper  基于FPGA的PCIe接口设计---01_PCIe基本概念
5、Jack-Xu  一步一步开始FPGA逻辑设计 - 高速接口之PCIe
6、huan09900990 Altera FPGA PCIE 例程仿真
7、fzhykx xlinx_pcie_ip 使用笔记
   

 

 

 

 

你可能感兴趣的:(FPGA基础进阶)