FPGA PCIE IP核(7 Series Integrated Block for PCI Express)学习日志

起始编辑日期 2024.05.29 星期三  晴天 轻松的生菜

一.前言

      其实对于PCIE的学习,我只是停留在知道如何简单地应用IP核,因此,我会从一个USER,也就是使用者的角度来写下面这些东西,而不是一个CREATOR创造者的角度,如果想当一个CREATOR,先从一个USER开始做起吧,哈哈哈。

二.关于PCIEIP

      在我看来,PCIE和UART、SPI本质上没有什么区别,只是PCIE这个协议会更加复杂,而且PCIE接口的传输速度明显快于低速接口的传输速度,一个接口如果传输速度很快,我们很自然地就会想到一件事情,也就是我们该用怎样的时钟去采集传输过来的的数据,Xilinx在设计PCIE IP核的时候其实已经把这个问题给你解决了,是利用了Xilinx芯片上的一个接口,好像叫GTX,具体的不是很清楚,总之,我们是不需要去考虑最底层的接收和解析的问题的,IP核会帮我们接收数据并且帮我们解析成TLP,这样一说是不是感觉IP核可真是大好人呢,对吧。IP核给到我们USER的数据统一称为TLP,TLP的组成是HEADER+DATAPAYLOAD,而且是通过AXI 的一组接口来给到我们的。

三.TLPHEADER+DATAPAYLOAD

     这里提到的TLP局限于这几种类型:MEMORY WRITE(写存储器)、MEMORY READ(读存储器)、COMPLETION WITH DATA(返回读取数据,针对于MEMORY READ)、COMPLETION WITHOUT DATA(返回命令)。前两者是由主设备下发给从设备的,后两个是由从设备返回给主设备的,当主设备发出MEMORY READ命令时,我们就需要返回

就像上面说的,虽然我们不需要进行最底层的接收和解析,但是接收并解析TLP,是需要我们USER去做的,举个很简单的例子,A发送一条命令给BA先将信息加密,然后传给BB的任务就是先解密这个信息,然后再执行解密以后的命令,其中USER with IP 就是BIP核负责接收并解析出TLP,我们USER负责接收和执行TLP,那么我们先来看看一个基本的TLP命令是怎么样的吧,看图一。(这里需要知道一个数据单位DWDW是一个数据单位,也就是DOUBLE WRODS-双字,1DW=32bits)。

图一.3DW Memory Write TLP

      这个图怎么看呢,首先每一行都是1DW的数据,一共有七行,也就是7DW,最后一行的TLP Digest是CRC校验码,暂时不用管,可以不选择,因为对于USER来说,这是一个可选项,那我就先不选。

接下来我们来看最右边的红色标识,H开头的表示是HEADER,D开头的表示是DATA PAYLOAD。前三行是TLP的HEARDER部分,紧接着的三行Data是DATA PAYLOAD,也就是数据部分。我们注意到这里的HEADER一共有3DW,实际上HEADER的长度也可以是4DW,一般来说4DW的HEADER就是在3DW的基础上把图中的Address从[31:2]拓展为[63:2]。HEADER的长度是由HEADER的类型决定,也就是H0最左边的那一个字节{R,Fmt,Type},这里,我举六种TLP类型。

{R,Fmt,Type}=8’b0_00_00000,这是3DW的Memory Read 命令;

{R,Fmt,Type}=8’b0_01_00000,这是4DW的Memory Read 命令;

{R,Fmt,Type}=8’b0_10_00000,这是3DW的Memory Write 命令;

{R,Fmt,Type}=8’b0_11_00000,这是4DW的Memory Write 命令;

{R,Fmt,Type}=8’b0_10_01010,这是3DW的Completion With Data 命令;

{R,Fmt,Type}=8’b0_00_01010,这是3DW的Completion Without Data 命令;

而且这六种类型也是我用到的所有类型,至于其他类型我这里就不提了,你们如果有需要的话可以去看相关的文档。我们来讲讲除了{R,Fmt,Type}以外HEADER的其他数据位,例如TC、TD、EP等等,基本都用不到,对于这些暂时用不到的信号,IP核传输过来以后,我们寄存一下就可以,后续如果需要PCIE主设备需要我们从设备反馈的话再用。接下来说说用到的几个重要的数据位:

Length[9:0]:对于WRITE命令来说,Length表示DATA PAYLOAD的长度(单位:DW),也就是图二中没有加深的Data部分,图二的Length为3;

Last DW BE1st DW BE:1st DW BE是DATA PAYLOAD的第一个DW数据的字节使能,Last DW BE是DATA PAYLOAD的最后一个DW数据的字节使能;

Address[31:2]:读写的基准地址。

基本用到的就是这几个部分,其实不管是3DW的HEADER还是4DW的HEADER,IP核都会用两个时钟周期发送完,IP核给我们发这些数据的时候是从上往下发的,也就是从Byte0->Byte27,而且是两行两行发的,因为AXI接口是64位的,图一中TLP发送的前两个时钟周期如图二Clock0、Clock1。所以说我们对于HEADER的解析,也需要用两个时钟周期来解析,第一个时钟周期先通过{R,Fmt,Type}确定TLP的类型和DATA_PAYLOAD的长度,第二个时钟周期获取读写命令的基准地址Address[31:2]。

