【FPGA】SRIO中的关键问题总结(一)SRIO中的关键数据包格式总结
目录
1 SRIO事务及其类型
SRIO(Serial Rapid IO)事务(transaction)类型有SRIO包(packet)中的Ftype和Ttype决定,其中比较重要的是Nread(Ftype = 2,Ttype = 4),功能是读制定的地址;
NWRITE(Ftype = 5,Ttype = 4)表示往指定的地址写数据;
NWRITE_R(Ftype = 5,Ttype = 5),表示往指定的地址写数据,写完之后接收目标期间的响应,即所谓的带响应的写;
SWRITE(Ftype = 6,Ttype 保留),表示以流写方式写指定的地址,与NWRITE以及NWRITE_R相比,这种方式效率最高;
DOOREBELL(Ftype = 10,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 resquest |
端口写请求 |
|
9 |
—— |
Reserve |
无 |
10 |
4’bxxxx |
DOORBELL |
门铃 |
11 |
4’bxxxx |
MESSAGE |
消息 |
12 |
—— |
Reserve |
无 |
13 |
4’b0000 |
RESPONSE no data |
不带有效数据的响应包 |
4’b1000 |
RESPONSE with data |
带有效数据的响应包 |
|
14~15 |
—— |
Reserve |
无 |
I/O逻辑操作支持RapidIO存储空间的基本读写,它可以通过请求和响应事务对来完成。请求和响应事务对穿越 RapidIO交换结构运行, 但当事务穿越交换结构时RapidIO交换结构并不跟踪该事务。从交换结构的角度看, 请求事务和与之对应的响应事务间并没有明确的关系。虽然系统中可能存在多个中间交换器件和由此引起的多次包转发,但是从RapidlO逻辑层的角度来说,请求事务和响应事务只有一个(如果需要响应的话),中间交换器件不区分请求和响应事务,它们的作用只是转发事务到它们的最终目的地。
在 RapidIO体系结构中定义了6种基本的I/O操作, 下表给出了这6种基本的I/O操作、用来执行相应操作的事务和对操作的描述,
操作 |
使用的事务 |
描述 |
读 |
NREAD、RESPONSE |
从目标器件中读数据 |
写 |
NWRITE |
往目标器件中写数据 |
有响应写 |
NWRITE_R、RESPONSE |
往目标器件中写数据,写完后等待目标的响应 |
流写 |
SWRITE |
面向大数据量DMA传输优化写数据 |
Atomic |
ATOMIC、RESPONSE |
原子操作,读-修改-写,事务不能被打断 |
维护 |
MAINTENANCE |
以RapidIO专用寄存器为目标的事务 |
2 常用的I/O逻辑操作事务
1、读操作(NREAD)
读操作由一个NREAD事务和一个RESPONSE事务组成,NREAD事务由请求方(Requestor)发起,目标方(Destination)正确的处理请求方发过来的响应以后会给请求方反馈正确的响应以及请求方读取的数据。整个操作的示意图如下所示
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和srcTID三个字段全部定义为了Extended Address字段的一部分,所以头部开销变少)。NWRITE事务和SWRITE事务不需要接收目标方的响应,所以当事务被目标方处理完以后并不会给发起方反馈任何信息。NWRITE事务与SWRITE事务的操作示意图如下图所示
3、带响应的写操作(NWRITE_R)
带响应的写操作(write-with-response operations)由NWRITE_R事务和RESPONSE事务组成。它的整个请求操作和NWRITE事务的请求操作完全相同,但是在目标方正确处理请求方的NWRITE_R事务以后,目标方会给请求方反馈一个响应包告诉请求方事务已经被正确的处理。这种机制可以有效的保证数据传输的稳定性。NWRITE_R事务的处理流程如下图所示
4、原子操作(Atomic Operations)
原子操作(Atomic Operations)又叫做读-修改-写操作(Read-modify-Write Operations),它是由ATOMIC事务和RESPONSE事务组成,许多协处理器单元使用该操作来执行非一致性(non-coherent)存储器的同步。它允许携带的数据量为一个字(4个字节),一个半字(2个字节)或者一个字节,其他数据量都是不被允许的。
原子操作既包含了读操作,也包含了写操作。目标方读取指定地址的数据,并把读取的数据返回给请求方,然后对数据执行相关的操作,最后在写回指定的地址。这个过程不会被任何其他的事务干扰或者打断。对数据执行的操作包括加1运算(increment),减1运算(decrement),测试和交换(test-and-swap),置1操作(set)和清0操作(clear),在这些操作中,只有测试和交换(test-and-swap),比较和交换(compare-and-swap)以及交换(swap)需要处理单元提供数据。原子操作的目标数据可以用NWRITE事务进行初始化。原子操作的整个操作示意图如下图所示
3 HELLO包格式(重点)
为了简化RapidIO包的构建过程,RapidIO核的事务传输接口(ireq,treq,iresp,tresp)可以配置为HELLO(Header Encoded Logical Layer Optimized)格式。这种格式把包的包头(Header)域进行标准化,而且把包头和数据在接口上分开传输,这将简化控制逻辑并且允许数据与发送边界对齐,有助于数据的管理。
HELLO格式的包如下图所示
其中,各个字段的定义如下表所示
字段 |
位置 |
描述 |
TID |
[63:56] |
包的事务ID(Transaction ID),RapidIO手册规定在给定的时机,RapidIO包只能有唯一的TID与Src ID对。 |
FTYPE |
[55:52] |
包的事务类(Transaction Class),HELLO格式支持的FTYPEs为2,5,6,A,B和D。 |
TTYPE |
[51:48] |
包的事务类型(Transaction Type),当FTYPE的值为2,5或D时,不同的TTYPE值对应于包的不同功能。 |
Priority |
[46:45] |
包的优先级。请求包的优先级值为0~2,响应包的优先级值为请求包的优先级加1 |
CRF |
[44] |
包的关键请求流标志(Critical Request Flow) |
Size |
[43:36] |
有效数据负载的字节数减1,如果这个字段的值为0xFF,那么表示有效数据为256(0xFF + 1)个字节 |
Error |
[35] |
当这个字段为1时表示包处于错误状态 |
Address |
[33:0] |
事务的字节地址 |
Info |
[31:16] |
信息域。仅在门铃事务(DOORBELL)中包含此字段 |
Msglen-1 |
[63:60] |
消息事务(MESSAGE)中包的个数。仅在消息事务(MESSAGE)中包含此字段 |
Msgseg-1 |
[59:56] |
包中的消息段,仅在消息事务(MESSAGE)中包含此字段,如果是单段(signal-segment)消息,此字段保留 |
Mailbox |
[9:4] |
包的目标邮箱,仅在消息事务(MESSAGE)中包含此字段,除了单段(signal-segment)消息以外,此字段的高四位是保留位 |
Letter |
[1:0] |
包的信件,仅在消息事务(MESSAGE)中包含此字段,指示了邮箱中的一个插槽 |
S,E,R,xh,O,P |
[63:56] |
S:起始位,当此字段为1时表示这个包是新PDU(Protocol Data Unit)的第一个分段。 E:结束位,当此字段为1时表示这个包是新PDU(Protocol Data Unit)的最后一个分段。当S和E均为1时表示PDU仅包含一个包。 R:保留位。 Xh:扩展头(Extended Header)。目前版本不支持 O:奇数(Odd),当此字段为1时表示数据负载有奇数个半字。 P:填充位(Pad)。当此字段为1时,一个填充字节用于去填充数据到半字(half-word)边界 |
Cos |
[43:36] |
服务类(Class of service) |
StreamID |
[31:16] |
点到点的数据流标识符 |
Length |
[15:0] |
协议数据单元(Procotol Data Unit,PDU)长度 |
HELLO格式的包中Size域的值等于传输的字节的总数减1,Size域的有效值范围为0~255,对应于实际传输的字节数量1~256。HELLO格式中的size和address域必须对应于RapidIO包中有效的size,address和wdptr域,所以HELLO格式的size和address字段的值存在一些限制条件。RapidIO核不能把Size域中的非法值修正为实际RapidIO包中Size域的有效值,所以需要对HELLO格式包的Size域提供一个正确的值。由于AXI4-Stream协议中tdata信号为8个字节,也就是一个双字(Double Word),所以Size域的值需要分两种情况讨论:传输的数据量小于8字节和传输的数据量大于8字节。
传输的数据量小于8字节(Sub-DWORD Accesses):
对于传输的数据量小于8字节的情况,address字段和size字段用来决定有效的字节位置(tkeep信号必须为0xff),但是仅仅能导致RapidIO包中rdsize/wrsize和wdptr为有效值的address和size值组合才是被允许的,下图是HELLO格式中address和size两个字段与有效字节位置的对应关系示意图(图中灰色部分为有效字节位置)
例如,对size=2,address=34’h1_1234_5675这两个组合来说,由于size=2,所以往address中写入的数据个数为3(size+1)个字节,而address的最低3位为5(3’b101),通过上图可知,有效字节的位置是第7、6、5三个字节。对于size和address[2:0]值的组合不在上图中的情况都是非法的,这是应该避免的,比如,size=2, address=34’h1_1234_5673这种组合就属于非法的组合。
传输的数据量大于8字节(Large Accesses):
对于传输的数据量大于8字节,并且地址的起始字节偏移不为0的情况必须把数据分成多次进行传输,其中未对齐的小于8字节的段就可以通过上图中size和address的有效组合来确定有效字节的位置。另一种解决办法是,读操作的数据量大小可以被增加到下一个支持的大小,然后从对应的响应中剥离出必要的数据。
因此,对于数据量为1个双字(8个字节)或更大的情况,address的最低3位必须为0,RapidIO手册给读写事务定义了范围从1到256个字节的可支持的数据量。请求事务的数据量如果大于一个双字(8个字节),那么数据量应该通过四舍五入到最接近的支持的值。读写事务有效的HELLO格式的数据量为:7,15,31,63,95(仅支持读事务),127,159(仅支持读事务),191(仅支持读事务),223(仅支持读事务)和255。
对于写事务的数据量介于以上这些支持的数据量中间的情况,在通道的tlast信号为1之前应该给RapidIO核提供必要的数据量,仅仅提供的数据才能被发送。同理,用户的设计提供的数据可能少于期望的数据量,那么实际的数据量应该被写入,传输应该假设完成。
RapidIO协议不支持传输的数据量大于256字节的情况,并且逻辑层(Logical)也不能把大于256字节的数据量分割为小的数据量进行发送。如果不满足这个要求可能会导致致命的链路错误,在这种错误情况下,链路可能会不断重传数据量大于256字节的包。
HELLO格式数据的包头(Header)在用户接口的第一个有效时钟上,如果发送的事务携带数据负载,那么数据负载紧接着包头(Header)后面进行连续发送。包的Source ID和Destination ID放在tuser信号中并与包头(Header)一样,在第一个有效时钟下进行发送,发送完毕以后,tuser信号的数据被忽略。
下图是携带有数据负载HELLO格式包在用户接口上传输的时序图,这个传输有4个双字(32个字节)的数据负载,加上包头,整个传输一共花费了5个时钟周期。用户只需要把想要发送的数据按照下图的时序图送入RapidIO核的AXI4-Stream接口,RapidIO核就能把它转化为标准的RapidiO串行物理层的包发出去从而完成一次事务的交互。
下图是一种更复杂的传输示意图。首先,有两个背靠背(back-to-back)单周期包(包不带数据负载,仅包含一个包头)。包的边界通过拉高tlast信号进行指示。在单周期包传输完毕以后,主机等待了一个时钟周期才开始发送下一个包。在发送第三个包的过程中,主机(Master)和从机(Slave)分别通过拉低tvalid和tready信号一个时钟周期来暂停数据的发送,由于第三个包的数据负载为2个双字,所以传输第三个包一共消耗了3个有效时钟,加上2个无效的时钟周期,一共消耗了5个时钟周期。
4 SRIO数据包包格式
注意这个包格式是总的包格式,最后由高速串口发送出去的数据包的格式就是这个格式,我们知道数据包的类型,也就是传输事物(transaction)的类型由Ftype和Ttype决定的,从上表也可以看到Ftype取值有2,5,6,8,10,11,13,通过Ftype来区分传输事物类型的大类,而具体的事物类型有Type决定,如下表:
易知,Ftype = 2 为读事物类型以及原子事物类型;
5为写事物类型以及原子事务类型;
6为流写事物类型;
8为维护事物类型;
10为门铃事物类型;
11为消息事物类型;
13为响应事物类型,也即专门用来传输响应事物的响应事物包。例如发送NWRITE_R写事物,接收方就需要产生一个响应事物,而最终响应事物的格式通过高速串口发送出去的格式就是这种格式。
5 控制符号数据包格式
先给出控制符号包格式:
控制符号有什么用途呢?
通过阅读数据手册(PG007)可以知道,当7个连续的error free控制符号被接收,并且15个连续的控制符号被发送的时候,link_initialized信号才被拉高。
如下图,link_initialized信号为SRIO IP核的一个输出,有效则表示链路初始化成功。
此外,在传输一个事物包时,都会有一个包起始控制符号,当然事物包传输结束时也会有一个包结束控制符号。
例如:
起始包:
结束包:
最后提醒一下,如果在Serial Transceiver收到的数据包的包起始控制符号之前有一个8位数据7c,它表示的是包界定符,K28.3,它通常在包起始控制符号开头以及包结束控制符号开头。
参考链接:
PG007
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/94352579
- 点赞
- 收藏
- 关注作者
评论(0)