AXI-Stream协议细读

  • 简要说明
  • 交互握手过程简述
  • 源码分析
  • TestBench测试
  • 写在最后
  • 参考资料

简要说明

  1. 不同于AXI和AXI-lite协议,AXI-Stream协议不是基于地址的数据交互协议,如其名,数据流协议。
  2. 支持多个主从端之间通过同一个通路进行交互。
  3. 支持常规数据流,位置数据流,以及填充数据流的传输。

交互握手过程简述



上面三个图为交互过程的TVALID和TREADY的顺序不同时,数据流INFORMATION随始终ACLK的传输过程。需要注意的点如下:

  1. 注意TVALID是Master设备发出的信号,当TVALID拉高时,数据流必须保持不变。等待从设备的TREADY信号拉高,表示从设备已经可以接受数据流了。注意我们的数据是跟随TVALID来表示当前数据有效的。

源码分析

  1. 主设备关键源码分析

首先关注我们的主机接口

     // Global portsinput wire  M_AXIS_ACLK,// input wire  M_AXIS_ARESETN,// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. output wire  M_AXIS_TVALID,// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,// TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte.output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,// TLAST indicates the boundary of a packet.output wire  M_AXIS_TLAST,// TREADY indicates that the slave can accept a transfer in the current cycle.input wire  M_AXIS_TREADY

注意看到关键握手信号即可。

// Define the states of state machine                                                // The control state machine oversees the writing of input streaming data to the FIFO,// and outputs the streaming data from the FIFO                                      parameter [1:0] IDLE = 2'b00,        // This is the initial/idle state               INIT_COUNTER  = 2'b01, // This state initializes the counter, once   // the counter reaches C_M_START_COUNT count,        // the state machine changes state to SEND_STREAM     SEND_STREAM   = 2'b10; // In this state the                          // stream data is output through M_AXIS_TDATA

再次是状态机的转移。分为原始状态,发送计数状态,发送状态。

// Control state machine implementation                             always @(posedge M_AXIS_ACLK)                                             begin                                                                     if (!M_AXIS_ARESETN)                                                    // Synchronous reset (active low)                                       begin                                                                 mst_exec_state <= IDLE;                                             count    <= 0;                                                      end                                                                   else                                                                    case (mst_exec_state)                                                 IDLE:                                                               // The slave starts accepting tdata when                          // there tvalid is asserted to mark the                           // presence of valid streaming data                               //if ( count == 0 )                                                 //  begin                                                           mst_exec_state  <= INIT_COUNTER;                              //  end                                                             //else                                                              //  begin                                                           //    mst_exec_state  <= IDLE;                                      //  end                                                             INIT_COUNTER:                                                       // The slave starts accepting tdata when                          // there tvalid is asserted to mark the                           // presence of valid streaming data                               if ( count == C_M_START_COUNT - 1 )                               begin                                                           mst_exec_state  <= SEND_STREAM;                               end                                                             else                                                              begin                                                           count <= count + 1;                                           mst_exec_state  <= INIT_COUNTER;                              end                                                             SEND_STREAM:                                                        // The example design streaming master functionality starts       // when the master drives output tdata from the FIFO and the slave// has finished storing the S_AXIS_TDATA                          if (tx_done)                                                      begin                                                           mst_exec_state <= IDLE;                                       end                                                             else                                                              begin                                                           mst_exec_state <= SEND_STREAM;                                end                                                             endcase                                                               end

注意到这个过程非常简单。进入计数状态后只要计数未结束就进入发送状态。
最后关注接口提到的flag信号和发送的数据信号即可。

flag信号:

//tvalid generation//axis_tvalid is asserted when the control state machine's state is SEND_STREAM and//number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS.assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < NUMBER_OF_OUTPUT_WORDS));// AXI tlast generation                                                                        // axis_tlast is asserted number of output streaming data is NUMBER_OF_OUTPUT_WORDS-1          // (0 to NUMBER_OF_OUTPUT_WORDS-1)                                                             assign axis_tlast = (read_pointer == NUMBER_OF_OUTPUT_WORDS-1);

数据信号:

