设备层简介
PCIe定义了分层的架构,如图2-12所示。可以将这些层在逻辑上拆分为两个独立运行的部分,因为它们各自具有用于发出信号流(traffic:the messages or signals transmitted through a communications system)的发送侧和用于接收信号流的接收侧。这种分层方法对硬件设计人员来说具有一些优势,因为如果细致的去划分逻辑,则可以通过更改现有设计中的一层,就轻松地迁移到新版本的协议标准,从而使其他设计不受影响。即便如此,请务必注意,各层仅定义了接口职责,并且实际设计中不需要为了符合规范去对各层设计进行分区。本节的目的是描述每一层的职责以及完成数据传输所涉及的事件流。
图2-12中所示的设备层包括:
•设备核心和与事务层的接口:核心实现了设备的主要功能。如果设备是端点(endpoint),则它最多可以包含8个功能(functions),每个功能实现自己的配置空间。如果设备是交换器(switch),则交换器核心由数据包路由逻辑和用于实现此目标的内部总线组成。如果设备是根(root),则根核心将实现虚拟PCI总线0,该总线上驻留所有芯片组的嵌入式端点和虚拟桥。
•事务层。该层负责在发送侧创建事务层分组(TLP),并在接收侧负责TLP解码。该层还负责服务功能,流控制功能和事务排序功能的质量。在本书的第二部分中介绍了所有这四个事务层功能。
•数据链路层:该层负责在发送侧创建数据链路层数据包(DLLP),并在接收侧进行解码。该层还负责链路错误检测和纠正。该数据链路层功能称为Ack/Nak协议。本书第三部分介绍了这两个数据链路层功能。
•物理层:该层负责在发送端创建有序集数据包(Ordered‐Set packet),并在接收端负责有序集数据包的解码。该层处理将在链路上处理传输的所有三种类型的数据包(TLP,DLLP,和有序集(Ordered‐Set packet)),并处理从链路接收的所有类型的数据包。数据包在发送端由字节分条逻辑(byte striping logic),加扰器(scramblers),8b/10b编码器(Gen1/Gen2协议)或128b/130b编码器(Gen3协议)和数据包序列化器(packet serializers)进行处理。最终,数据包以规范的链路速度在所有通道上以差分方式移出。在接收物理层,数据包处理包括串行接收差分编码的比特,并转换为数字格式,然后对输入的比特流进行反序列化处理(串并转换,所谓的序列化就是把信息状态转化为可以存储或传输的形式的过程,反序列化相反)。完成此操作的基准时钟速率是从CDR(时钟和数据恢复电路)电路恢复出的时钟。接收到的数据包由弹性缓冲区(elastic buffers),8b/10b解码器(与Gen1 /Gen2协议)或128b/130b解码器(Gen3协议),解扰器(de‐scramblers)和字节反分条逻辑(byte un‐striping logic)进行处理。最终,物理层的 LTSSM( Link Training and Status State Machine,链路训练与状态 状态机) 负责进行链路初始化以及训练。所有这些物理层功能将在本书的第四部分进行讲解。
图2-12 PCIExpress设备层
每个PCIe接口都支持这些层的功能,包括交换端口,如图2-13所示。因为交换端口通常只是实现转发数据包,在早期的课程中经常会问到交换端口(Switch Ports)是否需要实现所有层的问题。答案是肯定的,原因是评估数据包的内容以确定其路由需要查看数据包的内部细节,而这是在事务层逻辑中进行的。
图2-13 交换机端口层
原则上,每一层都与链路另一端设备中的相应层通信。上面的两层通过将一串bit嵌入到一个数据包中,从而创建一种格式(pattern),该格式可被接收器中的相应层识别。数据包在进入或离开链路的过程中通过其他层被转发。物理层还直接与另一台设备中的该层通信,但其功能有所不同。
在深入探讨之前,让我们首先浏览一下概述,以了解各层如何相互作用。广义上讲,来自设备的传出请求或完成数据包的内容是根据设备核心逻辑所提供的信息在事务层中组装的,有时我们也将其称为软件层(尽管规范未使用该术语)。该信息通常包括所需的命令类型,目标设备的地址,请求的属性等等。然后,新创建的数据包将存储在称为虚拟通道(Virtual Channel)的缓冲区中,直到准备好传递到下一层为止。当数据包向下传递到数据链路层时,会将附加信息添加到数据包以在相邻接收器处进行错误检查,并将副本存储在本地,因此如果发生传输错误,我们可以再次发送它。当数据包到达物理层时,它会被编码,然后会使用链路的所有可用通道进行差分传输。
图2-14 PCI Express设备各层的详细框图
接收器对物理层中的输入位进行解码,检查在此级别上可以看到的错误,如果没有,则将结果数据包转发到数据链路层。在此检查数据包是否存在不同的错误,如果没有错误,则将其转发到事务层。对数据包进行缓冲,检查是否有错误,然后将其分解成原始信息(命令,属性等),以便将内容传送到接收器的设备核心。接下来,让我们使用图2-14来更深入地探讨使该过程起作用的每一层必须做什么。我们从顶部开始。
设备核心/软件层
这是设备的核心功能,例如网络接口或硬盘驱动器控制器。在PCIe规范中未将其定义为层,但可以这样考虑,因为它位于事务层之上,并且将成为所有请求的源或目的地。它向事务层的发送方提供请求,这些请求包括诸如事务类型,地址,要传输的数据量等信息。当接收到传入的数据包时,它也是从事务层转发的信息的目的地。
事务层
响应软件层的请求,事务层生成出站数据包。它还检查入站数据包,并将其中包含的信息转发到软件层。事务层支持非投递式(non‐posted,也有译为“非转发”,non‐posted和posted都是事务层的两种事务类型)请求的拆分事务协议,并将入站完成包与先前传输出站该层处理的non‐posted请求包关联起来,事务使用TLP(事务层数据包),可以分为四个请求类别:
1.内存(Memory)
2. IO
3.配置(Configuration)
4.信息(Messages)
PCI和PCI-X已经支持其中的前三个,但是messages是PCIe的一种新型。事务定义为将命令传递到目标设备的请求(Request)数据包与目标发送回的所有完成数据包(Completion packets)的组合。表2-2给出了请求类型的列表。
Request Type | Non‐Posted or Posted |
Memory Read | Non‐Posted |
Memory Write | Posted |
Memory Read Lock | Non‐Posted |
表2-2 PCIExpress请求类型
Request Type | Non‐Posted or Posted |
IO Read | Non‐Posted |
IO Write | Non‐Posted |
Configuration Read (Type 0 and Type 1) | Non‐Posted |
Configuration Write (Type 0 and Type 1) | Non‐Posted |
Message | Posted |
表2-2 PCIExpress请求类型(续)
如表右列所示,请求(Request)也属于以下两类之一:非投递和投递(non‐posted and posted)。对于non‐posted的请求,请求者发送一个数据包,完成者应针对该数据包以完成数据包的形式生成响应。读者可以将其当成从PCI-X继承的拆分事务协议。例如,任何读取请求都不会是non‐posted,因为需要在完成时返回所请求的数据。也许出乎意料的是,IO写入和配置写入也是non‐posted。即使它们正在交付命令的数据,这些请求仍然希望从目标接收到完成信息,以确认写入数据实际上已经正确无误地到达了目的地。
相反,“Memory Writes and Messages”是posted,这意味着目标设备不会将完成的TLP返回给请求者。Posted事务提高了性能,因为请求者不必等待答复或承担完成工作的开销。折衷方案是他们无法获得有关写入已完成还是遇到错误的反馈。这种行为是从PCI继承的,仍然被认为是一件好事,因为发生故障的可能性很小,并且性能提升显着。请注意,即使不需要填写,但“Posted Writes”仍会参与数据链路层中的Ack/Nak协议,以确保可靠的数据包传递。有关更多信息,请参阅第10章,标题为“ Ack/Nak协议”。
TLP(事务层数据包)基础
表2-3给出了所有PCIe请求和完成数据包类型的列表。
TLP Packet Types | Abbreviated
Name |
Memory Read Request | MRd |
Memory Read Request ‐ Locked access | MRdLk |
Memory Write Request | MWr |
IO Read | IORd |
IO Write | IOWr |
Configuration Read (Type 0 and Type 1) | CfgRd0, CfgRd1 |
Configuration Write (Type 0 and Type 1) | CfgWr0, CfgWr1 |
Message Request without Data | Msg |
Message Request with Data | MsgD |
Completion without Data | Cpl |
Completion with Data | CplD |
Completion without Data ‐ associated with Locked Memory Read Requests | CplLk |
Completion with Data ‐ associated with Locked Memory Read Requests | CplDLk |
表2-3 PCI ExpressTLP类型
TLPs始于发送器的事务层,终止于接收器的事务层,如图2-15所示。数据链路层和物理层在数据包通过发送器层时将校验内容添加到数据包中,然后在接收器处验证这些内容是否已通过链路正确发送。
图2-15 TLP起点和终点
TLP组包(TLP Packet Assembly):
图2-16中显示了通过链路发送的已完成TLP的各个部分的示意图,可以看出,在每个层中都添加了数据包的不同部分。为了更容易识别数据包的构造方式,TLP的不同部分采用了颜色编码,以指示哪个层负责它们:红色代表事务层,蓝色代表数据链路层,绿色代表物理层。
设备核心发送在事务层中组装的TLP核心部分所需的信息。每个TLP都有一个标头,尽管有些标头(header),如读取请求,将不包含数据。计算一个可选的端到端CRC(ECRC/End‐to‐End CRC)字段并将其附加到数据包中。CRC是循环冗余校验的缩写(Cyclic Redundancy Check),并且几乎所有串行体系结构都采用CRC进行校验,原因很简单,因为它易于实现并且具有非常强大的错误检测功能。CRC还可以检测“突发错误”(burst errors)或重复的错误比特串,这一串的比特长度取决于CRC值的长度(PCIe为32位)。由于在发送长位字符串比特时可能会遇到这种类型的错误,因此CRC的校验特性对于串行传输非常有用。ECRC字段通过数据包的发送方和接收方之间的任何服务点(“服务点/service points”通常是指具有TLP路由选项的交换器或根端口)不变地传递,有助于在目的地验证途中是否有错误。
为了进行传输,TLP的核心部分被转发到数据链路层,后者负责附加一个序列号和另一个称为链路CRC(LCRC/Link CRC)的CRC字段。相邻接收器使用LCRC来检查错误,并针对该链路上发送的每个数据包,并将检查结果报告给发送器。细心的读者可能想知道,如果强制性LCRC检查已经验证了链路上的无错误传输,那么ECRC为什么还会有所帮助?原因是传输仍然存在没有进行错误检查的地方,并且该地方位于路由数据包的设备中。数据包到达并在一个端口上检查是否有错误,检查路由,然后在另一个端口上发送数据包时,将计算一个新的LCRC值并将其添加到该数据包中。端口之间的内部转发可能会遇到一个错误,而该错误并未作为常规PCIe协议的一部分进行检查,这就是ECRC有用的原因。
最后,将得到的数据包转发到物理层,然后在物理层将其他字符添加到数据包中,以使接收器知道预期的结果。对于前两代PCIe,这些是添加到数据包开头和结尾的控制字符。对于第三代,不再使用控制字符,而是将其它比特附加到给出有关数据包所需信息的块上。然后,使用所有可用通道对数据包进行编码并在链路上进行差分传输。
图2-16 TLP组件
TLP解包(TLP Packet Disassembly):
当相邻接收器看到传入的TLP比特流时,它需要识别并删除为恢复发射器核心逻辑请求的原始信息而添加的冗余部分。如图2-17所示,物理层将验证是否存在正确的开始和结束字符或其他字符并将其删除,从而将TLP的其余部分转发给数据链路层。该层首先检查LCRC和序列号(Sequence Number)错误。如果没有发现错误,它将从TLP中删除那些字段并将其转发到事务层。如果接收方是交换器,则在事务层对数据包进行评估,以在TLP的标头(header)中找到路由信息,并确定将数据包转发到哪个端口。即使它不是预期的目的地,如果交换器发现一个错误,它仍然可以检查并报告ECRC错误。但是,不允许修改ECRC,因此目标设备也可以检测到ECRC错误。
目标设备可以检查ECRC错误(如果已启用),如果目标设备没有错误,那么将删除ECRC字段,从而将数据包的标头和数据部分保留转发给软件层。
图2-17 TLP拆卸
没有回复内容