RapidIO:是为满足未来高性能嵌入式系统需求而设计的一种开放式互连技术标准。
SRIO:Serial RapidIO,即串行RapidIO;另外还有并行RapidIO。
GT:高速串行通信接口,因为FPGA在硬件上已经集成了GT高速串行通信接口,所以SRIO都以GT为物理层来实现SRIO通信协议。
1.Rapid IO协议
1.1 背景介绍
RapidIO是由Motorola和Mercury等公司率先倡导的一种高性能、低引脚数、基于数据包交换的互联体系结构,是为满足和未来高性能嵌入式系统需求而设计的一种开放式互联技术标准。Rapid IO主要应用于嵌入式系统内部互连,支持芯片到芯片、板与板之间的通讯,可作为嵌入式设备的背板连接。可以得知Rapid IO是一种总线技术,常见的总线技术包括:
传统串行总线:UART、SPI、IIC总线等;接口简单,硬件设计简单;协议较简单;传输速度慢。
传统并行总线:EMIF、UPP、PCI总线等;比传统串行总线速度快;接口引脚多,硬件设计困难;传输距离短。
由此诞生了高速串行总线:USB、PCIE、SRIO总线等;
速度快,链路速度一般可以在2.5Gbps,3.2Gbps,5Gbps,6.25Gbps;
低压差分信号(Low Voltage Differential Signal ,LVDS),接口简单,硬件设计简单,但传输协议复杂。
有三种带宽能达到10Gbps的互连技术:以太网,PCIE,SRIO(串行RapidIO)。
软件实现 TCP/IP协议栈的以太网 | 4*PCI Express | 4*SRIO | 备注 | |
软件开始 | 高 | 中 | 低 | SRIO协议栈简单,一般都由硬件实现,软件开销很小 |
硬件纠错重传 | 不支持 | 支持 | 支持 | |
传输模式 | 消息 | DMA | DMA,消息 | |
拓扑结构 | 任意 | PCI树 | 任意 | SRIO支持直接点对点或通过交换器件实现的各种拓扑结构 |
直接点对点对等互连 | 支持 | 不支持 | 支持 | SRIO互连对方可对等的发起传输 |
传输距离 | 长 | 中 | 中 | SRIO针对嵌入式设备内部互连。传输距离一般小于1米 |
数据包最大有效载荷长度 | 1500字节 | 4096字节 | 256字节 | 嵌入式通信系统对实时性要求高,SRIO小包传输可减少传输时延 |
打包效率(以传输256字节数据为例) | 79%(TCP包) | 82% | 92%-94% | 打包效率是有效载荷长度与总包长的比率,SRIO支持多种高效包格式 |
Rapid IO 2.0已经支持40Gbps带宽。
Rapid IO最初规范使用并行总线,8位或16位,但并行总线需要较多信号引脚,比如8位位宽的接口需要40根信号线,16位位宽的接口需要76根,不适用于系统背板间的互联。现在基本上都有串行总线RapidIO,即SRIO。并行和串行只是物理接口的不同,它们具有相同的编程模型,事务处理,寻址机制。
作为高速串行总线,RapidIO的特点有:系统结构灵活,允许点对点传输;带错误检测的鲁棒传输(CRC?);可扩展的频率和接口宽度;非软件密集型操作;低开销的高带宽互联;低引脚数、低功耗、低延迟。
Rapid IO采用三层分级体系结构
其中逻辑层位于最高层.定又全部协议和包的格式,他们为端点器件发起和完成事务提供必要的信息;传输规范位于中间层,定义了RapidIO地址空间和在端点器件间传输包所需要的路由信息,物理层规范在整个分级结构的底部,包括器件级接口的细节,如包传输机制、流量控制、电气特性和低级错误管理等功能。
Rapid IO分为并行Rapid IO标准和串行Rapid IO标准,串行Rapid IO是物理层采用串行差分模拟信号传输的Rapid IO标准。在Xilinx的一部分FPGA里面已经集成了GTP,GTX或GTZ等高速串行收发电路,这些是FPGA实现Rapid IO高速传输的物理层基础。
1.2 Rapid IO协议概述
1.2.1包与控制符号
Rapid IO操作是基于请求和响应事务的。
包是系统中端点器件间的基本通信单元。发起器件或主控器件产生一个请求事务,该事务被发送至目标器件。目标器件于是产生一个响应事务返回至发起器件来完成该次操作。Rapid IO事务被封装在包中,而包则包含确保将事务可靠传送至目标端点的所有必需的位字段。通常不会将Rapid IO端点相互直接连接到一起,而是通过介于其间的交换结构连接。名词“交换结构”指的是提供系统互连的单个或多个交换器件的结合。
控制符号用于管理Rapid IO物理层互连的事务流,也用于包确定、流量控制信息和维护功能。下图展示了如何在Rapid IO系统中传输事务。
上图中,系统的发起器件(Initiator)通过产生一个请求事务(Request)开始一次操作。该请求包传送至交换结构器件(Fabric),通常是一个交换机,交换结构器件发出控制符号确认收到了该请求包,然后交换结构将该包转发至目标器件(Response)。通过交换结构(Fabric)将承载该事务的响应包传送回发起器件(Initiator)。传送时使用控制符号对每一跳(hop)进行确认。一旦响应包到达发起器件(Initiator)并得到确认,就可认为此次操作已经完成。
1.2.2包格式
Rapid IO包有代表3级规范体系结构的多个字段组成。包由包头、可选的载荷数据和16bitsCRC校验码组成。包头的长度因为包类型不同可能是十几到二十几个字节;每包的载荷数据长度不超过256字节,这有利于减少传输时延,简化硬件实现。
下图显示了典型的请求包和响应包的格式,这些包的格式属于并行物理层包格式,串行物理层包的格式与此稍有不同。某些字段是依赖于具体的上下文的,并不会在所有的包中出现。
请求包以物理层字段开始,S位指示这是一个包还是一个控制符号(S=0表示是一个包,S=1表示是控制符号),AckID表明交换结构器件将用控制符号来确认哪一个包。PRIO字段指示用于流量控制的包优先级。TT、目标地址(Target Address)和源地址(Source Address)字段指示传输地址的机制类型、包应被传送到器件的地址和产生包的器件的地址。Ftype和事务(Transation)指示正被请求的事务。长度(size)字段等于编码后事务的长度,Rapid IO事务数据的有效裁荷(payload)长度从1到256字节不等。
SrcTID(源事务ID)指示事务ID,Rapid IO器件在两个端点器件间最多允许有256个未完成的事务。对于存储器映射事务,跟随在srcTID后面的是器件偏移地址(Device Offset Address)字段。写事务必须附带数据的有效裁荷,所有包以16位(2个字节)循环冗余校验码(CRC)结束。
响应包与请求包类似。状态(Status)字段指示是否完成了事务。目标TID(目标事务ID)字段的值与请求包中源事务ID字段的值相等。下图是请求包与响应包的包格式示意图
对于用户来说,最需要关注的就是逻辑层(上图中蓝色部分)各个字段的含义,逻辑层中Ftype与Ttype(Ttype字段和上图中的Transaction字段是同一字段,只不过叫法不同而已)两个字段唯一的确定了这个请求包的功能。下表列出了Ftype与Ttype所确定的包定义
Ftype (Format Type) 格式类型 | Ttype (Transaction Type) 事务类型 | 包类型 | 功能 |
0~1 | —— | Reserve | 无 |
2 | 4’b0100 | NREAD | 读指定的地址 |
4’b1100 | ATOMIC increment | 先往指定的地址中传递数据,再把传递的数据加1,此操作位原子操作,不可打断 | |
4’b1101 | ATOMIC decrement | 先往指定的地址中传递数据,再把传递的数据减1,此操作位原子操作,不可打断 | |
4’b1110 | ATOMIC set | 把指定地址中的数据每个bit全部写1 | |
4’b1111 | ATOMIC clear | 把指定地址中的数据清0(每个bit全部清零) | |
3~4 | —— | Reserve | 无 |
5 | 4’b0100 | NWRITE | 往指定的地址写数据 |
4’b0101 | NWRITE_R | 往指定的地址写数据,写完成以后接收目标器件(Target)的响应 | |
4’b1101 | ATOMIC test/swap | 对指定地址中的数据进行测试并交换,此操作为原子操作,不可打断 | |
6 | 4’bxxxx | SWRITE | 以流写方式写指定的地址,与NWRITE以及NWRITE_R相比,此方法效率最高 |
7 | —— | Reserve | 无 |
8 | 4’b0000 | MAINTENANCE read request | 发起读配置,控制,状态寄存器请求 |
4’b0001 | MAINTENANCE write request | 发起写配置,控制,状态寄存器请求 | |
4’b0010 | MAINTENANCE read response | 产生读配置,控制,状态寄存器响应 | |
4’b0011 | MAINTENANCE write response | 产生写配置,控制,状态寄存器响应 | |
4’b0100 | MAINTENANCE write request | 端口写请求 | |
9 | —— | Reserve | 无 |
10 | 4’bxxxx | DOOEBELL | 门铃 |
11 | 4’bxxxx | MESSAGE | 消息 |
12 | —— | Reserve | 无 |
13 | 4’b0000 | RESPONSE no data | 不带有效数据的响应包 |
4’b1000 | RESPONSE with data | 带有效数据的响应包 | |
14~15 | —— | Reserve | 无 |
1.2.3事务格式与类型
事务类型:
SRIO Gen2端点支持通过HELLO接口对八种格式类型进行编码和解码。许多格式类型也有与之关联的事务类型。一些格式也有与他们相关的特定格式的字段。由于这些数据包头的可变性质,有必要在逐个格式的基础上重用便码头中的字段。
FTYPE2-请求类
请求数据包允许生成端点从另一个SRIO Gen2端点中读取数据。SRIO Gen2端点可能被配置为支持公告端口、发起者/目标端口或发起者/目标读取端口上的请求类。有四个原子事务和一个与请求类相关的基本读取。所有请求事务都是AXI4-Stream接口上的单个节拍,并且只是编码的标头。
·NREAD(TTYPE=4’b0100)标准读取事务。相关响应是大小字段中提供的大小。
·ATOMIC Increment(TTYPE=4’b1100)读后增量事务,相关响应返回相关地址空间中的当前值。响应发送后,相关位置的值会递增和更新。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
·ATOMIC Decrement(TTYPE=4’b1101)读后递减事务。相关响应返回相关地址空间中的当前值。响应发送后,相关位置的值会递减和更新。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
·ATOMIC Set(TTYPE=4’b1110)读后集事务。相关响应返回相关地址空间中的当前值。响应发送后,相关位置的值应设置为全1。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
·ATOMIC clear(TTYPE = 4'b1111)读后清晰事务。相关响应返回相关地址空间中的当前值。响应发送后,相关位置的值应设置为全0。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
FTYPE5-Write Class写类型
写入数据包允许端点元素修改链接合作伙伴内存空间中的数据。SRIO Gen2端点可以配置为支持公共端口、发起者/目标端口或发起者/目标写入端口的写类。有三个原子事务和两个与写入类相关联的写入事务(一个有响应,一个没有)。AXI4-Stream接口上的所有写入事务都在2到33拍之间,由编码的标头和最多32字的数据组成。
·NWRITE(TTYPE=4’b0100).写事务,没有响应。标准写入事务允许子d-word或者多d-word写入。接收端点应执行写入指定地址。由于这种数据包类型的无响应性质,TID值未定义。
·NWRITE_R(TTYPE=4’b0101).写事务,期待响应。标准写入事务允许子d-word或者多d-word写入。接收端点应执行写入指定地址,然后将状态位OK或ERROR的单个节拍响应发送回发起端点。
·ATOMIC Swap(TTYPE=4’b1100).读后写事务。相关的响应应返回目标地址空间中的当前值。发送响应后,目标位置的值应替换为写入数据。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
·ATOMIC Compare-and-Swap(TTYPE=4’b1101).读后比较和交换。相关的响应应返回目标地址空间中的当前值。发送响应后,目标位置的值应与前八字节的有效裁荷进行比较。如果这两个值相等,则将数据的第二个DWORD写入一是别的内存位置。比较和交换事务必须同时发送比较值和写入值。所以请求事务在用户界面上有三拍:标题,比较值和写入值。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。
·ATOMIC Test-and-Swap(TTYPE=4’b1110).读后测试和交换事务。相关的响应应返回目标地址空间中的当前值。发送响应后,目标位置的值应替换为写入数据。ATOMIC事务只能是字节大小(size-1=0),半字大小(size-1=1)或者字大小(size-1=3)。由于这些大小限制,所有的响应都是两拍:一个标题后跟着一个数据的DWORD。
FTYPE6-Streaming Write Class流写类型
流写数据包允许断电元素修改链路合作伙伴内存空间中的大块数据。SRIO Gen2端点可以配置为支持公共端口、发起者/目标端口或发起者/目标写入端口的流写类。SWRITE事务旨在称为跨链路接口的SRIO事务中最有效的,因此在其他事务中缺乏许多字段。SWRITE类只是用了ftype、优先级和地址字段。不需要TID因为此数据包类型没有发送响应。不需要大小,因为所有事务都是DWORD的倍数。在AXI4-Stream接口上,流写事务在2和33拍之间,由编码头组成,后面跟着更多32个DWORD的数据。
FTYPE10-Doorbell Class门铃类型
门铃数据包包含一个16位的信息字段但是没有地址或者数据。为了使HELLO接口尽可能地高效,HELLO地址字段的部分用于传递门铃信息。SRIO Gen2端点可以配置为支持公共端口或发起器/目标端口上的门铃类。门铃数据包及其相关响应都是AXI用户界面上的单个字节(仅限编码标头)。
FTYPE11-Message Class消息类型
消息数据包头字段与其他事务类型非常不同。由于消息的寻址有接收端点处理,因此消息引用邮箱和信件进行投递,在任何时候每个邮箱/邮件组合都只允许一个消息序列。每个消息包仍然被限制在256字节的数据限制,但可以发送消息序列来构建更大的数据消息。Msglen字段指示有多少个消息包组成了更大的消息序列。消息序列中的每个数据包都提供了一个顺序段编号,以便接收端可以正确识别已接收的段。拆分消息序列时,预计该序列(最后一个数据包除外)中的每个数据包或段的大小相同。就是那个尺寸减去1,放在HELLO标题的一个字段尺寸里。段大小限制为8、16、32、64、128或256字节。最后的段大小可以是任何dword的倍数。Size-1字段仍反应用于序列中其余数据包的一般段大小。
SRIO Gen2端点可以配置为在公共端口、发起人/目标端口或单独的消息端口上支持消息类。所有消息都包含数据,因此它们包含HELLO接口上的多个节拍。消息响应不包含数据,仅跨越HELLO接口上的单个周期。
FTYPE13-Response Class响应类
HELLO接口上的响应数据包使用三种事务类型。响应大小,在一个案例中,字段取决于类型。响应事务必须用其相应请求事务中的源ID填充目标ID(在AXI4-Stream用户字段中)。此外,每个响应必须使用相同的TID,或者目标数据值,以便每个响应与其因果请求包相关联。
·No Data(TTYPE=4’b0000).没有数据的响应事务。当没有返回数据时使用的响应。通常这些响应预计将于NWRITR_R和DOORBELL数据包握手。一些端点可以选择使用此响应类型对于错误响应(“E”字段=1’b1)因为错误响应是必须的不携带数据。在HELLO界面上,这些响应总是一个节拍。当为SRIO Gen2端点选择单独的读写发起端口时,写响应端口上不会显示数据响应。对于其他配置,接收(I/O)或发起者响应(遗留)端口上是没有数据响应。任何数据响应都无法通过任何出口端口传输。
·Message(TTYPE=4’b0001).消息响应事务。无论错误状态如何。这些响应在HELLO界面上总是的那一的节拍,因为消息响应不包含数据。SRIO Gen2端点可以配置为在公共端口、发起人/目标端口或单独的消息端口上支持消息及其相应的响应。
·With Data(TTYPE=4’b1000).带有数据有效负载的响应事务。预期或返回数据时使用的响应。通常,这些响应预计将作为对ATOMIC和NREAD数据包的握手。端点可以选择使用此响应读取和原子错误响应(“E”字段=1’b1)即使错误需要响应不带数据。数据响应通常在HELLO接口上跨越2到33个周期,具体取决于请求大小。例外是不需要携带数据的单周期错误响应。当为SRIO Gen2端点选择单独的读写启动端口时,读取响应端口上会显示数据响应。对于其他配置,携带数据的响应会显示在接收(I/O)或者发起响应(Legacy)端口上。数据响应可以通过任何出口端口传输。
FTYPE9-Data Streaming数据流
HELLO接口上的数据流包使用五种事务类型,这取决于S和E位。像其他FTYPE支持一样,HELLO头后面跟着256字节的数据。在TX路径下,如有必要,你必须填充数据字节,并在用户界面上的HELLO头中设置适当的O和P位。在RX路径下,核心在用户界面上输出HELLO头和数据。HELLO头和用户界面的数据采用大端格式。
RapidIO事务的类型大概有以下几种
功能 | 事务类型 |
I/O非一致功能 | NREAITED(读非共享存储器) |
NWRITE、NWRITE_R、SWRITE(写非共享存储器) | |
原子(ATOMIC)(读-修改-写至非共享存储器) | |
基于端口的功能 | 门铃(DOORBELL)(产生中断) |
消息(MESSAGE)(对端口写) | |
系统支持功能 | 维护(MAINTENANCE)(读写配置、控制、状态寄存器) |
用户定义功能 | 对专用事务开放 |
高速缓存一致性功能 | 读(READ)(读全局共享高速缓存器) |
READ_TO_DOWN(写全局共享高速缓存器) | |
抛弃(CASTOUT)(交出全局共享高速缓存器拥有权) | |
IKILL(指令缓存失效) | |
DKILL(数据缓冲失效) | |
刷新(FLUSH)(返回全局共享高速缓存器至存储器) | |
IO_READ(读非缓冲全局共享高速缓存器的副本) | |
操作系统支持功能 | TLBIE(TLB失效) |
TLBSYNC(TLB强迫完成失效) |
1.2.4消息传递
当数据必须被系统中的多个处理器件共享时,必须由协议维护和管理多个器件对共享数据的临时占用,许多嵌入式系统用软件机制实现该协议。如果存储器空间可被多个器件访问,可以使用锁或者信号量来保证器件间正确的访问次序。在其他情况下,处理部件可能只有访问本地存储器空间的权力,在这些“非共享”的系统中,需要一种机制把数据从一个处理器件传递到另一个器件。使用消息传递(Message Passing)信箱(Mailbox)可以实现这种机制。
RapidIO提供了一种有用的消息机制,RapidIO消息传递协议描述了支持信箱和门铃通信的事务。
RapidIO信箱是一个端口,器件间可通过它发送消息。接收消息在消息到达后对其进行处理。
RapidIO消息的长度从0到4096字节不等。一个接收器件有1~4个可寻址消息队列来捕获输入的消息。
RapidIO门铃(Doorbell)是一种基于端口的轻量级事务,可用于带内(in_band)中断。门铃消息包括一个由软件定义的16位字段,该字段可用来在两个器件间传达多种不同意图的消息。
1.2.5全局共享存储器
支持全局共享的分布式存储器系统是RapidIO协议的扩展功能之一。这意味着可以把存储器放到系统中不同的物理位置上,可以正确地在不同处理器件之间的缓存。
RapidIO制定了一种基于目录的一致性解决方案来支持这种方法、使用这种方法,每个存储器控制器都有责任跟踪每个数据元素的当前副本在系统中位于什么位置,为一致域中的每个器件维护一个目录。跟踪每个器件的修改、共享、位置(MSL)等简单的一致性状态。
1.2.6流量控制
流量控制是任何互连技术的重要内容。流量控制是指任意时间互连技术采用某些规则和机制,根据这些规则和机制决定任意时间从可能获得的若干事务中选择哪一个事务进行发送。流量控制的目的是使器件完成系统中的事务,避免被其他事务阻塞。基于总线的互连技术使用仲裁算法来确保器件进行恰当的转发操作,确保高优先级的事务优先于低优先级的事务得到转发。采用交换的互连技术,事务从系统的不同位置进入,从而无法使用集中式的仲裁机制。这就需要一种管理系统中的事务流的方法。
RapidIO使用若干补充机制来获得系统中聘问的数据流并避免系统死锁。
1.2.7串行物理层
RapidIO逻辑层的包被定义为一连串的比特,并且与物理层实现无关。这意味着RapidIO协议在串行与并行接口,铜线与光纤介质下都能正常工作。在Xilinx FPGA中已经集成了GTP,GTX或GTH等高速串行收发器,所以在FPGA实现RapidIO高速传输协议都是采用的串行物理层而并非并行物理层。串行物理层使用8B/10B编码用到的字符(K码)完成定界,利用这种方式,发送器件使用K码作为定界符,为接收器件指明包或控制符号的开始和结束。
串行RapidIO规范使用物理编码子层(PCS)和物理媒介附属子层(PMA)在发送方将包转换成串行比特流。并在接收方提取出该比特流。除了在发送前进行编码和在接收后进行编码操作,PCS层还负责空闲序列(idle sequence)产生、通道对齐(lane alignment)以及接收方通道合并(lane destriping)的操作。PCS层使用8B/10B编码技术在链路上传送数据,8B/10B编码模块把8位数据编码转换为10位数据,编码后的数据包括原始数据和可恢复的时钟信息。PCS层还提供了一种机制,用于自动决定端口的工作模式是在单通道(1-lane)模式还是四通道(4-lane)模式。PSC层也可弥补发送方和接收方之间的时钟差。
PMA层负责逐个通道地将10位并行码组(code_group)数据串行化为串行比特流或将串行比特流并行化为10位并行码组数据。接收数据时,PMA层独立地、逐个通道地将接收到的比特流对齐到10位码组边界。然后向PCS层提供连续的10位码组流,每一通道分配一个码组流,每一通道分配一个码组流,10位码组对于PCS层以上各层是不可见的。
1.3 I/O逻辑操作与包格式
1.3.1引言
I/O逻辑操作支持RapidIO存储空间的基本读写,它可以通过请求和响应事务对来完成。请求和响应事务对穿越RapidIO交换结构运行,但当事务穿越交换结构时RapidIO交换结构并不跟踪该事务。从交换结构的角度看,请求事务和与之对应的响应事务间并没有明确的关系。虽然系统中可能存在多个中间交换器件和因此引起的多次包转发,但是从RapidIO逻辑层的角度来说,请求事务和响应事务只有一个(如果需要响应的话),中间交换器件不区分请求和响应事务,它们的作用只是转发事务到它们的最终目的地。
在RapidIO体系结构中定义了6中基本的I/O操作,下表给出了这6种基本的I/O操作、用来执行相应操作的事务和对操作的描述。
操作 | 使用的事务 | 描述 |
读 | NREAD、RESPONSE | 从目标器件中读数据 |
写 | NWRITE | 往目标器件中写数据 |
有响应写 | NWRITE_R、RESPONSE | 往目标器件中写数据,写完后等待目标的响应 |
流写 | SWRITE | 面向大数据量DMA传输优化写数据 |
Atomic | ATOMIC、RESPONSE | 原子操作,读-修改-写,事务不能被打断 |
维护 | MAINTENANCE | 以RapidIO专用寄存器为目标的事务 |
1.3.2请求包格式
RapidIO处理器发起一个请求包给目标器件(Target),目标器件收到这个请求包以后给一个响应包到处理器(前提是这个请求包需要目标器件的响应),比如存储器读操作。这个典型的请求包的格式如下图所示
对于用户来说,最需要关注的就是逻辑层(上图中蓝色部分)各个字段的含义,Ftype与Ttype两个字段唯一的确定了包的类型,具体的对应关系请参考1.2.2节。逻辑层各个字段的含义如下表所示
字段 | 含义 |
Ftype | 格式类型(Format Type),与Ttype共同唯一的确定包的格式 |
Ttype | 事务类型(Transaction Type),与Ftype共同唯一的确定包的格式 |
Wrsize/Rdsize | 此字段根据包的类型来决定是写事务数据的大小还是读事务数据的大小,这个字段配合wdptr(word pointer)字段一起使用 |
Src TID | 包的事务ID(Transaction ID)号 |
Extended Address | 扩展地址,这是一个可选字段,指定50-bit物理地址的高16-bit或者66-bit物理地址的高32-bit |
Address | 29-bit的物理地址,由于RapidIO传输以一个双字(double_word)为基本单元,大多数嵌入式系统是32位的,所以一个字(word)占用4个字节,一个双字(double_word)占用8个字节,所以29-bit的物理地址指向的一个存储单元实际上是占用了8个字节,这样用29-bit的物理地址实际上可以访问4G(2^32)的内存空间 |
Wdptr | 字指针(Word pointer),配合Wrisize/Rdsize字段来指明数据的大小以及对齐方式 |
Xamsbs | 扩展地址最高位(Extended address most significant bits),把物理地址进一步扩展2位,由于29-bit的地址已经可以访问4G内存空间,在最高位扩展2位以后就可以访问16G的内存空间 |
Data Payload | 要传输的数据 |
1.3.3响应包格式
当一个RapidIO端点完成由另一个RapidIO端点发起的请求时,该端点就会发送一个响应事务。响应事务包总是以与请求事务包相同的方式被发送和路由。从广义上说,第12、13、14和15类格式是响应类事务的格式。通常,第12和14类是保留的,第15类由具体应用定义,第13类才是主要的响应类事务。第13类包格式返回状态,数据(如果需要)和请求者的事务ID。带有“ERROR”状态或没有预期的数据裁荷的响应的REPONSE包没有数据裁荷。响应包使用第13类格式来响应出维护和无响应写之外的所有请求包。维护响应包响应维护请求。一个典型的响应包的格式如下图所示
逻辑层各个字段的含义如下表所示
字段 | 值 | 含义 |
Ftype | 4’b1101 | 格式类型(Format Type),与Ttype共同唯一的确定包的格式,对于一个有效的响应包来说,此字段的值固定为4’b1101,也就是16进制的d |
Ttype | 4’b0000 | 不携带数据的响应 |
4’b0001~4’b0111 | 保留 | |
4’b1000 | 携带数据的响应 | |
4’b1001~4’b1111 | 保留 | |
Status | 4’b0000 | DONE状态:表示请求事务得到了正确的响应 |
4’b0001~4’b0110 | 保留 | |
4’b0111 | ERROR状态:表示请求事务得到了正确的响应 | |
4’b1000~4’b1011 | 保留 | |
4’b1100~4’b1111 | 用户自定义响应 | |
Target TID | —— | 目标事务ID(Transaction ID)号 |
Data Payload | —— | 响应包携带的数据,如果是不携带数据的响应,那么这个字段就不存在 |
1.3.4常用的I/O逻辑操作事务
1.3.4.1读操作(NREAD)
读操作由一个NREAD事务和一个RESPONSE事务组成,NREAD事务由请求方(Requestor)发起,目标方(Destination)正确的处理请求方发过来的响应以后会给请求方反馈正确的响应以及请求方读取的数据。整个操作的示意图如下图所示
1.3.4.2写操作(NWRITE)和流写操作(SWRITE)
写操作(write operations)和流写操作(streaming-write operations)分别由NWRITE和SWRITE事务组成。请求方可以用这两种事务往目标方指定的地址写入数据。NWRITE事务允许多个双字(double-word),字(word),半字(half-word)和字节(byte)作为数据负载(Data Payload)进行适当的补0(padded)并进行8字节边界对齐。而SWRITE事务相当于用NWRITE事务传输双字(double-word)的情况,并且SWRITE事务具有更少的头部开销(SWRITE事务的包格式中把Ttype,Rdsize/Wrsize和scrTID三个字段全部定义为了Extened Address字段的一部分,所以头部开销变少)。NWRITE事务和SWRITE事务不需要接收目标方的响应,所以当事务被目标方处理完之后并不会给发起方反馈任何信息。NWRITE事务与SWRITE事务的操作示意图如下图所示
1.3.4.3带响应的写操作(NWRITE_R)
带响应的写操作(write-with-response operations)由NWRITE_R和RESPONSE事务组成。它的整个请求操作和NWRITE事务的请求操作完全相同,但是在目标方正确处理请求方的NWRITE_R事务以后,目标方会给请求方反馈一个响应包告诉请求方事务已经被正确的处理。这种机制可以有效地保证数据传输的稳定性。NWRITE_R事务的处理流程如下图所示
1.3.4.4原子操作(Atomic Operations)
原子操作(Atomic Operations)又叫做读-修改-写操作(Read-modify-Write Operations),它是由ATOMIC事务和RESPONSE事务组成,许多协处理器单元使用该操作来执行非一致性(non-coherent)存储器的同步。它所允许携带的数据量为一个字(4个字节),一个半字(2个字节)或者一个字节,其他数据量都是不被允许的。
原子操作既包含了写操作,也包含了读操作。目标方读取指定地址的数据,并把读取的数据返回给到请求方,然后对数据执行相关的操作,最后在写回指定的地址。这个过程不会被任何的其他事务所干扰或者打断。对数据执行的操作包括加1运算,减1运算,测试和交换,置1操作和清0操作,在这些操作中,只有测试和交换,比较和交换以及交换需要处理单元提供数据。原子操作的目标数据可以用NWRITE事务进行初始化。原子操作的操作示意图如下图所示
1.4操作维护和包格式
第8类事务维护事务用于访问RapidIO能力寄存器(CARs,Capability Registers)、命令和状态寄存器(CSRs,Command and Status Register),本地定义的寄存器(Locally-Refined Registers)以及数据结构(Data STRUCTURES)。与其他的请求格式不同,维护操作的请求和响应包格式都是第8类包格式。第8类包不含地址字段,只含写请求和读响应的数据裁荷。
WRSIZE字段规定了多双字事务数据裁荷的最大长度。数据裁荷的长度不能超过这个最大长度,但是如果需要的话,可以比这个最大长度小。维护读请求和维护请求都产生正确的维护响应。
维护事务的请求包格式如下图所示
维护事务的响应包格式如下图所示
维护事务包格式中逻辑层各个字段(Hopcount字段不属于逻辑层,下表同样列出它的含义)的含义如下表所示
字段 | 值 | 含义 |
Ftype | 8 | 第8类事务代表维护类事务,维护类事务中这个字段固定为8 |
Ttype | 4’b0000 | 指定一个维护读请求 |
4’b0001 | 指定一个维护写请求 | |
4’b0010 | 指定一个维护读响应 | |
4’b0011 | 指定一个维护写响应 | |
4’b0100 | 指定一个维护写端口请求 | |
4’b0101~4’b1111 | 保留 | |
Hopcount | 跳数是一个8bit字段,用于确定维护事务的目标交换器件。RapidIO交换器件没有器件ID,跳数是可供选择的寻址交换器件机制 | |
Config Offset | 用于读写CAR/CSR寄存器的双字偏移量 | |
Src TID | 维护请求包的事务ID | |
Target TID | 维护响应包的事务ID | |
Status | 4’b0000 | DONE状态:表明请求的事务成功完成 |
4’b0001~4’b0110 | 保留 | |
4’b0111 | ERROR状态:检查到不可恢复的错误 | |
4’b1000~4’b1011 | 保留 | |
4’b1100~4’b1111 | 用户定义 |
维护操作由维护请求事务和维护响应事务组成,处理器可以通过这类事务访问CARs/CSRs等寄存器中的数据。如果发起的维护请求事务需要一个响应,那么目标方正确处理了维护请求事务以后会给请求方反馈一个维护响应包而不是由NWRITE_R事务或NREAD事务产生的正常响应包。它支持读取配置寄存器的操作执行长度是字(4字节),也可以是双字(8字节)或设计者自己指定的双字的整数倍长,但执行长度最多不得超过64字节。所有写配置寄存器的操作执行长度规定与读操作相同。维护操作的示意图如下图所示
1.5消息操作和包格式
1.5.1引言
分布式处理系统的一般方法是使用连接到分布式存储器件的紧耦合处理器。这些处理器可能运行在一个单独的操作系统下。例如,一个单Linux系统可以在最多数十个处理器上有效地运行。通常一个单操作系统的任务是管理处理器组和存储器组。多数情况下,处理器可以高效的计算出通用硬件维护的一致性存储器空间。这允许处理器通过使用信号量(semaphores)、自旋锁(spin lock)和处理器间中断来解决任务的初始化和完成的通信问题。操作系统使用页保护方案集中管理存储器。这种多处理技术十分成熟,已经使用了几十年。
在其他分布式系统中,处理器和存储器的耦合度可能松一些。若干操作系统或者内核可能在同一个系统中共存,每个内核负责整个系统的一小部分。这些内核可能来自不同的软件供应商,可能运行在不同的处理器体系结构上。在这些系统中使用简单的通信机制时十分有用的;内核可以使用该机制与系统内的其他内核通信。例如,运行Linux的PowerPC处理器可能与运行QNX的TigerSHARC数字信号处理器通信。对于一个给定的应用,可能没有理由在这些器件间共享存储器空间。在这种类型的系统中,需要一种在所有器件上可用的通用硬件和软件接口机制来简单、经济地完成高性能通信。在这些系统中,处理器之间通过消息传递进行通信。
在这些消息传递系统中,经常使用两种机制将命令或数据从一个器件移动到另一个器件,第一种机制称为直接存储器访问(DMA),第二种称为消息(Message)。这两种模型地主要差别是,DMA事务由源端控制,而消息由目标端控制。这意味着DMA源端不仅需要访问目标,还必须具有对目标的地址空间的可见性。消息的源端仅需访问目标,而不需要对目标空间的可见性。在分布式系统中,通常DMA和消息机制是结合使用的。
RapidIO体系结构包括一种可以用于消息的包传输机制。RapidIO消息模型应满足下列目标:
- 消息由一个或多个事务组成,这些事务可以通过无序的互连发送和接收。
- 发送者可以有多个正在排队等待发送的未完成的消息。
- 发送者可以在低优先级消息前发送高优先级消息,也可以为了发送一个高优先级消息而抢占低优先级消息,并在高优先级消息完成后恢复低优先级消息(基于优先级的并发性)。
- 发送者无需了解接收者地内部结构或存储器映射。
- 消息接收者控制它本身的本地地址空间。
- 如果需要,接收者可以有多个未完成的正在排队等待服务的消息。
- 如果需要,接收者可以接收多个并发的多事务消息。
RapidIO消息传递逻辑规范定义了两种不同的包格式用于消息事务。第10类包格式用来发送非常短的16位数据裁荷,第10类包也称为门铃(DOORBELL)事务,门铃事务很适合发送最多4096字节的数据裁荷。下面将分别介绍两种事务。
1.5.2门铃事务(DOORBELL)
第10类包格式是门铃事务格式。它没有数据裁荷。
上图中的Ftype字段固定为10,表示这是一个门铃事务,8位的Reserved字段应该置0,Source TID指的是请求方的事务ID,info(msb)表示的是发送信息的高位,info(lsb)表示的是发送信息的低8位。如果信息使用数字表示的,而且长度大于8位,那么数据符合低地址存放高字节(big-endian)的格式。比特流中先到达的是高字节。门铃事务适合向处理器递送中断信息,在这种信息下,信息字段用来向接收者传递中断级别和目标信息,除此之外,还可以在处理器件间发送信号量。
一个完整的门铃操作由DOORBELL事务和RESPONSE事务(通常是DONE响应)组成。处理单元用这个操作将非常短的消息通过互连结构发送到另一个处理器部件。门铃事务包括用于保持事务信息的信息字段。该事务没有数据裁荷。它的信息字段是由软件定义的,可以用于任何目的。通常,运行在处理器上的操作系统会定义门铃事务使用的信息字段的意义。收到门铃事务的处理器部件将包放进处理器部件中的门铃消息队列,该队列可以在硬件或者本地存储器中实现。一个完整的门铃操作如下图所示
1.5.3消息事务
第11类包为消息事务格式包。第11类包总有数据裁荷,并且数据裁荷长度总是双字(64-bits或8-bytes)长度的整数倍。没有规定子双字(sub-double-word)消息,如果需要的话,可以用软件管理子双字消息。一个消息请求包的格式如下图所示
图中逻辑层各个字段的含义如下表所示
字段 | 值 | 含义 |
Ftype | 11 | Ftype=11表示这是一个MSEEAGE事务 |
Msglen | 消息长度(Message Length):指的是组成该消息的包的总数。值为0时表明该包是一个单包消息,值为15(4’b1111)时,表明这是一个由16个包组成的消息。 | |
Ssize | 标准消息包数据大小(Stardard message packet data size)。该字段告诉消息操作除消息中最后一个包外组成消息的所有包的数据裁荷大小。这样可以防止发送者过度延长最后一个包的数据字段并允许接收者正确的将包放入本地存储器 | |
4’b0000~4’b1000 | 保留(Reserved) | |
4’b1001 | 8字节(byte) | |
4’b1010 | 16字节(byte) | |
4’b1011 | 32字节(byte) | |
4’b1100 | 64字节(byte) | |
4’b1101 | 128字节(byte) | |
4’b1110 | 256字节(byte) | |
4’b1111 | 保留(Reserved) | |
Letter | 信件。该字段用来识别信箱(MailBox)中的一个槽(SLOT)。该字段允许发送方同时发送最多4个消息到接收方的同一个信箱中 | |
Mbox | 信箱(MailBox)。该字段用来指定目标处理部件中的接收信箱 | |
Msgseg | 消息段(Message Segment)。该字段用来表明该包是组成消息的包中的第几个包。值为15(4’b1111)表明该包是消息的第16个包 | |
Xmbox | 对于单包数据消息事务,该字段用来指明目标信箱的高四位。该字段与Msgseg占用相同的字段。Xmbox字段和mbox字段组合使用的定义如下: Xmbox||mbox:mailbox number 0000 00 : mailbox 0 0000 01 : mailbox 1 0000 10 : mailbox 2 0000 11 : mailbox 3 0001 00 : mailbox 4 …… 1111 11 : mailbox 63 |
尽管RapidIO规范使用信箱(MailBox)、信件(Letter)和消息分段(Messsage Segment)之类的术语,但是这些字段在逻辑上指的是一个8位的消息标识符信息。消息标识符信息可以用来唯一的标识和管理任意两个处理部件之间最多256个不同的消息流。接收处理部件的消息传递硬件会根据该信息计算应该把事务数据存放在本地存储器的什么位置。
例如,假设接收处理部件的信箱0、信箱1、信箱2和信箱3的起始地址分别为地址0*1000、0*2000、0*3000和0*4000,处理部件接收到的消息事务带有下列字段:
A、消息长度为6个包(msglen=4’b0110)
B、消息段是第3个包(msgseg=4’b0011)
C、信箱为信箱2(mbox=2’b10)
D、信件为1(letter=2’b01)
E、标准大小为32字节(ssize=4’b1011)
F、数据裁荷为32字节(由于这不是最后一个事务,所以数据裁荷应该是32字节)
处理部件的消息传递硬件使用这些信息来决定将这部分数据消息所含2字节数据存放在本地存储器地址0*3040。
目标地址=信箱2基地址(Mailbox_2_base)+(消息分段*标准长度)
0*3040 = 0*3000 +(0*0002 * 0*0020)
这个简单的寻址地址使得接收处理部件很容易计算存储消息数据的目标存储结构的位置对发送者也是不可见的。这允许仅在处理器部件间提供基于消息通信的安全系统研发工作。
消息的响应事务也是由第13类包产生,与NREAD事务和NWRITE_R事务响应包不同的是,消息事务的响应包中的target_info字段占用了普通响应包中的target ID字段的位置,具体的响应包格式见下图
其中消息响应中逻辑层Ftype字段,Ttype字段,Status字段以及Data Payload字段的含义与普通响应包中各字段的含义完全相同,Target_info字段由letter,mbox和msgseg三个字段组成,这三个字段的含义与消息请求包中这三个字段的含义完全相同。
由消息和响应(一般是DONE响应)事务组成的数据消息操作如下图所示,处理部件的支持消息传递的硬件用它向另一个处理器件发送数据消息。完成一次数据消息操作最多需要16个单独的消息事务。消息事务数据裁荷的大小是双字长度(8个字节)的整数倍。信件(letter),信箱(mbox)和消息段(msgseg)组合在一起,唯一地标识系统中每个请求和响应部件对的消息包,与其他请求类型使用的事务ID的作用一样。
1.6 RIO传输流程
RIO协议数据有包和控制符号组成。包是系统中各器件间通信的基本单元;控制符号有两个作用,一是管理RIO物理层互联的事务流,二是用来流量控制和维护等功能。
RIO协议的操作过程基于“请求”和“响应”事务,如图所示。
Rapid IO的传输流程
对于一次操作,发起器件向交换结构发出请求事务,开始一起操作,交换结构收到请求后发起控制符号,确认收到该请求,然后将该请求转发到目标端点,目标接收请求事务并完成操作后,发出响应事务,交换结构收到响应事务后发起控制符号,确认收到响应,并将响应事务转发到发起器件,发起器件收到响应事务后发出控制符号,表明响应包得到确认,至此操作完成。交换结构是指提供系统互连的单个或多个交换器件的集合,通常是一个交换机,一般只在大型系统中使用该结构,在小型系统中直接使用点对点的连接方式。
1.7总结
RapidIO的事务大致就上面几种,下图把所有的事务都放到一起以便于大家更快的查看相关的包格式与各个字段的位置。
这里有几点值得注意的是:
- 每个包的逻辑层字段与上文所讲的各个包的逻辑层字段定义完全相同
- 上图物理层字段的前10位所代表的字段ackID,rsvd,crf以及prio与正文中包格式的物理层字段有所出入,这是因为正文所讲解的包都是并行物理层的包格式,而上图中是串行物理层的包格式,所以物理层字段会有一点点区别。
- 上图每个包CRC字段的后面还有一些字段是正文中包格式所没有讲到的。由于RapidIO包的总长度大于80个字节以后。RapidIO包会对前80个字节生成一个2字节CRC码并补0使字节边界对齐。然后80字节以上的数据放在处理完毕以后的数据后面继续发送,发送完毕以后生成第二个CRC码并补0使字节边界再次补齐,其中第二个CRC校验码是第一个CRC校验码的延续。因此上图中会出现后面的那些字段。