本文是AXI-Stream IP调试日记的终结篇。
看到这里,可能大家都还对Stream没有一个直观的认识。其实Stream并不陌生,在我们学c++编程时,一定会包含,这样就可以完成控制终端对程序的输入输出了。如果还是不够直观,想象一下水流,是连续不断的,向某一方向,以固定的速度输送的接口。以我们看视频为例,视频文件本来是保存在硬盘里的,怎么播放呢,不能一下子把整个文件都显示到屏幕上,而是以一定速度,连续不断地输出到屏幕上(每秒若干帧),这个过程就是流Stream接口完成的。
Xilinx提供的流式IP核有很多用途,可以实现音频流、视频流、数据流到内存或者相反方向的传输。有人问了,内存是PS控制的,怎么才能把PS里DDR2的内容以Stream形式发出去呢(例如以固定速度送往DA,完成信号发生器的设计)?答案就是利用AXI总线做转换。ZYNQ的PS部分是ARM Cortex A9系列,支持AXI4,AXI-Lite总线。PL部分也有相应AXI总线接口,这样就能完成PS到PL的互联。仅仅这样还不够,需要PL部分实现流式转换,即AXI-Stream接口实现。Xilinx提供的从AXI到AXI-Stream转换的IP核有:AXI-DMA,AXI-Datamover,AXI-FIFO-MM2S以及AXI-vDMA等。这些IP核可以在XPS中看到。
这里要和大家说明白一点,就是AXI总线和接口的区别。总线是一种标准化接口,由数据线、地址线、控制线等构成,具有一定的强制性。接口是其物理实现,即在硬件上的分配。在ZYNQ中,支持AXI-Lite,AXI4和AXI-Stream三种总线,但PS与PL之间的接口却只支持前两种,AXI-Stream只能在PL中实现,不能直接和PS相连,必须通过AXI-Lite或AXI4转接。PS与PL之间的物理接口有9个,包括4个AXI-GP接口和4个AXI-HP接口、1个AXI-ACP接口。
AXI-DMA:实现从PS内存到PL高速传输高速通道AXI-HPAXI-Stream的转换
AXI-FIFO-MM2S:实现从PS内存到PL通用传输通道AXI-GPAXI-Stream的转换
AXI-Datamover:实现从PS内存到PL高速传输高速通道AXI-HPAXI-Stream的转换,只不过这次是完全由PL控制的,PS是完全被动的。
AXI-VDMA:实现从PS内存到PL高速传输高速通道AXI-HPAXI-Stream的转换,只不过是专门针对视频、图像等二维数据的。
除了上面的还有一个AXI-CDMA IP核,这个是由PL完成的将数据从内存的一个位置搬移到另一个位置,无需CPU来插手。这个和我们这里用的Stream没有关系,所以不表。
上面的IP是完成总线协议转换,如果需要做某些处理(如变换、迭代、训练……),则需要生成一个自定义Stream类型IP,与上面的Stream接口连接起来,实现数据输入输出。用户的功能在自定义Stream类型IP中实现。
下面讲一个例子,来加深对上面介绍内容的理解。
软件:ISE 14.2
1.先建立PlanAhead工程,一直做到进入XPS,具体流程见官方文档CTT。
2.在XPS中,添加一个AXI-DMA模块,配置界面如下图所示
其余参数默认。SG模块如果选上,那么后面软件控制会相对复杂一些。这里不选,采用Simple模式。
3.选菜单Hardware->Create or Import Peripheral。。。,设计自定义IP。名称起为my_stream_ip,自动版本为1.00a。遇到Bus Interface选择AXI4-Stream类型,一直点下一步到最后结束。该类型IP的生成过程比AXI4-Lite和AXI4都要简单。
4.添加一个my_stream_ip到系统中,连接图见下。
my_stream_ip实现了先接受8个字的数据,求和,然后将和发送回去(发送8次)。上图连接方式说明是AXI-DMA发送给my_stream_ip,然后my_stream_ip又发回AXI-DMA。同时看到AXI-DMA和PS连接是通过HP0传输数据,由GP0控制其传输的进行。
5.以上连接是有问题的(主要是XPS的bug),需要一项项修改。
首先是HP0的地址区间报错,可以先点Zynq标签,然后单击HP0绿线,在弹出的配置对话框中将HP0的地址区间改为我们ZED Board 上DDR2区间 0x00000000~0x1FFFFFFF,像下图这样:
在高版本ISE14.5中,这个bug已经修复,不需要改。
之后就是AXI-DMA和my_stream_ip的连线问题。本来都是Stream 接口,按理说是标准接口,不应该有差异。但事实就是这样,XPS界面掩饰之下,问题层出不穷。我们右击my_stream_ip&#x