本文转载自:十年老鸟的CSDN博客
前言
这段时间,随着对SRIO的学习,又有了更深的一点认识,不像一开始这么慌张了。
SRIO的协议有一千来页,一个初学者是不可能一开始就去读协议的,那得学到猴年马月呀,为了避免从入门到放弃,得快速的学习才行,不仅要看明白官方的例程,同时还要自己动手改改才行,这样才能建立信心。
这里要特别感谢这几个博主,对我学习SRIO起到了非常大的作用。
1、https://www.cnblogs.com/liujinggang/p/ 这位大佬对SRIO估计已经玩转的非常深刻了,他的系列文章实在是太详细了
2、https://blog.csdn.net/m0_52840978/article/details/121618190?spm=1001.2014.3001.5502 这位大哥的系列文章也还不错
SRIO的理解
RapidIO采用三层分级体系结构:
1、逻辑层
2、传输层
3、物理层
Rapid IO分为并行Rapid IO标准和串行Rapid IO标准,现在一般来说我们都是用串行Rapid IO,使用FPGA的Serdes,因此是SRIO
RapidIO操作是基于请求和响应事务的。
系统中的发起器件(Initiator)通过产生一个请求事务(Request)开始一次操作。该请求包传送至交换结构器件(Fabric),通常是一个交换机,交换结构器件发出控制符号确认收到了该请求包,然后交换结构将该包转发至目标器件(Target),这就完成了此次操作的请求过程。目标器件(Target)完成要求的操作,产生响应事务(Response)。通过交换结构(Fabric)将承载该事务的响应包传送回发起器件(Initiator).传送时使用控制符号对每一跳(hop)进行确认。一旦响应包到达发起器件(Initiator)并得到确认,就可认为此次操作已经完成。
RapidIO 传递信息又是以包的形式
逻辑层、传输层、物理层会对信息进行层层封装,最终形成一个物理层包。
其请求包和响应包的物理层包格式如下:
如果是使用IP核的话,与用户的接口就是逻辑层,因此我们只要对逻辑层的内容进行填写。
包的类型有很多,是通过逻辑层中Ftype与Ttype(Ttype字段和上图中的Transaction字段是同一个字段,只不过叫法不同而已)两个字段。
以下是所有包的定义:
大部分情况下,我们都是用于I/O逻辑操作,在 RapidIO体系结构中定义了6种基本的I/O操作, 下表给出了这6种基本的I/O操作、用来执行相应操作的事务和对操作的描述,
这些操作,有些是没有响应的,有些是有响应的,这点在后面需要慢慢理解
RapidIO的协议已经在这个系列的前面几篇文章中做了很多介绍了,这里仅仅做一个总结。
第2类事务(FTYPE=2)为请求类事务,根据TTYPE字段的不同值,它包括NREAD事务(TTYPE=4’b0100),ATOMIC Increment事务(TTYPE=4’b1100),ATOMIC Decrement事务(TTYPE=4’b1101),ATOMIC Set事务(TTYPE=4’b1110),ATOMIC Clear事务(TTYPE=4’b1111)这几种。
第5类事务(FTYPE=5)为写类事务,根据TTYPE字段的不同值,它包括NWRITE事务(TTYPE=4’b0100),NWRITE_R事务(TTYPE=4’b0101),ATOMIC Swap事务(TTYPE=4’b1100),ATOMIC Compare-and-Swap事务(TTYPE=4’b1101),ATOMIC Test-and-Swap事务(TTYPE=4’b1110)这几种。
第6类事务(FTYPE=6)为SWRITE事务(流写事务),请求方可以利用流写事务往目标方的存储空间写入大块数据。与NWRITE相比,流写事务具备以下两个特点:1、流写事务传输数据的最小单位为双字(Double Word);2、流写事务的包格式相对于NWRITE包格式具有更少的头部开销。
第10类事务(FTYPE=10)为DOORBELL事务(门铃事务),门铃事务不包含数据负载,它只能用来传输16-bit的信息,所以DOORBELL事务适合传输中断或者信号量。
第11类事务(FTYPE=11)为MESSAGE事务(消息事务),消息事务必须携带数据负载,完成一次数据消息操作最多需要16个单独的消息事务,其中每个消息事务携带的数据负载最大仍为256字节,所以消息操作的最大数据载荷为4096字节(16*256 Bytes)。
第13类事务(FTYPE=13)为响应类事务,根据TTYPE字段的不同值,它包括不带数据响应事务(TTYPE=4’b0000),消息响应事务(TTYPE=4’b0001)和携带数据响应事务(TTYPE=4’b1000)。
第9类事务(FTYPE=9)为Data Streaming事务,在标准的RapidIO协议中第9类事务为保留事务,所以第9类事务是一种自定义的事务。关于第9类事务的详细内容请查看pg007_srio_gen2.pdf的第106页。
RapidIO协议中只有NREAD、DOORBELL、MESSAGE以及NWRITE_R这几种事务有响应事务。
IP核的理解
RapidIO核的设计标准来源于RapidIO Interconnect Specification rev2.2,它支持1x,2x和4x三种模式,每通道的速度支持1.25Gbaud,2.5Gbaud,3.125Gbaud,5.0Gbaud和6.25Gbaud五种。
RapidIO核分为逻辑层(Logical Layer),缓冲(Buffer)和物理层(Physical Layer)三个部分。其中逻辑层(Logical Layer)支持发起方(Initiator)和目标方(Target)同时操作;支持门铃事务(DOORBELL)和消息事务(MESSAGE),为维护事务(MAINTENANCE)设计了专用的端口;采用AXI4-Lite接口和AXI4-Stream接口,支持简单的握手机制去控制数据流;支持可编程的Source ID,支持16-bit的device IDs(可选)。缓冲层(Buffer)支持8,16和32包的独立可配置的TX和RX Buffer深度;支持独立的时钟,支持可选的发送数据流控制。物理层(Physical Layer)支持可配置的空闲序列1和空闲序列2;支持关键请求流(Critical Request Flow);支持多播事件。
IP核中罗列出来了这些操作,我想,只要把这些类型的操作都熟悉了,这个IP核也就能玩转了
Port I/O Style:I/O接口可以配置为Condensed I/O和Initiator/Target两种类型。其中Condensed I/O接收和发送均使用一个AXI4-Stream通道。Initiator/Target接收和发送采用不同的AXI4-Stream通道。
I/O Format:I/O端口能被配置使用HELLO格式包或SRIO Stream格式包,一般情况下,强烈推荐使用HELLO格式
Messaging:用来选择消息事务的端口,可选的参数有Combined with IO和Separate Messaging Port两种。Combined with IO选项表明消息事务和I/O写事务采用相同的IO端口,Separate Messaging Port选项表明消息事务采用一个独立的端口传输,选中这个选项以后IP核会出现消息事务的AXI4-Stream通道。
Maintainance:用来选择维护端口类型,维护端口类型只能为AXI4-Lite类型。
本地设备(Local Device)生成的请求(Requests)通过ireq通道发送,远程设备(Remote Device)产生的响应包通过iresp通道接收来完成整个事务的交互过程。 远程设备(Remote Device)生成的请求(Requests)通过treq通道接收,本地设备(Local Device)产生的响应包通过tresp通道发送来完成整个事务的交互过程。
在顶层模块中,变量名与通道的对应关系如下:
s_axis_ireq* 对应于ireq通道
m_axis_iresp* 对应于iresp通道
m_axis_treq* 对应于treq通道
s_axis_tresp* 对应于tresp通道
请求和响应的信号流示意图,因为对于我这个初学者而言,这几个端口总是有点搞混,因此需要下面这个示意图,每次搞不清楚信号流从哪个端口到哪个端口的时候,就可以找出来看看
例如 如果是一个只有请求没有响应的事物的话,信号流就是:
ireq --------> treq
如果是一个需要响应的请求事物的话,信号流就是:
ireq --------> treq ,然后构造 tresp --------> iresp
HELLO包格式(重点)
为了简化RapidIO包的构建过程,RapidIO核的事务传输接口(ireq,treq,iresp,tresp)可以配置为HELLO(Header Encoded Logical Layer Optimized)格式。这种格式把包的包头(Header)域进行标准化,而且把包头和数据在接口上分开传输,这将简化控制逻辑并且允许数据与发送边界对齐,有助于数据的管理。
HELLO格式的包如下图所示
整片文章的重点只有一个,就是设计指南那一节所提到的HELLO格式与HELLO格式的时序,强烈建议对照pg007_srio_gen2.pdf文档多读几遍。 事实上,在编写Verilog代码时,就是先根据事务类型组装对应的HELLO格式的包头(Header),然后按照HELLO格式的时序,在第一个有效时钟周期类把包头(Header)发出去,后面几个有效的时钟周期发送你的数据。在这个过程中,RapidIO核会自动把HELLO格式的包转化为标准的RapidIO串行物理层的包,并添加控制符号,空闲序列等必要信息发出去,接收过程则正好相反,RapidIO核接收到标准的RapidIO串行物理层的包,控制符号,空闲序列等信息后以后,会把接收的信息转化为HELLO格式的包给用户做后续处理。所以对用户来说只需要理解HELLO格式包的组成与HELLO格式的时序就可以利用RapidIO核实现数据的高速传输,而不需要关注RapidIO协议的过多细节。