一、RapidIO串行物理层背景介绍
上篇博文提到RapidIO的物理层支持串行物理层与并行物理层两种,由于Xilinx 部分FPGA内部已经集成了串行高速收发器,所以用FPGA实现RapidIO大多都是基于串行物理层的。本文将主要讨论一下RapidIO串行物理层的包格式与控制符号。
RapidIO串行物理层,通常称为串行RapidIO,简称为SRIO(Serial-RapidIO)。 串行物理层定义器件间的全双工串行链路,在每个方向上使用单向差分信号。RapidIO串行物理层支持RapidIO器件间的包传送,包括包和控制符号的传送、流量控制、错误管理和其他器件到器件的功能。
RapidIO串行物理层有如下特征:
1、采用8B/10B编码方案将时钟嵌入到数据中。
2、在每个方向上支持一个串行差分对,称为1通道;或支持四个并列的串行差分对,称为4通道。
3、使用专用的8B/10B码(称为K码)来管理链路。管理内容包括流量控制、包定界和错误报告。
4、允许在RapidIO 1x/4x LP-Serial(串行RapidIO)端口和RapidIO物理层8/l6 LP-LVDS(并行RapidIO)端口之间进行包传输而无需包处理。(LP=Link Protocol)
5、使用与并行RapidlO物理层相似的重传和错误恢复协议。
6、支持每通道1.25G、2.5G和3.125G波特率(数据速率为1.0Gbps、2.0 Gbps和2.5 Gbps)的传送速率。
二、RapidIO串行物理层的包格式
2.1 串行物理层包格式与并行物理层包格式的区别
RapidIO并行物理层包格式和串行物理层包格式的逻辑层和传输层字段完全相同,唯一不同的是物理层字段有所区别。总体来说,并行RapidIO包和串行RapidIO包在物理层有以下两方面不同:
1、因为并行RapidlO包和控制符号在同样的数据线路中传送,并且并行接口不使用K码来为包和控制符号定界,所以并行包的第一位用来区分包和控制符号。而串行包不包括用来区别包和控制符号的S字段。
2、串行物理层提供5比特的ackID而并行物理层仅提供3比特的ackID。这意味着在两个串行链路端口之间最多可以包含32个未完成的事务,而对于并行接口两个端口之间最多只能有8个未完成的事务。串行链路接口覆盖范围更大,因为串行接口更可能运行在需要较长距离通信的情况,更可能在两个端口之问有较多的未确认的活动事务。
下图是RapidIO串行物理层包格式与并行物理层包格式的对比图
由上图可以看出,串行物理层的包格式与并行物理层的包格式仅仅只有前6-bit不同,而其余的字段完全相同。所以包格式最后的CRC校验码的计算范围不包括包的前6-bit。
2.2 RapidIO串行物理层包格式
RapidIO串行物理层的包格式如下图所示
其中逻辑层和传输层各个字段的含义与上篇文章并行物理层包格式字段含义完全相同。这里不再赘述,串行包格式物理层各个字段的含义如下表所示
字段 |
描述 |
ackID[0-4] |
ackID是返回给包发送者的包标识符。串行物理层为该字段定义了5位。这足以在两个器件间唯一的识别最多32个未完成的事务 |
rsvd[0-2] |
ackID字段后面的两个0就是rsvd字段。产生包时这两位必须置0,接收包时,这两位需要忽略 |
crf |
关键请求流(Critical Request Flow),与prio字段共同决定包的优先级 |
prio[0-1] |
设置包的优先级,2’b11的优先级最高,2’b00的优先级最低 |
crc[0-15] |
使用16位循环校验码检查包中的错误 |
串行RapidIO包的长度应该是32位的整数倍。因为内部数据的宽度一般是32位的整数倍,所以使串行RapidIO包的长度等于32位的整数倍可以简化发送和接收端口逻辑的设计。如果包的长度是16位的奇数倍(包括循环冗余校验码字段),值为0x0000的16位数据会填充到包尾。填充后的包长度是32位的整数倍。
2.3 RapidIO串行物理层包保护
串行物理层在每个包中加入16位循环冗余校验码以提供错误检测机制。该码覆盖了除ackID字段和rsvd字段首位外的整个包,循环冗余校验码计算时将未覆盖的部分视为0。下图显示了循环冗余校验码未覆盖的串行物理层包头的前6位(ackID和第一个保留位)。
由于包通过交换结构传输时不要求为每个链路重复计算循环冗余校验码,所以该结构允许ackID在每条链路上改变。由于在每条链路上为每一后续传送的包分配的ackID是连续的,所以很容易检测到ackID字段的错误。
有两种方式将循环冗余校验码附加在包尾。对除循环冗余校验码外长度等于或少于80字节的包来说,在逻辑层字段尾附加一个单独的循环冗余校验码。下图是长度小于80字节的被填充过的包的示例
对除循环冗余校验码外长度大于80字节的包来说,在前80字节后附加一个循环冗余校验码。在逻辑层字段尾的加另一个循环冗余校验码。第二个循环冗余校验码是第一个的延续。第一个循环冗余校验码包含在运行(running)计算中,这意味着在运行循环冗余校验码值插入到包的前80个字节后面之后不再重新初始化。这允许相关器件将嵌入的循环冗余校验码值视为2字节的数据载荷以进行循环校验码的校验。 如果附在逻辑层后面的循环冗余校验码不能使包尾部对齐32位边界的话, 2字节的全逻辑0填充就会加在包尾部。该逻辑0填充区有助于保证循环冗余校验码校验总在32位边界完成。接收处理部件使用前一个循环冗余校验码来检査较大包头的有效性并在接收到整个包前开始处理数据,这样可以更早地释放资源并减少完成事务的延迟。
下图是一个长度大于80字节的被填充过的包的示例。这个包包括两个循环冗余校验码和一个位于包尾的填充区。包的总长度为32位的整数倍。
使用ITU(国际电信联盟)多项式X16+X12+X5+1可以产生包16位的循环冗余校验码。在每个包的开始循环冗余校验码的值初始化为0xFFFF(全部逻辑1)。在循环冗余校验码计算时把未覆盖的6位视为逻辑0。具体的实现过程请参考RapidIO官方手册(参考文献1)第465页。
三、RapidIO串行物理层的控制符号
3.1 控制符号介绍
控制符号是被串行链路端口使用的消息单元,它用来管理串行链路操作的各个功能,包括链路维护,包界定,包应答,错误报告和错误恢复。
SRIO中定义了两种控制符号。第一种控制符号长度为3个字节,被称为短控制符号(Short Control Symbol),第二种控制符号长度为6个字节,被称为长控制符号(Long Control Symbol)。短控制符号是SRIO最先定义的一种控制符号,它适用于串行链路的线速率低于5.5Gbps,并且接收方并未对数据进行判决反馈均衡(Decision Feedback Equalization,DFE)的情况,它提供了串行链路协议需要的基本功能以及一些扩展功能。长控制符号是对短控制符号的扩展,它适用于串行链路的线速率高于5.5Gbps,并且接收方对数据进行判决反馈均衡(Decision Feedback Equalization,DFE)的情况。由于接收方对数据进行判决反馈均衡(Decision Feedback Equalization,DFE)容易产生数据的突发错误(Burst Error),所以长控制符号提供了一些额外的功能去加强突发错误的错误检测能力。同时,长控制符号还提供了一些短控制符号不具备的其他扩展功能。当然,长控制符号也支持串行链路的线速率低于5.5Gbps的情况,在这种情况下,长控制符号可以替代短控制符号提供更多的控制符号功能。
3.2 控制符号格式
控制符号包括长控制符号和短控制符号两种。长控制符号是对短控制符号功能的扩展。
所有的短控制符号长度都为24位(3个字节),格式如下图所示
短控制符号一共承载了两个功能,一个功能由stype0字段决定,另一个功能由stype1字段决定。其中,parameter0字段和parameter1字段被stype0字段所代表的功能所使用,而cmd字段是被stype1字段所代表的功能所使用。stype0字段所代表的功能主要包括端口传输控制符号过程中的状态信息,而stype1字段所代表的功能主要是传输RapidIO包的界定符和一些接收端口的请求。
所有的长控制符号长度都为48位(6个字节),它的格式如下图所示
长控制符号各个字段的含义与短控制符号各个字段的含义完全相同,唯一的不同之处在于短控制符号的parameter0字段和parameter1字段长度为5位,而长控制符号的parameter0字段和parameter1字段长度为6位。
控制符号中各个字段的详细定义如下表所示
字段 |
定义 |
stype0 |
为使用了parameter0和parameter1字段的控制符号编码 |
Parameter0 |
与stype0编码一起使用 |
Parameter1 |
与stype0编码一起使用 |
Stype1 |
为使用cmd字段的控制符号编码 |
Cmd |
与stype1字段一起用来定义链路维护命令 |
Crc-5 |
用来检测控制符号传输错误的5位循环冗余校验码 |
Crc-13 |
用来检测控制符号传输错误的13位循环冗余校验码 |
只有一种功能的控制符号以它所表示的功能的名字来命名。有两种功能控制符号以它所表示的某个功能的名字来命名。例如, stype0设置为接收包(packet-accepted)而stype1设量为NOP的控制符号称为接收包控制符号。其stype0设置为接收包而stype1设置为从重传处重启(restart-from-retry)的控制符号被称为接收包控制符号或从重传处重启控制符号,这取决于上下文。
可以传达两种功能的能力是控制符号特有的属性。这样包确认控制符号和包定界控制符号就能由同一控制符号表示。链路传送的控制符号流中大多数是包确认控制符号和包定界控制符号。有的时候在一个控制符号中携带确认(或状态)和包定界符能显著降低链路开销并增加传送包的链路带宽。
3.3 stype0控制符号
下表列出了stype0控制符号的编码和功能以及parameter0字段和parameter1字段所代表的含义
Stype0 |
功能 |
内容 |
|
Parameter0 |
Parameter1 |
||
3’b000 |
可接收的包 |
Packet_ackID |
Buf_status |
3’b001 |
包重传 |
Packet_ackID |
Buf_status |
3’b010 |
不可接收的包 |
任意值 |
Cause |
3’b011 |
保留 |
—— |
—— |
3’b100 |
状态 |
ackID_status |
Buf_status |
3’b101 |
虚拟通道状态 |
VCID |
Buf_status |
3’b110 |
链路响应 |
ackID_status |
Port_status |
3’b111 |
用户定义 |
用户定义 |
用户定义 |
上表中各个字段的含义如下表所示
参数 |
定义 |
Packet_ackID |
被应答控制符号的ackID |
ackID_status |
端口预期接收的下一个包的ackID的值。这个值比上一次收到的包的ackID值大1, |
Buf_status |
端口在指定的虚拟通道可接收的最大包的个数 对于短控制符号: 值为0~29:该编码值定义了端口在指定的虚拟通道件可以接收的新的最大包的个数。例如,值0表示端口在指定的虚拟通道没有包缓冲,因此不能接收新包 值为30:端口在指定的虚拟通道件可以接收的新的最大包的个数为30个 值为31: 端口在指定的虚拟通道件可以接收的新的最大包的个数未定义,包的个数取决于流控制的重传协议 对于长控制符号: 值为0~61:该编码值定义了端口在指定的虚拟通道件可以接收的新的最大包的个数。例如,值0表示端口在指定的虚拟通道没有包缓冲,因此不能接收新包 值为62:端口在指定的虚拟通道件可以接收的新的最大包的个数为30个 值为63: 端口在指定的虚拟通道件可以接收的新的最大包的个数未定义,包的个数取决于流控制的重传协议 |
Cause |
这个参数指的是包不被接收的原因。 5’b00001:接收包中的ackID值错误 5’b00010:接收控制符号的循环冗余校验码错误 5’b00011:非维护的接收包被阻止 5’b00100:接收包的循环冗余校验码错误 5’b00101:接收了无效的字符或者有效但不合法的字符 5’b00110:缺乏资源 5’b00111:解交织同步信号丢失 5’b11111:普通错误 |
Port_status |
端口状态: 5’b00010:端口遇到了不可恢复的错误 5’b00100:重传停止(Retry-stopped) 5’b00101:错误停止(Error-stopped) 5’b10000:正常(OK) 其他值均为保留值。 |
接收包(Paket-Accepted)控制符号:
接收包的控制符号表明接收器件已经把包发送到其最终目的地并且可以释放由发送器件分配的资源。该控制符号应该仅在已接收到整个包并且没有发现可检测的错误之后产生。接收包控制符号的格式如下图所示
重传包(Paket-Retry)控制符号:
重传包控制符号表明接收器件由于某些临时的资源冲突,如缓冲区不足而不能接收包,发送者应该重新发送包。重传包控制符号的格式如下图所示
未接收包(Packet-not-accepted)控制符号:
未接收包控制符号用来向包发送者表明接收端口没有接收到包的原因。控制符号包含一个指示无法接收包的原因的cause字段和一个packet_ackID字段。如果接收器件不能确定原因,或原因不属于定义的原因选项,就使用一般错误编码。Cause字段的定义在上表已经给出,未接收包控制符号的格式如下图所示
状态(Status)控制符号:
状态控制符号默认为stype0编码。它在控制符号不传达另一个stype0功能时使用。状态控制符号包含ackID_status和buf_status字段。buf_status字段向接收端口指示发送端口在产生控制符号时拥有的可用来接收包的可容纳最大长度包的缓冲区数量。ackID_status字段允许接收端口判定该端口和发送端口是否关于发送端口期望接收到的下一个ackID值同步。下图是状态控制符号的格式
链路响应(Link-Request)控制符号:
器件用链路响应控制符号响应链路请求(link-request)控制符号。在状态字段中报告的状态是在接收到相关链路请求/输入状态(link-request/input-status)控制符号时端口的状态。下图是链路响应控制符号的格式,port_status字段的功能在上表已经描述
3.4 stype1控制符号
下表列出了stype1控制符号的编码和功能以及cmd字段所代表的含义
Stype1 |
Stype1功能 |
cmd |
Cmd功能 |
包定界符 |
3’b000 |
包开始 |
3’b000 |
包开始 |
是 |
3’b001~3’b111 |
保留 |
否 |
||
3’b001 |
包取消 |
3’b000 |
包取消 |
是 |
3’b001~3’b111 |
保留 |
否 |
||
3’b010 |
包结束 |
3’b000 |
包结束 |
是 |
3’b001~3’b111 |
保留 |
否 |
||
3’b011 |
从重传处重启 |
3’b000 |
从重传处重启 |
* |
3’b001~3’b111 |
保留 |
否 |
||
3’b100 |
链路请求 |
3’b000~3’b010 |
保留 |
* |
3’b011 |
复位设备 |
|||
3’b100 |
输入状态 |
|||
3’b101~3’b111 |
保留 |
|||
3’b101 |
多播事件 |
3’b000 |
多播事件 |
否 |
3’b001~3’b111 |
保留 |
否 |
||
3’b110 |
保留 |
3’b000~3’b111 |
保留 |
否 |
3’b111 |
NOP(忽略)** |
3’b000 |
NOP(忽略)** |
否 |
3’b001~3’b111 |
保留 |
否 |
* 表示如果包在转发过程中,从重传处重启并且链路请求控制符号可能只是包定界符。
** 表示虽然NOP(忽略)没有作为控制符号定义,但是它是在控制符号不传达另一个stype1功能时的默认值。
包开始(Start-Of-Packet)控制符号:
包开始控制符号用来界定包的起始位置,它的格式如下图所示
包取消(Stomp)控制符号:
包取消控制符号用来取消一个正在发送的包,它的格式如下图所示
包结束(End-Of-Packet)控制符号:
包结束控制符号用来界定一个包的结束位置,它的格式如下图所示
从重传处重启(Restart-from-Retry)控制符号:
从重传处重启控制符号会取消一个当前的包。该控制符号可能在空闲链路上传送。用该控制符号标记重传包的开始可使接收者知道在其请求重传一个包后什么时候开始接收包。它的格式如下图所示
链路请求(Link-Request)控制符号:
器件使用链路请求控制符号发起一个命令到相连器件或请求相连器件的输入端口状态。链路请求控制符号取消当前包并可在包之间发送。在错误情况下,链路请求/输入状态控制符号的作用与链路请求/从错误处重启控制符号的作用相同。链路请求控制符号的格式如下图所示。
链路请求控制符号的第二个字段是一个3位的命令(cmd)字段。该字段包含发送到链路的命令。定义了两个命令:器件复位(reset-device)和输入状态(input-status),cmd字段详细的描述如下表所示
Cmd的值 |
命令名称 |
描述 |
3’b000~3’010 |
|
保留 |
3’b011 |
复位设备(reset-device) |
复位接收设备 |
3’b100 |
输入状态(input-status) |
返回输入端口状态;在错误情况下和链路请求(从错误处重启)控制符号的功能相同 |
3’b101~3’b111 |
|
保留 |
复位设备命令引起接收器件执行复位或上电过程; 所有状态机和寄存器都复位到上电初始状态。复位设备命令不会产生链路响应控制符号。由于各系统设计的可靠性并不确定, 在链路响应控制符号的复位功能上设置保护是必要的。设备接收到链路响应控制符号中的复位设备命令时并不执行复位功能,除非它收到四个连续的复位器件命令。这些连续的命令之间不应有除状态控制符号外的任何其他插入的包或控制符号。这样做能防止假复位命令在无意中复位器件。
输入状态命令请求正在接收的器件返回在其输入端口期望接收到的来自发送者的下一个ackID值,同时返回该输入端口当前的工作状态。该命令使接收端刷新其输出端口在输入状态命令之前接收到的由包产生的所有控制符号。刷新输出端口是与具体实现相关的,可能导致丢弃接收缓冲区的内容或在链路上发送控制符号,然后接收者产生链路响应控制符号作为响应。
多播事件(Multicast-Event)控制符号:
多播事件控制符号与其他的控制符号不同,不同之处在于它携带的信息与链路传输的控制符号无关。多播事件控制符号允许把用户定义事件的发生广播到整个系统。它的格式如下图所示
3.5 控制符号保护
控制符号的错误检测是通过循环冗余校验码(Cyclic Redundancy Check,CRC)来完成的。
对于短控制符号来说,RapidIO协议使用一个5位的CRC对错误进行检测。它能为8B/10B解码模块解出来的24位短控制符号检测最多5位的突发错误(Burst Error),5位的突发错误是最长的突发错误,8B/10B解码模块组的顶层如果出现单比特的传输错误就有可能导致5位的突发错误。
对于长控制符号来说,RapidIO协议使用一个13位的CRC对错误进行检测。它能为8B/10B解码模块解出来的48位长控制符号检测任意位数的突发错误(Burst Error),11位的突发错误最多可以破坏两个8B/10B码组。
CRC-5循环冗余校验码
使用ITU多项式X5+X4+X2+1为控制符号产生5位循环冗余校验码。循环冗余校验码的校验位占用了控制符号的最后5位。应该注意的是,5位循环冗余校验码必须由发送者产生并由接收者检验。在计算5位循环冗余校验码前应该将循环冗余校验码字段设置为全1 (5’b11111 )。为了使各种类型的循环冗余校验码实现更加灵活,在控制符号字段中加人了一个虚拟的第20位。对所有的计算来说,第20位是应用的最后1位,并且总是置为逻辑0。
CRC-13循环冗余校验码
使用ITU多项式X13+X10+X8+X5+X2+1为控制符号产生13位循环冗余校验码。循环冗余校验码的校验位占用了控制符号的最后13位。应该注意的是,13位循环冗余校验码必须由发送者产生并由接收者检验。在计算13位循环冗余校验码前应该将循环冗余校验码字段设置为全0 (13’b0000000000000 )。
关于CRC码的具体产生方法请阅读RapidIO官方手册(参考文献1)的第481页。
四、总结
RapidIO串行物理层的控制符号就是上文介绍的几种情况,关于并行物理层的控制符号不属于本文的讨论范围,感兴趣的请阅读RapidIO官方手册(参考文献1)的第209页。为了便于大家以后的查看,下面列出一张比较精简的控制符号的图方便大家快速的查看各个字段的意义。
上图列出的是短控制符号的定义。右下角关于K码的内容请看下一篇博客。上篇文章和这篇文章讲的都是Rapid协议相关的东西,可能比较抽象,仍然不知道在FPGA里面如何实现RapidIO协议。我建议大家初学RapidIO协议可以把这两篇文章和下一篇文章快速浏览一遍对相关的包和控制符号的概念有个印象即可,等你自己最后把所有的事务都在Vivado里面仿过一遍以后再回过头来看这些东西就觉得很合理了。
五、参考资料
1、RapidIO™ Interconnect Specification,下载链接 https://pan.baidu.com/s/1ek-3AAhetLAcxTuOE2IyMg
2、RapidIO嵌入式系统互连,电子工业出版社
3、Xilinx的pg007_srio_gen2,下载地址 https://china.xilinx.com/support/documentation/ip_documentation/srio_gen2/v4_0/pg007_srio_gen2.pdf