20210803:AXI-Stream协议源码分析初探

简要说明

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

交互握手过程简述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

源码分析

  1. 主设备关键源码分析

首先关注我们的主机接口

		// Global ports
		input 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: Clock
		input wire  S_AXIS_ACLK,
		// AXI4Stream sink: Reset
		input wire  S_AXIS_ARESETN,
		// Ready to accept data in
		output wire  S_AXIS_TREADY,
		// Data in
		input wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA,
		// Byte qualifier
		input wire [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB,
		// Indicates boundary of last packet
		input wire  S_AXIS_TLAST,
		// Data is in valid
		input 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 FIFO
	parameter [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 implementation
	always @(posedge S_AXIS_ACLK) 
	begin  
	  if (!S_AXIS_ARESETN) 
	  // Synchronous reset (active low)
	    begin
	      mst_exec_state <= IDLE;
	    end  
	  else
	    case (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)
	            begin
	              mst_exec_state <= WRITE_FIFO;
	            end
	          else
	            begin
	              mst_exec_state <= IDLE;
	            end
	      WRITE_FIFO: 
	        // When the sink has accepted all the streaming input data,
	        // the interface swiches functionality to a streaming master
	        if (writes_done)
	          begin
	            mst_exec_state <= IDLE;
	          end
	        else
	          begin
	            // The sink accepts and stores tdata 
	            // into FIFO
	            mst_exec_state <= WRITE_FIFO;
	          end

	    endcase
	end

最后当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)
	begin
	  if(!S_AXIS_ARESETN)
	    begin
	      write_pointer <= 0;
	      writes_done <= 1'b0;
	    end  
	  else
	    if (write_pointer <= NUMBER_OF_INPUT_WORDS-1)
	      begin
	        if (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;
	          end
	          if ((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;
	            end
	      end  
	end

TestBench测试

注意到我们只需要进行复位和置位操作即可开启此次传输。
在这里插入图片描述
主要激励代码:

    initial begin
        sys_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
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实现将AXI4协议数据转换为AXI-Stream协议数据的过程可以通过以下步骤进行: 1. AXI4协议数据格式(如地址、数据、控制信号等)与AXI-Stream协议数据格式(仅有数据信号)存在差异,在转换过程中需要对数据进行重新组织和调整。 2. 首先,从AXI4总线上接收到的数据包括地址信号、数据信号和控制信号。其中,地址信号指示要访问的AXI4设备的具体位置,数据信号包含要传输的实际数据,而控制信号则指示操作类型和传输方向。 3. 在数据转换模块中,需要将接收到的AXI4数据进行解析和分离。根据AXI4协议规范,地址信号和数据信号以及控制信号之间存在对应关系。通过解析控制信号,可以确定要进行的操作类型,如读取或写入。 4. 根据控制信号的类型(读取或写入),确定在AXI-Stream数据中要设置的有效位(Valid)标志。对于写入操作,需要将有效位设置为高电平,以指示有新的数据要传输。对于读取操作,有效位设置为低电平,以指示无新的数据传输。 5. 组织被选中的数据(根据控制信号的读取或写入操作类型),并以AXI-Stream协议的格式进行处理和编码。AXI-Stream协议仅包含数据信号,没有地址信号和控制信号。 6. 在AXI-Stream数据中,根据AXI4数据的信息,包含数据位(data)以及标志位(valid)。有效位标志(valid)在数据有效时设置为高电平,以表明数据位(data)是有效的。 7. 最后,将转换后的AXI-Stream数据发送到AXI-Stream总线上,以供其他支持该协议的设备使用。 通过以上步骤,可以将AXI4协议数据转换为AXI-Stream协议数据,实现不同协议之间的数据交互和传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IMMUNIZE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值