写在前面
笔者在工作中需要包个 PCIe wrapper,正在努力飞快学习 PCIe ing.
本文系转载,略做格式调整与增加解释(使用斜体表示),转自:
PCIe扫盲系列博文连载目录篇(第一阶段)-Felix-电子技术应用-AET-中国科技核心期刊-最丰富的电子设计资源平台
转载正文
PCIe总线体系结构入门
和很多的串行传输协议一样,一个完整的PCIe体系结构包括应用层、事务层(Transaction Layer)、数据链路层(Data Link Layer)和物理层(Physical Layer)。
其中,应用层并不是PCIe Spec所规定的内容,完全由用户根据自己的需求进行设计,另外三层都是PCIe Spec明确规范的,并要求设计者严格遵循的。
一个简化的PCIe总线体系结构如上图所示,其中Device Core and interface to Transaction Layer就是我们常说的应用层或者软件层。这一层决定了PCIe设备的类型和基础功能,可以由硬件(如FPGA)或者软硬件协同实现。
- 如果该设备为Endpoint,则其最多可拥有8项功能(Function),且每项功能都有一个对应的配置空间(Configuration Space)。
- 如果该设备为Switch,则应用层需要实现包路由(Packet Routing)等相关逻辑。
- 如果该设备为Root,则应用层需要实现虚拟的PCIe总线0(Virtual PCIe Bus 0),并代表整个PCIe总线系统与CPU通信。
事务层(Transaction Layer):接收端的事务层负责事务层包(Transaction Layer Packet,TLP)的解码与校检,发送端的事务层负责TLP的创建。此外,事务层还有QoS(Quality of Service)和流量控制(Flow Control)以及Transaction Ordering等功能。
数据链路层(Data Link Layer):数据链路层负责数据链路层包(Data Link Layer Packet,DLLP)的创建,解码和校检。同时,本层还实现了Ack/Nak的应答机制。
物理层(Physical Layer):物理层负责Ordered-Set Packet的创建与解码。同时负责发送与接收所有类型的包(TLPs、DLLPs和Ordered-Sets)。
当前在发送之前,还需要对包进行一些列的处理,如Byte Striping、Scramble(扰码)和Encoder(8b/10b for Gen1&Gen2, 128b/130b for Gen3& Gen4)。对应的,在接收端就需要进行相反的处理。
此外,物理层还实现了链路训练(Link Training)和链路初始化(Link Initialization)的功能,这一般是通过链路训练状态机(Link Training and Status State Machine,LTSSM)来完成的。
需要注意的是,在PCIe体系结构中,事务层,数据链路层和物理层存在于每一个端口(Port)中,也就是说Switch中必然存在一个以上的这样的结构(包括事务层,数据链路层和物理层的)。一个简化的模型如下图所示:
关于事务层,数据链路层和物理层的详细的功能图标如下图所示:
PCIe总线物理层入门
前面的文章简单的介绍了一些关于PCIe总线事务层(Transaction Layer)和数据链路层(Data Link Layer)的一些基本概念。(转载注:在转载中层次顺序调换了)
这篇文章来继续聊一聊PCIe总线的最底层——物理层(Physical Layer)。
在PCIe Spec中,物理层是被分为两个部分单独介绍的,分别是物理层逻辑子层和物理层电气子层,其中后者一般都是基于SerDes来实现的。
本篇文章只是简单地介绍一些PCIe物理层的基本概念,关于物理层详细、深入地介绍,请关注我后续的连载博文。
由于物理层处于PCIe体系结构中的最底层,所以无论是TLP还是DLLP都必须通过物理层完成收发操作。来自数据链路层的TLP和DLLP都会被临时放入物理层的Buffer中,并被加上起始字符(Start & End Characters),这些起始字符有的时候也被称为帧字符(Frame Characters)。具体如下图所示:
注:这里所说的TLP和DLLP指的是包的原始发送者发的包,即TLP表示这个包的原始发送者为事务层,而DLLP则为数据链路层。但是TLP仍然会被数据链路层转发,并添加Sequence和LCRC。
物理层完成的一个重要的功能就是8b/10b编码和解码(Gen1 & Gen2),Gen3及之后的PCIe则采用了128b/130b的编码和解码机制。
关于8b/10b,这里不再详细地介绍了,有兴趣的可以去参考一下我之前的文章:http://blog.chinaaet.com/justlxy/p/5100052814
物理层的另一个重要的功能时进行链路(Link)的初始化和训练(Initialization & Training),且是完全自动的操作,并不需要人为的干预。完成链路的初始化和训练之后,便可以确定当前PCIe设备的一些基本属性:
- 链路的宽度(Link Width,x1还是x2,x4……)
- 链路的速率(Link Data Rate)
- Lane Reversal - Lanes connected in reverse order 链路连接翻转
- Polarity Inversion – Lane polarity connected backward 链路高低电平翻转
- Bit Lock Per Lane – Recovering the transmitter clock 每条 Lane 的 bit 锁定
- Symbol Lock Per Lane – Finding a recognizable position in the bit-stream 每条 Lane 的 symbol 锁定
- Lane-to-Lane De-skew Within a Multi-Lane Link 多 lane 间去抖动
物理层的电气子层主要实现了差分收发对,如下图所示:
由于其速度很高,因此采用的是交流耦合的方式(AC-Coupled),说白了就是在信号线上加了电容Ctx,此时低频信号和直流信号都会被抑制。
注:图中的电容容值有误,应为75~265nF for Gen1 & Gen2, 176~265nF for Gen3 & newer.
需要注意的是,PCIe物理层处理可以转发TLP和DLLP之外,还可以直接发送命令集(Ordered Sets)。之所以称其为命令集,是因为它并不是真正意义上的包(Packet),因为物理层不会为其添加起始字符(Start & End Characters)。
并且命令集始于发送端的物理层,结束于接收端的物理层。虽然命令集没有起始字符,但是对于Gen1&Gen2版本的PCIe物理层来说,会为其添加一个叫做COM的字符作为开始字符,随后跟着三个或者更多的信息字符。
注:PCIe Gen3及之后的版本处理方式有所不同,但是Gen3是向前兼容Gen1 & Gen2的。由于本文主要还是基于Gen2来介绍的,所以关于Gen3的更多信息,大家可以自行参考PCIe Gen3 的Spec。
命令集(Ordered Sets)的收发示意图,如下图所示:
命令集(Ordered Sets)的结构图如下图所示:
命令集主要用于链路的训练操作(Link Training Process)。此外,命令集还用于链路进入或者退出低功耗模式的操作。
PCIe总线数据链路层入门
前面的文章介绍过,数据链路层(Data Link Layer)主要进行链路管理(Link Management)、TLP错误检测,Flow Control和Link功耗管理。
数据链路层不仅可以转发来自事务层的包(TLP),还可以直接向另一个相邻设备的数据链路层直接发送DLLP,比如应用于Flow Control和Ack/Nak的DLLP。如下图所示:
数据链路层还实现了一种自动的错误校正功能,即Ack/Nak机制。
如下图所示,发送方会对每一个TLP在Replay Buffer中做备份,直到其接收到来自接收方的Ack DLLP,确认该DLP已经成功的被接受,才会删除这个备份。
如果接收方发现TLP存在错误,则会向发送发发送Nak DLLP,然后发送方会从Replay Buffer中取出数据,重新发送该TLP。
注:关于Ack/Nak机制,后面的文章会详细的介绍。
两种DLLP(转发TLP的DLLP,用于Flow Control或Ack/Nak等的DLLP)的结构图分别如下图所示:
一个Non-Posted传输中,Ack/Nak的执行过程如下图所示:
版权声明
版权声明:本文为 AET 博主「Felix」的原创文章,转载请附上原文出处链接及本声明。
原文链接:http://blog.chinaaet.com/justlxy/p/5100053328
转载自:知乎
作者:Felix
推荐阅读
更多招聘及面经请关注FPGA的逻辑。