PCIE笔记摘录

> 以下内容非原创,主要是摘录 老男孩读pcie和网上的其他文章,仅限学习,不用于任何商业用途。
  1. PCIE接口电气的耦合方式
    高速差分信号电气规范要求其发送端串接一个电容,以进行AC耦合
    =================
  2. PCIE总线的缺点
    Pcie的内部实际上还是以64bit/128bit的并行数据传输的,时钟为125M/250M。只不过在物理层转成了高速串口
    但是PCIe总线也有其弱点,其中最突出的问题是传送延时。PCIe链路使用串行方式进行数据传送,然而在芯片内部,数据总线仍然是并行的因此PCIe链路接口需要进行串并转换,这种串并转换将产生较大的延时。除此之外PCIe总线的数据报文需要经过事务层、数据链路层和物理层,这些数据报文在穿越这些层次时,也将带来延时
    =================
  3. PCIE拓扑结构
  4. 精粤bios pcie 延迟计时器_人工智能

  5. 整个PCIe拓扑结构是一个树形结构,Root Complex(RC)是树的根。RC为CPU代言,与整个计算机系统其它部分通讯,比如CPU通过它访问内存,通过它访问PCIe系统中的设备。
    PCIe Endpoint:就是PCIe终端设备,比如PCIe SSD,PCIe网卡等等。Legacy Endpoint:接口是PCIe,但是内部的行为却和传统的PCI或者PCI-x一样(比如支持IO空间)。
    Switch:扩展口。
    =================
  6. 分层设计
    PCIe定义了下三层:事务层(Transaction Layer),数据链路层(Data Link Layer)和物理层(Physical Layer),每层职能是不同的,且下层是为上层服务的。分层设计的一个好处:如果层次分得够好,接口版本升级时,硬件设计可能只需要改动某一层,其它层次可以保持不动。
    =================
  7. Switch中也有封包和解包的过程
    脱衣服是为了找到最里边的地址,找到地址了才知道要下发给下面那个endpoint,然后再把衣服穿起来穿给对应的endpoint.
    如下图,如果RC要与EP1通信,中间要经历怎样的一个过程?
  8. 精粤bios pcie 延迟计时器_数据_02

  9. 如果把前述的数据发送和接收过程,我们通俗的叫做穿衣脱衣,那么,RC与EP1数据传输过程中,则存在好几次这样穿衣脱衣过程:RC跟数据穿好衣服,发送给Switch的上游端口,A为了知道该笔数据发送给谁,就需要脱掉该数据的衣服,找到里面的地址信息。衣服脱光后,Switch发现它是往EP1的,又帮它换了身新衣服,发送给端口B。B又不嫌麻烦的脱掉它的衣服,换上新衣服,最后发送给EP1。
    =================
  10. TLP类型
    根据软件层的不同请求,事务层产生四种不同的TLP请求
    1) Memory
    2) IO
    3)Configuration
    4)Message

我们知道,一个设备的物理空间,可以通过内存映射(Memory map)的方式映射到Host的主存,有些空间还可以映射到Host的IO空间(如果Host存在IO空间的话)
所有的配置空间(Configuration)的访问,都是Host发起的,确切的说是RC发起的,往往只在上电枚举和配置阶段会发起Configuration的访问,这样的TLP很重要,但不是常态; Message也是一样,只有有中断,或者有错误等情况下,才会有Message TLP,属非主流。PCIe线上主流传输的是Memory访问相关的TLP,Host与device,或者device与device之间,数据都是在彼此的Memory之间(抛掉IO)交互,因此,这种TLP是我们最常见的。

如果需要对方响应的,我们叫做Non-Posted的TLP;如果不期望对方给响应的,我们称之为Posted TLP。

只要记住只有Memory Write和Message两种TLP是Posted就可以了。

=================
7. Host和endpoint的数据是如何交互的呢?

  1. Endpoint读host内存 MRD + N个CPLD
  2. 精粤bios pcie 延迟计时器_数据_03

  3. 例子中,Switch B下面的某个Endpoint想读Host内存的数据,因此,它在事务层上生成一个Memory Read TLP,该MRd一路向上,翻过B,越过A,最终到达RC。RC收到该Request,就到内存中取该Endpoint所需的数据,RC通过Completion with Data TLP(CplD)返回数据,原路返回,直到Endpoint。
    一个TLP,最多只能携带4KB有效数据,因此,上例子,如果Endpoint需要读16KB的数据,RC必须返回4个CplD给Endpoint。注意,Endpoint只需发1个MRd就可以了
    理论上可以这样,但是要注意发包的时候,既不能跨RCB,又不能超过MPS。所以一个包的长度最大为MPS个。
  4. 精粤bios pcie 延迟计时器_fpga开发_04

  5. Host想往某个Endpoint写入数据 N个MWr
  6. 精粤bios pcie 延迟计时器_fpga开发_05

  7. 该例子中,Host想往某个Endpoint写入数据,因此RC在其事务层生成一个Memory Write TLP(要写的数据在该TLP中),翻过A,越过B,直到目的地。前面说过Memory Write TLP是Posted的,因此,Endpoint收到数据后,是不需要返回Completion TLP(如果这个时候返回Completion TLP,反而是画蛇添足)。
    同样的,由于一个TLP只能携带 4KB数据,因此Host想往Endpoint上写入16KB数据,RC必须发送4个MWr TLP
    同样要注意发包的时候,既不能跨RCB,又不能超过MPS
    =================
  8. TLP结构
    对一个PCIe设备来说,它开放给Host访问的设备空间首先会映射到Host的内存空间,Host如果想访问设备的某个空间,TLP Header当中的地址应该设置为该访问空间在Host内存的映射地址。如果Host内存空间小于4GB,则Memory读写TLP的Header大小为3DW,大于4GB,则为4DW。那是因为,对4GB内存空间,32bit的地址用1DW就可以表示,该地址位于Byte8-11;而4GB以上的内存空间,需要2DW表示地址,该地址位于Byte8-15。
    TLP主要由三部分组成:Header,Data和CRC

    一共下面四种TLP包。
    1) Memory TLP(读/写)
    2) Configuration TLP
    3) Message TLP
    4) Completion TLP