//FIFO read enable generation assign tx_en = M_AXIS_TREADY && axis_tvalid;   // Streaming output data is read from FIFO       always @( posedge M_AXIS_ACLK )                  begin                                            if(!M_AXIS_ARESETN)                            begin                                        stream_data_out <= 1;                      end                                          else if (tx_en)// && M_AXIS_TSTRB[byte_index]  begin                                        stream_data_out <= read_pointer + 32'b1;   end                                          end

即发送数据为我们的read_pointer指针依次往后计数到last为止。
2. 从设备关键源码分析
依旧先关注接口信号

// AXI4Stream sink: Clockinput wire  S_AXIS_ACLK,// AXI4Stream sink: Resetinput wire  S_AXIS_ARESETN,// Ready to accept data inoutput wire  S_AXIS_TREADY,// Data ininput wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA,// Byte qualifierinput wire [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB,// Indicates boundary of last packetinput wire  S_AXIS_TLAST,// Data is in validinput wire  S_AXIS_TVALID

注意到TVALID和TREADY的方向问题。
从设备的状态机定义如下:

// Define the states of state machine// The control state machine oversees the writing of input streaming data to the FIFO,// and outputs the streaming data from the FIFOparameter [1:0] IDLE = 1'b0,        // This is the initial/idle state WRITE_FIFO  = 1'b1; // In this state FIFO is written with the// input stream data S_AXIS_TDATA

其转移关系为:当TVALID拉高时,即可往FIFO中写入数据。

// Control state machine implementationalways @(posedge S_AXIS_ACLK) begin  if (!S_AXIS_ARESETN) // Synchronous reset (active low)beginmst_exec_state <= IDLE;end  elsecase (mst_exec_state)IDLE: // The sink starts accepting tdata when // there tvalid is asserted to mark the// presence of valid streaming data if (S_AXIS_TVALID)beginmst_exec_state <= WRITE_FIFO;endelsebeginmst_exec_state <= IDLE;endWRITE_FIFO: // When the sink has accepted all the streaming input data,// the interface swiches functionality to a streaming masterif (writes_done)beginmst_exec_state <= IDLE;endelsebegin// The sink accepts and stores tdata // into FIFOmst_exec_state <= WRITE_FIFO;endendcaseend

最后当FIFO收到主设备发送的数据的数量时,表示写入完成。

// The example design sink is always ready to accept the S_AXIS_TDATA  until// the FIFO is not filled with NUMBER_OF_INPUT_WORDS number of input words.assign axis_tready = ((mst_exec_state == WRITE_FIFO) && (write_pointer <= NUMBER_OF_INPUT_WORDS-1));always@(posedge S_AXIS_ACLK)beginif(!S_AXIS_ARESETN)beginwrite_pointer <= 0;writes_done <= 1'b0;end  elseif (write_pointer <= NUMBER_OF_INPUT_WORDS-1)beginif (fifo_wren)begin// write pointer is incremented after every write to the FIFO// when FIFO write signal is enabled.write_pointer <= write_pointer + 1;writes_done <= 1'b0;endif ((write_pointer == NUMBER_OF_INPUT_WORDS-1)|| S_AXIS_TLAST)begin// reads_done is asserted when NUMBER_OF_INPUT_WORDS numbers of streaming data // has been written to the FIFO which is also marked by S_AXIS_TLAST(kept for optional usage).writes_done <= 1'b1;endend  end

TestBench测试

注意到我们只需要进行复位和置位操作即可开启此次传输。

主要激励代码:

    initial beginsys_clk_i = 0;sys_rst_n = 0;#40 sys_rst_n = 1;end

波形图如下,当复位之后,进行数据1到8的传输,到第八个数据时TLAST拉高一次:

写在最后

到此,我们完成了对AXI-Stream源码的一个初步了解。想进一步了解学习参见ARM
官方协议资料。(直接复制全名称百度即可获得)

参考资料

  1. IHI0051A_amba4_axi4_stream_v1_0_protocol_spec.pdf

