跳伞法速成PCIe【2】:PCIe通信全过程的解析 #PCIe接口 #PCIe入门 #FPGA #PCIeIP核 #PCIe协议 #PCIe XDMA #Vivado仿真 #配置空间 #AXI接口

        上一章我们说明了实际案例对速成一门技术的重要性。而对于开发者而言,在开发之前,能够先直观地观察一下成功案例的效果,无疑是事半功倍。

        我们上一章分析了例程设计,直观地了解了围绕PCIeIP核进行FPGA设计的框架与思路,而这一章我们将对该例程进行仿真,直接观察PCIe通信的双方如何构建起联系,对通信进行初始化,完成数据的传输,由此充分理解PCIe通信的过程,这对我们日后的设计开发尤为重要。

1. 对例程进行仿真

        打开上一章创建的PCIe示例工程,这个例程有完整的testbench。点击Run Simulation-->Run Behavioral Simulation,进入仿真界面。这次仿真大概要5分钟左右。

        接着我们把例程中顶层模块的所有接口拖到仿真界面里。这些接口包括输入/输出接口,与PCIeIP核的接口,这次仿真我们可以观察到整个模块的操作,以及PCIeIP核的输入输出信号的特性。

        重新开始仿真,将时间设定为187us。重新仿真要5分钟,150us仿真要10分钟左右,我们可以在这个时间继续往下阅读,了解仿真用例的结构,以及输出信号的激励波形。

        

2. 仿真用例的结构与激励输出

        2.1 仿真用例结构

        如图所示,为该测试用例的仿真结构。EP即为我们之前讨论的示例工程,这个工程的激励由RP模块提供,它就相当于实际通信中与该FPGA中的例程进行PCIe通信的主设备,它有可能是CPU,也可能是FPGA或者其他设备。

        值得一提的是,RX/TX是相对的。例如对于EP来说,Rp_pci_exp_txn/p是RX信号而非TX,因为这个接口是用来接收RP发来的信号的,但对于RP来说,这个信号就是TX了,因为它是用这个接口发送信号的。我们在开发中,需要统一规范,现在我们默认RX/TX是相对EP来讲的,也就是说RX是EP从RP接收来的信号,而TX是EP回发给RP的信号。

        2.2 时钟与复位激励

        时钟信号如图由时钟产生模块激励,默认均为100MHz信号

        系统对RP和EP统一做复位操作。阅读testbench代码,可知这个复位在一开始持续500个时钟,后面不再做复位操作,后面我们可以对其做修改观察复位操作。

        2.3 输入数据信号激励

        如图是RP端产生激励信号的过程,EP输入的数据由用户层产生,其数据经过AXI和PCIe核处理后由PCIe数据线发送到EP(示例工程上去);同样的原理,EP回发给RP数据也会由PCIeIP核解析,在经过AXI发回给RP的用户层。其实,我们的EP端,也就是该示例工程的设计,也和RP接发数据的框架一样,通过对仿真文件中RP接发数据的设计,我们也可以照猫画虎地设计EP端。

        值得一提的是,AXI数据传输的时钟频率为125MHz,而PCIe数据线的传输速度为2.5GT/5GT/s,也就是说PCIe数据线传输速率远远大于FPGA能够提供的时钟频率,因此我们也只能利用IP核来实现PCIe的数据传输,这就是高速率通信的特点。

        2.4 PCIe通信过程与AXI数据格式

        如图所示,为150us仿真过程中,上图pcie_axi_trn_bridge模块输出的AXI格式数据帧。我们先关注前两列-阶段和数据类型,总结RP发送PCIe数据的过程。

        1. 在前26个数据包中,用户层一直在发送读/写配置信号。由此可见PCIe通信在发送数据之前,需要发送多个配置信息来初始化PCIe通信。初始化可以分为三个阶段:系统配置检查,BAR扫描,BAR编程,具体发送数据如图。

        2.初始化PCIe后,RP用户层就可以向EP端发数据了。在这个测试用例中,RP向EP只发送了一组数据。数据格式可见表格右侧。

        3.RP端不仅可以向EP发送数据包RXC,也可以发送数据请求RXR,请求EP端回发一个数据。在这个测试用例中,也只请求了一个数据,而这个数据恰恰是RP刚刚向EP端发送的那组数据。

        需要注意的是,这个信号格式是AXI数据格式而非PCIe数据格式。PCIe数据线只有一位宽,是PCIe核将AXI数据做处理后的高速串行数据,而这个PCIe数据到达EP端后,也有PCIe核解析成AXI数据。我们作为开发者只需要对AXI数据做发送,接收,处理就行了。(PCIe数据我们也处理不了)