精粤bios pcie 延迟计时器_人工智能_06


从表中可以看到,写的包都是有数据的,读的包都是没有数据的。且只有mem TLP需要我们控制。

读的包一般都是Non-Posted的包。

有的场合写完数据,上位机会发个cpl nowith data,表示上位机已经收到数据了。

读包发完后,上位机会发cpld包(有数据)

精粤bios pcie 延迟计时器_人工智能_07

=================

9. TLP包的传输方式(AXI-Stream):

精粤bios pcie 延迟计时器_精粤bios pcie 延迟计时器_08


精粤bios pcie 延迟计时器_fpga开发_09


头+数据

精粤bios pcie 延迟计时器_图像处理_10


》》》还可以两帧数据连在一起。

精粤bios pcie 延迟计时器_图像处理_11


头+数据

精粤bios pcie 延迟计时器_fpga开发_12


精粤bios pcie 延迟计时器_fpga开发_13


中断

精粤bios pcie 延迟计时器_精粤bios pcie 延迟计时器_14


比方说你下面数据快存满了,你必须给上位机传个中断,告诉它我这儿有数据了,你赶紧处理一下。

中断的优点:响应比较及时。

也可以不通过中断,比如你写个mwr的包写进某个空间,上位机去循环去检测这个数一旦发生变化了,这个数大家定好什么含义,然后上位机就去做相应的处理。
缺点:让cpu分心了。

==============================

10. 配置和地址空间

其它的我们暂时不看,我们看看重要的BAR(Base Address Register)

精粤bios pcie 延迟计时器_图像处理_15


对Endpoint Configuration(Type 0),提供了最多6个BAR

而对Switch(Type 1)来说,只有2个。

BAR是干什么用的?

每个PCIe设备,都有自己的内部空间,这部分空间如果开放给Host(软件或者CPU)访问,那么Host怎样才能往这部分空间写入数据,或者读数据呢

我们知道,CPU只能直接访问Host内存(Memory)空间(或者IO空间,我们不考虑),不对PCIe等外设直接操作,而是DMA(直接操作内存)。怎么办?记得皇帝身边那个有根的太监吗?Root Complex,RC。RC可以为CPU分忧。

解决办法是:CPU如果想访问某个设备的空间,由于它不能(或者不屑)亲自跟那些PCIe外设打交道,因此叫太监RC去办。比如,如果CPU想读PCIe外设的数据,先叫RC通过TLP把数据从PCIe外设读到Host内存,然后CPU从Host内存读数据;如果CPU要往外设写数据,则先把数据在内存中准备好,然后叫RC通过TLP写入到PCIe设备。完美!

精粤bios pcie 延迟计时器_精粤bios pcie 延迟计时器_16


上图例子中,最左边虚线的表示CPU要读Endpoint A的数据,RC则通过TLP(经历Switch)数据交互获得数据,并把它写入到系统内存中,然后CPU从内存中读取数据(紫色箭头所示),从而CPU间接完成对PCIe设备数据的读取

具体实现就是上电的时候,系统把PCIe设备开放的空间(系统软件可见)映射到内存空间CPU要访问该PCIe设备空间,只需访问对应的内存空间RC检查该内存地址,如果发现该内存空间地址是某个PCIe设备空间的映射,就会触发其产生TLP,去访问对应的PCIe设备,读取或者写入PCIe设备。

一个PCIe设备,可能有若干个内部空间(属性可能不一样,比如有些可预读,有些不可预读)需要映射到内存空间,设备出厂时,这些空间的大小和属性都写在Configuration BAR寄存器里面,然后上电后,系统软件读取这些BAR,分别为其分配对应的系统内存空间,并把相应的内存基地址写回到BAR。(BAR的地址其实是PCI总线域的地址,CPU访问的是存储器域的地址,CPU访问PCIe设备时,需要把总线域地址转换成存储器域的地址。)