总的目录在这哦~
https://blog.csdn.net/z123canghai/article/details/114648658
5.1 概述
第一二章内容是概念性的,一是理解互连的含义,二是对rapidio有个大致的认识。第三、四章阐述xilinx的srio核相关内容,了解核结构、如何配置该核以及相应的测试程序的解析,本章就在前四章内容的基础上深入的阐述rapidio的各种协议。描述方式采用是按功能进行分类,对每一类的协议进行详细的描述并结合具体的时序。
5.2 事务类型介绍
在RapidIO体系结构中定义了6种基本的I/O操作,也就是6种不同的事务类型(FT),每个大的事务类型有包括若干个小的事务类型(TT),如下表所示给出了这6种基本的I/O操作及用来执行相应操作的事务和对操作的描述,其中“N”应该是节点的意思吧。
操作 | 使用的事务 | 描述 |
请求类事务 | NREAD、ATOMIC_inc、dec、set、clr | 从目标器件中读数据 |
写 | NWRITE | 往目标器件中写数据 |
有响应写 | NWRITE_R、RESPONSE | 往目标器件中写数据,写完后等待目标的响应 |
流写 | SWRITE | 面向大数据量DMA传输优化写数据 |
Atomic | ATOMIC、RESPONSE | 原子操作,读-修改-写,事务不能被打断 |
维护 | MAINTENANCE | 以RapidIO专用寄存器为目标的事务 |
对上表的分析我们也可以看出,这六个事务(FT)其实囊括了四大类功能,即读、写、Atomic和维护。为什么要将这四大类功能分为不同的事务而不直接分为四大类呢?这是因为事务的分类是按照协议的格式分的。如下图,每一条是一个协议类型,每一种协议就是一种格式,而一种格式可适用于多项功能。这种分类方式更有利于我们的程序设计和可扩展性。例如我们是功能分类,那我们肯定是分为四类,每一类可能都需要对同一个协议进行描述,所以必然造成代码的重复性。如果按照协议分类,只要我们做好每种协议的接口即可
但我们在理解各种协议时却可以按照功能分类来理解,如下表。
操作 | 使用的事务 |
写 | NWRITE、NWRITE_R、SWRITE |
读 | NREAD、RESPONSE |
Atomic | ATOMIC_inc(增加)、dec(减少)、set(置位)、clr(清零)、test(测试)、swap(交换) |
维护 | MAINTENANCE |
写很好理解,就是A给B发数据,只不过rapidio比较厉害,支持不同的数据发送模式,具体的在下文阐述。读也是,A发出个读请求,B将数据反馈给A。Atomic呢?我们也称之为原子操作。原子本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被中断的一个或一系列操作”。这就是原子操作的特点,它类似与中断,是不可被打断的,如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性。所以我们在用原子操作时候就要有这样的功能。维护操作是用来访问寄存器的,一般是用来访问 RapidIO能力寄存器(CARs,Capability Registers)、命令和状态奇存器( CSRs,Command and Status Register) ,本地定义的寄存器(Locally-Refined Registers)以及数据结构(Data Structures)。
下面呢,我们就对各个事务分别做详细描述。
5.2.1 请求事务格式(FT=2)
请求类事务包括读请求和原子操作。这一类事务的执行不包括有效数据的传递,也可以将这种事务类型理解成是一个指令,对于NREAD类型事务,通过该指令请求得到另一个器件上某内存区域中的内容,内存请求的数据长度在1到256字节之间,返回的数据要进行对齐限制(通过Rdsize、Wdptr实现),数据超过8字节就应以双字的方式对齐,数据长度应该是8字节的整数倍。对于原子操作,允许请求的数据长度为单字节、双字节和四字节,不允许8、3、5、7字节。具体事务如下表。
序号 | TT | 类型 | 备注 |
1 | 0X4 | NREAD | 读操作, |
2 | 0XC | ATOMIC_inc | 增加数据 |
3 | 0XD | ATOMIC_dec | 删减数据 |
4 | 0XE | ATOMIC_set | 置位 |
5 | 0XF | ATOMIC_clr | 清零 |
字段 | 含义 |
Ftype | 事务类型,就是确定这包数据大致是干嘛的 |
Ttype | 事务类型(Transaction Type),与Ftype共同唯一的确定包的格式 |
Rdsize | 此字段根据包的类型来决定读事务数据的大小,这个字段配合wdptr(word pointer)字段一起使用,并不是简单的表示数据长度 |
Src TID | 包的事务ID(Transaction ID)号。RapidIO器件在两个端点器件间同时处理最多允许有256个事务。可以理解为两个端点间传输包的编号吧 |
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),配合Wrsize/Rdsize字段来指明数据的大小以及对齐方式,详细的说明请查看RapidIO_Rev_2.2_Specification第33页 |
Xamsbs | 扩展地址最高位(Extended address most significant bits),把物理地址进一步扩展2位,由于29-bit的地址已经可以访问4G内存空间,在最高位扩展2位以后就可以访问16G的内存空间 |
本节最重要的内容是如何确定请求地址及请求的数据长度。
正如《RapidIO嵌入式互连》所说,Wrsize/Rdsize、Extended Address、Wdptr、Address并不是如字面意思那样简单。当初rapidio的设计为了节省位宽,将通常需要48bit表示总线事务的典型设计(32bit地址,8bit字节通道,8bit事务大小)用36比特实现。首先,请求地址为什么是29bit呢,因为rapidio是双字对齐,注意是双字不是双字节,也就是64bit对齐。Address是一个位宽为29bit的物理地址,由于29bit指定的是双字(64bit),所以支持寻址范围达4G,Xamsbs是两bit数据,作为寻址空间的最高位,将寻址范围扩大到了16G。但有个问题,由于寻址最小单元是64bit数据,那么,如果一个地址存放8bit,我们只需要取出20个字节,该如何操作呢?而且若地址不能对齐,即便数据是8的整数倍,也会出现如下图的情形。
一个发送端期望通过互联架构将其数据包发送到另外接收端中,因为流的开始和结束并不对齐到一个双字边界,发送端会将这个流拆分成3次交易如图所示,第一次交易送出头三个字节(在字节lane5、6、7),第二次交易送出所有余下的数据完整的64bit数据,第三次交易送出最后5个字节在字节lanes0、1、2、3、4。
这就需要其他数据来进行辅助定位,而且说到现在,我们还没说如何确定请求数据长度呢。所以,下面就靠Wrsize/Rdsize、Wdptr了。它们所表示的含义已经在上文表格中描述了,下面就说一下怎么用。
首先要思考一个问题,我们要用“Wrsize/Rdsize、Wdptr”做什么?两件事,1是确定数据长度,2是非边界对齐时读的或写的位置,也就是如图1-2的第一次和第三次读数据。Rapidio的巧妙设计实现了这两个功能的同时实现。
这个就是rapidio做了规定,规定“Wrsize/Rdsize、Wdptr”以什么样的组合表示什么样的情况,如下表所示。所以在设计时就需要以查找表的方式来实现。
5.2.2 写事务包格式(FT=5)
写类型格式包包括NWRITE(节点写)、NWRITE_R(带响应的节点写)、ATOMIC_swap、compare-and-swap、test-and-swap这几种类型。这一类事务包括有效数据,对于有效数据等于或小于一个双字的数据组合方式由Wrsize、Wdptr生成的查找表来确定,对于整数倍的双字数据,wrsize字段指定多个双字事务的数据有效负载的最大大小。对于NWRITE,是不需要响应的写事务,故srcID是任意值。NWRITE_R是需要接收方响应的两种操作,这两种操作对于请求放指示TT的不同,请求方可以用这两种事务往目标方指定的地址写入数据。对于原子操作的test-and-swap模式和swap,只允许1个双字的数据载荷。而compare-and-swap模式允许两个双字的有效数据载荷。
它们的协议如下所示。
各个字段的含义与5.2.1一致,只不过多了数据段。
5.2.3 流写事务包格式(FT=6)
事务类型6只有一种事务,就是流写(swrite streaming write)。这可以看做NWRITE的一种特殊形式,它没有表示数据长度的字段(即Wrsize、Wdptr),所以只能通过包内的数据长度来判断,数据字段的长度可以在8到256之间,且必须双字对齐,长度是双字的整数倍。这种模式一般用来迁移DMA类操作的大量数据,传输效率很高。
3.2.4 维护事务格式(FT=8)
类型维护数据包格式用于访问RapidIO功能和状态寄存器(CAR和CSR)以及数据结构。与其它事务不同,类型8数据包格式既用作维护操作的请求格式又用作响应格式。类型8数据包不包含地址,仅包含写请求和读响应的数据有效载荷。所有配置寄存器读取访问均以字(4字节)和可选的双字(8字节)或指定的多个双字数量(不超过64个字节)进行wrsize字段指定。
维护端口写操作是写操作,不能保证传递,也没有相关的响应。此维护操作对于从不包含端点的设备(例如交换机)发送消息(例如错误指示符或状态信息)很有用。数据有效载荷通常放置在目标端点的队列中,并且通常会向本地处理器生成中断。对已满的队列的端口写请求或忙于处理另一个请求可能会被丢弃
表4-7提供了特定于类型8数据包的字段的定义和编码。表4-2中描述了非特定于类型8数据包的字段。
第8类事务维护事务用于访问RapidIO能力寄存器(CARs,Capability Registers)、命令和状态奇存器(CSRs,Command and Status Register),本地定义的寄存器(Locally-Refined Registers)以及数据结构(Data Structures)。与其他的请求格式不同,维护操作的请求和响应包格式都是第8类包格式。第8类包不含地址字段,只含写请求和读响应的数据载荷。
第8类事务维护事务用于访问RapidIO能力寄存器(CARs,Capability Registers)、命令和状态奇存器(CSRs,Command and Status Register),本地定义的寄存器(Locally-Refined Registers)以及数据结构(Data Structures)。与其他的请求格式不同,维护操作的请求和响应包格式都是第8类包格式。第8类包不含地址字段,只含写请求和读响应的数据载荷。
3.2.5 门铃事务格式(FT=10)
类型10数据包格式是(DOORBELL)门铃事务格式,这类型事务没有载荷有效数据,结构非常简单,用于简单的消息传递和中断。
3.2.6 消息事务格式(FT=11)
对消息事务的理解,首先要明白其应用场景。
如下图所示是消息事务格式,这与之前的有较大的不同,下面首先对比较陌生的几个字段进行阐述。
字段 | 值 | 含义 | |
Ftype | 4‘b1011 | Ftype=11表示这是一个MESSAGE事务 | |
Msglen | 包的个数 | 消息长度(Message Length):指的是组成该消息的包的总数。值为0时表明该包是一个单包消息,值为15(4’b1111)时,表明这是一个由16个包组成的消息。 | |
Ssize | 4’b0000~4’b1000 | 保留(Reserved) | 标准消息包数据大小(Stardard message packet data size)。该字段告诉消息接收者一个单独消息操作除消息中最后一个包外组成消息的所有包的数据载荷大小。这样可以防止发送者过度延长最后一个包的数据字段并允许接收者正确的将包放入本地存储器 |
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 | 2bit信件。该字段用来识别信箱(MailBox)中的一个槽(SLOT)。该字段允许发送方同时发送最多4个消息到接收方的同一个信箱中 | ||
Mbox | 信箱的哪个格子 | 2bit信箱(MailBox)。该字段用来指定目标处理部件中的接收信箱 | |
Msgseg | 哪个信箱 | 4bit消息段(Message Segment)。该字段用来表明该包是组成消息的包中的第几个包。值为0表明该包是消息的第一个包。值为15(4’b1111)表明该包是消息的第16个包。 | |
Xmbox | 对于单包数据消息事务,该字段用来指明目标信箱的高四位。该字段与Msgseg占用相同的字段。 Xmbox字段和mbox字段组合使用的定义如下: xmbox || mbox : mailbox number 0000 00:mailbox0 0000 01:mailbox1 0000 10:mailbox2 0000 11:mailbox3 0001 00:mailbox4 1111 11:mailbox63 |
3.2.7 响应类型包格式(FT=13)
当一个RapidIO端点完成由另一个RapidIO端点发起的请求时,该端点就会发送一个响应事务。响应事务包总是以与请求事务包相同的方式被发送和路由。从广义上说,第12、13、14 和15类格式(Ftype=12表示的就是第12类格式)是响应类事务的格式。通常,第12和14类是保留的,第15类由具体应用定义,第13类才是主要的响应类事务。第13类包格式返回状态,数据(如果需要)和请求者的事务ID。带有“ERROR”状态或没有预期的数据裁荷的响应的RESPONSE包没有数据载荷。响应包使用第13类格式来响应除维护和无响应写之外的所有请求包。维护响应包响应维护请求。一个典型的响应包的格式如下图所示
逻辑层各个字段的含义如下表所示
字段 | 值 | 含义 |
Ftype | 4’b1101 | 格式类型(Format Type),与Ttype唯一的确定包的格式,对于一个有效的响应包来说,此字段的值固定为4’b1101, |
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 | —— | 响应包携带的数据,如果是不携带数据的响应,那么这个字段就不存在 |
就关于官方的实例分析,不仅实现了对核的配置、仿真,还对信号进行了整理,如下所示
开发软软件为vivado2016.4,打开工程点击“Flow”选择“open static simulation”打开静态仿真可直接查看信号波形
相关程序可关注“沧小海的FPGA”微信公众号回复“SRIO”即可获取,感谢关注~