20210803:AXI-Stream协议源码分析初探相关推荐

  1. 透视RPC协议:SOFA-BOLT协议源码分析

    前提 最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现. ...

  2. Bancor协议源码分析

    1.编译源码.运行测试脚本 pull Bancor源码到当前目录. 在当前目录执行npm install 安装依赖的包 进入scripts目录,修改三个js文件中前面几行代码中的相对路径,如" ...

  3. Godot 4 源码分析 - 初探

    准备研究GoDot 4源码. 源码下载 获取源代码 在进入 SCons 构建系统并编译 Godot 之前,你需要将 Godot 的源代码下载到本地. 源代码位于 GitHub 上, 虽然你可以通过网站 ...

  4. Linux TCP/IP网络协议栈:IP协议源码分析

    目录 IP协议简介 IP头部 IP数据包的发送 IP数据包的接收 https://mp.weixin.qq.com/s/8WNcTxtD4DBcNtcrR8nz4Q IP协议 是网络的最重要部分,毫不 ...

  5. 蓝牙avrcp协议源码分析

    原址:http://blog.csdn.net/u012439416/article/details/54348147 1,概述 1.1 avrcp协议 全称: Audio / Video Remot ...

  6. 蓝牙a2dp协议源码分析

    1,a2dp协议 1.1 a2dp协议 全称:Advanced Audio Distribution Profile 蓝牙音频传输协议 使用场景:主要是通过蓝牙将声音从一个设备传输到另一个设备. 市场 ...

  7. zrender源码分析--初探

    先看下,本次例子做的效果 然后开始代码: 调用init接口初始化 // zrender_demo.html var zr = zrender.init(document.getElementById( ...

  8. go-ethereum-code-analysis 以太坊源码分析

    分析go-ethereum的过程,我希望从依赖比较少的底层技术组件开始,慢慢深入到核心逻辑. 目录 go-ethereum代码阅读环境搭建 以太坊黄皮书 符号索引 rlp源码解析 trie源码分析 e ...

  9. srs源码分析3-srs的启动

    本文分析的srs版本是0.6.0 srs源码分析1-搭建环境 srs源码分析2-浅析state_threads srs源码分析3-srs的启动 srs源码分析4-客户端的连接 srs源码分析5-han ...

最新文章

  1. linux mint 屏保_Linux Mint 修复了两个孩子发现的屏保锁定绕过漏洞
  2. 20年第三次架构大调整,腾讯永远年轻!
  3. Oracle 11g sys,system 密码忘记设置解决办法
  4. linux 多进程 多线程的选择
  5. Shell之系统函数和自定义函数
  6. 阿里云服务器 ,MySQL建库、建表
  7. [蓝桥杯]算法提高 vertex cover(dfs)
  8. ffmpeg rtp传输使用
  9. 【OCR一】字符识别技术总览(转)
  10. ALGO-84 大小写转换
  11. MySQL之MHA架构的介绍
  12. java计算机毕业设计网上书店进销存管理系统源程序+mysql+系统+lw文档+远程调试
  13. MQTT服务器的搭建与MQTT客户端的使用
  14. 莫烦 Python 基础
  15. 《亲密关系》读书笔记
  16. 搭建一个 软件授权码管理系统
  17. 读《天才在左,疯子在右》01--偷取时间
  18. 如何下载央视网视频,下载视频播放花屏怎么办
  19. 使用Apache搭建Web网站服务器
  20. 利用子集构造法实现NFA到DFA的转换

热门文章

  1. 程序员躲不掉的“中年危机”
  2. 程序员VS产品经理日常
  3. 158 行 Python 代码,复现 DeepMind 递归神经网络 DRAW!
  4. 移动开发的跨平台技术发展史 | 技术头条
  5. @程序员,解读 5G 中性命攸关的时延! | 技术头条
  6. Google 作恶!99.9% 的 Android 手机 App 都在窃取隐私
  7. 程序员们,你知道面试官是如何考察你的软素质吗?
  8. ======第一章操作系统引论======
  9. JAVA day18,19 单列集合Collection:List(ArrayList,LinkedList,Vector)、Queue(Deque)、Set(HashSet,TreeSet),比较器
  10. 50个经典jquery实例_【电气知识】从原理图到程序的4个经典实例详解