在本文中,你将可能学会:
本来想讲完怎么接入的,由于篇幅的原因,代码只能留在下一节中讲了,那我们下一节也顺便为这个系列做个简单的收尾吧。
终于介绍到AXI4中的最后一个协议了,AXI-Stream顾名思义是用来传输数据流的,如图像输入,高速AD等。如果有接触过的朋友应该知道,这种数据流的处理一般是和DMA一并使用的,那么也就会有一个叫做内存映射(Memory Mapping)的问题,一般会对数据的位宽(对齐),流传输方式比较敏感,反而对地址,读写上比较无所谓(因为这个基本由DMA控制)。
所以相较于AXI-FULL,AXIS有以下的改动,接口上:
功能性上:
此时我们来看看总体的端口表(主端,即发送端):
对比AXI-FULL,握手啥的我们就不讲了,下面需要介绍的有:
由于取消了地址这个概念,所以这里引入了一个“路由”的概念提示当前数据应该送到哪去,
其中:
实际上,这两个功能xilinx的ip也没有实现,所以我们这里就不过多介绍了
在AXIS中,定义了三种流数据字节:
其中,位置字节和空字节最大的差别就是他们能不能被删除,正如上文中提到,我们这些AXIS的数据一般都是后接DMA的,对于内存的写入位宽对齐尤为重要,下看AXIS中的三种数据流:
字节流是传输多个数据和空字节。 在每个TVALID,TREADY握手,可以传输任何数量的数据字节。 null字节没有含义,可以从流中插入或删除。
在图中,每个垂直列表示单个传输中的字节,使用4字节宽数据总线。
这个就是就喜闻乐见的情况了,没有任何Position byte和Null byte,数据本身就是对齐的,可以直接拉进内存。
这里也是一样,每次传4个Byte。
这里就相当于,数据包只有18B,但是对齐需要20B/24B,这个时候就需要引入占位字节:
这里的Position Byte可以在传输的开头或者结尾给出,以存进内存的时候位宽对齐。
这个就是连续不对齐流的推广,它允许数据流的中间也有占位字节,区分就靠你是怎么定义的了。
在AXI-FULL中,我们可以通过WSTRB来分开有效数据和无效数据,但现在又多了占位字节,所以相应地协议多了TKEEP信号,具体规则如下:
这个跟AXI-FULL是一致的,都是用tlast来指示到这一包的的接收了。但是在一些二维数据(比如图像)中,就必须再引入一条指示线,以Xilinx家出名的VDMA为例,他们的行结束(end of line)是用 tlast来指示的,而帧开始(start of frame)是用tuser的第一位指示的(一般用法,还可以多加一条fsync),见手册:
这个是大家可能看我上面的端口表感觉不对劲,或许多了些端口或少了些,这是因为这个协议是允许较大程度的自定义(省略)的:
Most applications of the AXI4-Stream interface will transfer a data payload. However, it is allowable to implement an interface that does not have a TDATA data payload.
TID, TDEST, and TUSER are all optional signals on the interface
简单来说,反压即入口流量大于出口流量,系统处理能力跟不上数据进来的速度,对多级流水线而言,处理能力越慢的那级就会使前面的流水线动弹不得(降速),导致链路速率下降,我们举一个简单例子:
现在我们来处理这么一个材料生产流程:
当前链路带宽为16/s,可见已达链路最大输入带宽,而一级处理速率为8,由于需要双通道输入,故每种染料需要16/s,证明一级流水线满速运行!
可见此时多加了一台合并机在一级合并中,各个速率就达到了一致。
回到AXIS中,所以取不取消tready信号,即:
assign axis_ready = 1'b1; // -> 你使点劲来数据啊.jpg
得从两个角度看问题:
当然,这不代表他们就去掉tready信号了,因为达到吞吐量上限了他们也依然会进行反压。
以一个行扫描的摄像头输入为例,输入信号有:
所以我们要解决的问题和处理的基本思路有:
在下一篇中有一个更有趣的现象就是,摄像头输入的物理位宽和像素格式位宽还不对齐,这又要解决呢?
欲知后事如何,且听下回分解。
在本节中,主要介绍了AXI-Stream,AXI4家族的最后一个成员,
和小何为了解释反压问题而买了个游戏,专门挑了这么个例子。
所以给个关注吧观众老爷们:
Xilinx-VDMA官方手册PG020
ARM-AXI-Stream官方手册
异形世界