3. 仿真波形与PCIe通信全过程

        如图,我们完成了对此示例PCIe通信全过程的仿真。接下来对于这个仿真我们有三个方面去学习: 1.EP端和RP端PCIe通信过程 2.PCIeIP核处理数据的结果 3.用户层处理AXI数据的方法。

        这一章我们着重关注EP端和RP端PCIe通信过程,了解整个系统如何互相发送数据。

          3.1 EP端工程总接口的波形

        我们对该工程的顶层接口仿真做一些说明。

        系统时钟和复位:正如之前对激励工程代码的解读,sys_clk_n和sys_clk_p为100MHz差分时钟,sys_rst_n在500个时钟周期,即5us后拉高,不再复位。

        rx/tx——PCIe物理层信号:这里的RX/TX是对于EP端而言的,也就是说rx是接收数据,tx是回发给RP端的数据。我们从几个角度分析一下这个物理层高速串行信号

        3.1.1. 如下图可以看到,即使在user_lnk_up拉高之前,即通信建立起来之前,rx/tx信号也在不断变化。这就是PCIe通信的特点,物理层为了高速通信的稳定性,它即使在不通信的时候也会乱发些数据(Chatgpt的说法,正确性有待考察,但是现象确实是这样)。因此rx/tx信号中既包含通信双方的有效数据,也有以维持高速通信的杂乱数据,PCIe核自会识别这些数据,因此我们可以不用细究。

        3.1.2 该数据发送速率极快,如图其一个数据周期为400ps,即发送频率为2.5GT/s。这个速率是PCIe通信的重要参数,即单通道,单比特,单向传输速率,在PCIeIP核配置时,你也可以将通信速率设置为5GT/s。

        

        3.2 PCIe通信链路的建立

        如图所示,user_lnk_up是PCIeIP核输出的标志着PCIe通信链路的建立的信号。可以看见在时钟接入之后,PCIe核花费了一定时间才建立起通信双方的链路。PCIeIP核在接入时钟后,产生了125MHz用户时钟user_clk,其复位user_reset维持了57us后拉低,最后才建立好连接。

        可以观察到,在复位结束时,m_axis_tkeep发生了变化,这说明此时IP核已经做好了接收数据的准备;在user_lnk_up拉高时,s_axis_tkeep发生了变化,这说明IP核已经做好了发送数据的准备,由此链路建立成功

4. PCIe通信全过程

        我们将目光聚焦于m_axis_tdata的数据,它体现了PCIe数据传输的几个阶段,

        从m_axis_tdata的波形看,我们可以把PCIe通信分为4个阶段,如图标记出了阶段的划分,接下来我们对各个阶段做详细介绍

        可以看到,PCIe前三个阶段都是对PCIe核的配置空间做操作。PCIe配置空间的分布图我们后续会详加介绍,目前你可以阅读Xilinx官方提供的pg054文档,个人主页有提供。

        4.1 检查配置阶段与m_axis_rx_tkeep的说明

        如图所示,为检查配置阶段,RP向EP发送的帧格式与数据。每一个数据的第一行是比特位,第二行是帧格式,第三行是EP端实际接收的数据。需要说明的是,由于这个例程AXI数据位宽为64,所以一帧128位数据由2组AXI数据传输。

       仔细检查,会发现前32位的实际数据与帧格式不一致,但是这一个Dword在实际传输中无效,所以不必细究。至于为什么无效,我们可以观察仿真波形。m_axis_tkeep代表着tdata各字节的有效性,例如0f(00001111)就代表m_axis_tdata前四个字节无效,后四个字节有效;我们可以发现,在发出这两组数据时,第一组tkeep为ff,即数据均有效,而第二组为0f,即只有后四个字节有效。

        所以在这个阶段,RP实际向EP发送的一帧有效数据为96位而非128位。

        4.2 扫描PCIe核的配置

        如图所示,为该阶段的帧格式与数据。观察数据类型,这个阶段在交替读写PCIe核的配置空间。其帧说明如下:

[75:66]:它代表要读/写的配置寄存器地址,观察各帧中标绿的数据,此例程分别读/写了10,14,18,1C,20,24,30地址的数;配置空间示意图如下,你可以对照了解各个地址的含义。

[47:40]:它跟当前操作贴了个标签,每进行一次操作,该标签加1,我们可以在数据中标红的地方得知。

写操作中的[127:96]:要往配置寄存器当中写的数据,写的地址由[75:66]决定。值得注意的是,这32位并非直接对应配置寄存器中的[31:0]位,而是分别对应[7:0],[15:8],[23:16],[31:24],这一点在配置寄存器的时候需要注意一下,发送的时候做额外处理。

        4.3 修改PCIe核配置寄存器

        如图所示,为此阶段的帧格式与数据。可以看到,这个阶段均为写操作,写数据/写地址/标签的含义如上已言。观察数据,可以看到这个例程里写的数非常简单,其含义参考此前对配置空间的描述,配置空间示意图上也已给出。  

        4.4 PCIe读写数据

        配置完PCIeIP核之后,就可以开始传输数据了。此例程的数据帧格式和数据如下图:

        可以看到该例程分别读写了一组数据,其具体数据由DATA_STORE存储,为0X01020304,我们也可以在仿真代码中自行修改要发送的数据。这组数据的地址ADDR[31:0],长度LEN[9:0]信息也在帧格式中一并给出。

        对于读操作,前32为无效位,可以看到tkeep为0f,说明了这一点。Dword2提供了要读取的数据的地址,可以发现写和读的地址值一样,也就是说该例程存了一个数,又立马取了出来,相当于一个回环验证。长度LEN等信息也已给出。

        4.5后续操作

        虽然这个仿真用例只读写了一个数,但也足够说清楚问题了。在配置完寄存器后,我们就可以让RP端向EP端存储数据或者传输数据,也可以向EP发送数据请求,读取相应地址的数据

5.总结与预告

        这一章我们利用例程的仿真用例,直观地了解了PCIe通信的详细过程。我们不仅了解了EP和RC端利用PCIe核传输数据的原理与方法,还直接观察了它们通信的内容,了解到PCIe初始化和开始工作的过程,详细的了解了发送数据的格式,明白配置PCIe和发送PCIe数据的格式和具体含义。

        下一章我们将继续利用仿真用例,直观的观察PCIe核的行为:看它对输入的AXI数据和PCIe的RX/TX数据做了什么处理,PCIe核各端口的含义及变化规律,例程利用PCIe核的方法等。通过对例程的利用,我们可以很容易的理解PCIeIP核和围绕PCIe核设计的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值