只要是IP核发送过来的TLP有DATA PAYLOAD的,那就说明一定是WRITE命令。

图二

四.IP核相关信号解析

4.1 m_axis_rx

我们可以看图三7 Series Integrated Block for PCI Express IP核的配置页面,其中右边的m_axis_rx的六根信号线,就是IP核解析上层(Root Complex 或者其他PCIE主设备)加密后的数据得到的TLP数据, 这几组信号也是对于我们USER来说需要处理的所有信号,注意是所有信号

图三

4.1.1 m_axis_rx_tdata[63:0]

先来说说m_axis_rx_tdata[63:0](数据信号),这个位宽可以在AXI Interface Width那里设置,一般就是64bits/128bits,我之后说的一切代码以及仿真都是基于64bitsIP核输出的数据都是每一个时钟周期输出2DW64bits)。

4.1.2 m_axis_rx_tvalidm_axis_rx_tlastm_axis_rx_tkeep

但是什么时候这个数据有效呢?什么时候这个数据结束呢?数据有效时,数据的哪几个字节有效呢?要知道这三个问题的答案,就需要借助另外三个信号。首先,对于问题一,数据什么时候有效,当m_axis_rx_tvalid=1m_axis_rx_tdata有效;对于问题二,当m_axis_rx_tlast=1时,表示这是TLP的最后一笔数据;对于问题三,m_axis_rx_tkeep=8’bxxxx_xxxx,每一bit都对应于m_axis_rx_tdata8bits,也就是说keep信号是data的字节使能信号。

4.1.3 m_axis_rx_tuser[21:0]

还有一个输出信号是m_axis_rx_tuser[21:0],我详细来说一说,可以看下表。它的一些bit位都是只针对于128bitsAXI接口的,所以这也是我为什么选择64bitsAXI接口,相对来说简单一些。

[21:17]

5bits

128 AXI Interface OnlyEnd of a packet(eof)

[16:15]

2bits

保留位

[14:10]

5bits

128 AXI Interface OnlyStart of a packet(sof)

[9:2]

8bits

[7:2]对应于BAR5-BAR0[8]表示Expansion ROM

[1]

1bit

64 AXI Interface Only=rx_err_forward,提前表示这是一笔错误的数据(err_poisoned

[0]

1bit

=rx_ecrc_err,表示packetCRC校验出错

表一.m_axis_rx_tuser[21:0]详解

4.1.4 m_axis_rx_tready

      m_axis_rx的最后一个信号,同时也是一个输入信号,m_axis_rx_tready信号,是有我们USER来驱动的,ready信号也很好理解,当我们ready好了以后,IP核才会把前面提到的五个信号给到我们USER,所以,记得,在每次接收完一个TLP后一定要先把ready信号给拉低,不然的话,连续接收TLP,我们可能会处理不过来。

4.1.5 m_axis_rx时序图(非常重要!!!)

      为了方便理解m_axis_rx的信号时序,这里给出一个HEADER长度为3DWMEMORY WRITE,携带4DWDATAPAYLOAD,如图四。从图中可以看出IP核是如何将TLP按照顺序分解成一份份64bits的数据的,这个是需要我们知道的,因为我们得用这些数据呀,就得知道IP核发送的第一笔数据是啥,第二笔数据是啥,最后一笔数据是啥,每一笔数据我们都需要知道它对应在TLP中是什么位置。另外,需要注意的一点,当ready信号拉高时,IP核才会传输一笔有效数据,所以在图中的红圈部分可以看到第一笔数据是保持了两个周期。最后一笔数据就可以通过last信号知道。

     

图四  Memory Write TLP with 3DW Header and 4DW Data Payload

      这个时序是非常非常重要的,因为知道了TLP的时序,我们就能接收和解析TLP了,而且同样地,如果主设备下发一个READ TLP,我们需要返还一个Completion TLP,也是通过AXI 接口来给给到IP核,也就是图三中最左边的那组信号线s_axis_tx,s_axis_tx的六根信号线其中除了s_axis_tx_tready以外,其他的五个信号都需要我们USER来驱动,就如同IP核驱动m_axis_rx的五个信号线一样,所以这里我就先不说了。

五.IP核的使用

      那么怎么把上述说的这些落实到verilog文件上呢,怎么围绕IP核搭建我们的FPGA PCIE DEALER呢,最直接的方式就是在配置完IP核以后,右击Open IP Example Design,如图五,IP Example Design,顾名思义,就是Xilinx官方给的一个示例教我们如何使用这个IP核,而且这个示例是一个具体的工程,里面除了IP核以外所有的Verilog文件都是可读可写的。

图五

      Example打开如图六,这个Example可以帮我们节省很多很多时间,我们只需要根据我们的工程或者项目需求来编辑图中的PIO.v(包括里面的小模块),这个PIO.v就对应于我们USER,你想实现什么,就去改PIO.v就可以。

图六.PCIE IP Example Design

这里我就把我们USER需要写的verilog文件的输入输出端口给出来,知道输入输出以后,就知道大方向了,不至于摸黑前行了。有啥不懂的欢迎留言,因为我写这些东西很随性,想到啥写啥,会有很多错误和漏洞,有啥不对或者不理解的地方尽管指出来,希望和大家一起交流进步。

图七

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值