UISRC工程师开源站

标题: 米联客-XILINX-H3_CZ08_7100] FPGA_AXI总线入门连载-05AXI4 总线 axi-stream [打印本页]

作者: UT发布    时间: 2024-10-14 18:20
标题: 米联客-XILINX-H3_CZ08_7100] FPGA_AXI总线入门连载-05AXI4 总线 axi-stream
​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1概述
AXI4-Stream去掉了地址,允许无限制的数据突发传输规模,AXI4-Stream接口在数据流传输中应用非常方便,本来首先介绍了AXI4-Stream协议的型号定义,并且给出了一些Stream接口的时序方案图。之后通过VIVADO自带的AXI4模板,创建axi-stream-master和axi-stream-slave ip。通过图形设计连线,添加仿真激励完成验证。
本文实验目的:
1:掌握基于VIVADO工具产生AXI协议模板
2:掌握通过VIVADO工具产生AXI-Stream代码
3:掌握通过VIVADO封装AXI-Stream图形化IP
4:通过仿真验证AXI-Stream IP的工作是否正常。
2AXI4-Stream协议介绍
2.1信号定义
                        
信号
                        
                        
                        
                        
描述
                        
                        
ACLK
                        
                        
时钟源
                        
                        
信号在ACLK信号上升沿采样
                        
                        
ARESETn
                        
                        
复位源
                        
                        
复位信号,ARESETn低电平有效
                        
                        
TVALID
                        
                        
master
                        
                        
TVALID代表主设备数据有效,当TVALID和TREADY同时有效完成数据收发
                        
                        
TREADY
                        
                        
slave
                        
                        
TREADY表示从设备准备可以,主设备可以发送数据,当TVALID和TREADY同时有效完成数据收发
                        
                        
TDATA[(8n-1):0]
                        
                        
master
                        
                        
TDATA axi-stream的数据
                        
                        
TSTRB[(n-1):0]
                        
                        
master
                        
                        
TSTRB[n-1:0]对应的bit位为1代表对应的字节有效,否则无效,但是会占用这个数据位。
                        
                        
TKEEP[(n-1):0]
                        
                        
master
                        
                        
KEEP[n-1:0]对应的bit位为1代表对应的字节有效,否则为空,可以丢掉。
                        
                        
TLAST
                        
                        
master
                        
                        
TLAST代表最后一个数据。
                        
                        
TID[(i-1):0]
                        
                        
master
                        
                        
TID是数据流的标识符,用来表明不同的数据流。
                        
                        
TDEST[(d-1):0]
                        
                        
master
                        
                        
TDEST为据流提供路由信息。
                        
                        
TUSER[(n-1):0]
                        
                        
master
                        
                        
TUSER一般用于数据的同步,代表stream数据的开始。
                        
以上所有信号,在axi-stream传输中,不一定全部用到,具体根据应用场景的情况而定。
2.2axi-stream方案展示
下图中除了ACLK外,axi-stream的信号用到了,TVALID、TREADY、TLAST、TDATA。其中TDATA虽然是12bit但是实际上会占用16bit的物理总线。并且数据是循环发送,用TLAST标识了一次循环的最后一个数据。
(, 下载次数: 231)
下图中截图来自AXI-DMA mm2s接口的时序图,除了ACLK外,axi-stream的信号用到了,TVALID、TREADY、TLAST、TDATA、TKEEP。用TLAST标识了一次循环的最后一个数据。
(, 下载次数: 260)
下图中是来自于xilinx vivado自带的axis_vid_out ip的视频输出时序。EOL就是tlast ,SOF就是tuser初次外还包括了VALID、READY、DATA信号。
(, 下载次数: 240)
3创建axi-stream-slave总线接口IP
新建fpga工程,过程省略
(, 下载次数: 255)
(, 下载次数: 213)
(, 下载次数: 241)
(, 下载次数: 234)
(, 下载次数: 239)
(, 下载次数: 237)
4创建axi-stream-master总线接口IP
未来完成axi-steam协议的验证,采用以上方法,我们再创建一个saxis的IP
(, 下载次数: 209)
(, 下载次数: 242)
(, 下载次数: 213)
创建完成后如下图所示
(, 下载次数: 223)
5创建FPGA图像化设计
(, 下载次数: 243)
设置IP路径
(, 下载次数: 226)

(, 下载次数: 236)
添加已经创建好的IP
(, 下载次数: 241)
输入关键词axis,在最后可以看到,双击添加Ip
(, 下载次数: 213)
(, 下载次数: 238)
完成连线
(, 下载次数: 219)

maxis的ip参数设置
(, 下载次数: 217)
saxis的ip参数设置
(, 下载次数: 242)
自动创建顶层文件
(, 下载次数: 235)
(, 下载次数: 236)
6创建仿真文件
(, 下载次数: 231)

(, 下载次数: 235)
(, 下载次数: 213)
仿真程序非常简单,只要提供时钟和复位信号
  1. `timescale 1ns / 1ns
  2. module axis_top_sim();
  3. reg m00_axis_aclk_0;
  4. reg m00_axis_aresetn_0;   
  5. system_wrappertem system_wrapper_inst
  6.     (
  7.     .m00_axis_aclk_0(m00_axis_aclk_0),  
  8.     .m00_axis_aresetn_0(m00_axis_aresetn_0)
  9.     );   
  10. initial begin
  11.     m00_axis_aclk_0  = 1'b0;
  12.     m00_axis_aresetn_0 = 1'b0;
  13.     #100;
  14.     m00_axis_aresetn_0 = 1'b1;
  15. end
  16. always
  17.     begin
  18.         #5 m00_axis_aclk_0 = ~m00_axis_aclk_0;
  19.     end        
  20. endmodule
复制代码

7程序分析
默认的maxis模板的代码有bug,我们对其进行修改。
1:把以下代码替换默认的代码并且保存
  1. `timescale 1 ns / 1 ps
  2.     module maxis_v1_0_M00_AXIS #
  3.     (
  4.         // Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH.
  5.         parameter integer C_M_AXIS_TDATA_WIDTH  = 32,
  6.         // Start count is the number of clock cycles the master will wait before initiating/issuing any transaction.
  7.         parameter integer C_M_START_COUNT   = 32
  8.     )
  9.     (
  10.         // Global ports
  11.         input wire  M_AXIS_ACLK,
  12.         //
  13.         input wire  M_AXIS_ARESETN,
  14.         // Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted.
  15.         output wire  M_AXIS_TVALID,
  16.         // TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.
  17.         output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,
  18.         // 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.
  19.         output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,
  20.         // TLAST indicates the boundary of a packet.
  21.         output wire  M_AXIS_TLAST,
  22.         // TREADY indicates that the slave can accept a transfer in the current cycle.
  23.         input wire  M_AXIS_TREADY
  24.     );
  25.     // Total number of output data                                                
  26.     localparam NUMBER_OF_OUTPUT_WORDS = 8;                                               
  27.                                                                                          
  28.     // function called clogb2 that returns an integer which has the                     
  29.     // value of the ceiling of the log base 2.                                          
  30.     function integer clogb2 (input integer bit_depth);                                   
  31.       begin                                                                              
  32.         for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                                      
  33.           bit_depth = bit_depth >> 1;                                                   
  34.       end                                                                                
  35.     endfunction                                                                          
  36.                                                                                          
  37.     // WAIT_COUNT_BITS is the width of the wait counter.                                 
  38.     localparam integer WAIT_COUNT_BITS = clogb2(C_M_START_COUNT-1);                     
  39.                                                                                          
  40.     // bit_num gives the minimum number of bits needed to address 'depth' size of FIFO.  
  41.     localparam bit_num  = clogb2(NUMBER_OF_OUTPUT_WORDS);                                
  42.                                                                                          
  43.     // Define the states of state machine                                                
  44.     // The control state machine oversees the writing of input streaming data to the FIFO,
  45.     // and outputs the streaming data from the FIFO                                      
  46.     parameter [1:0] IDLE = 2'b00,        // This is the initial/idle state               
  47.                                                                                          
  48.                     INIT_COUNTER  = 2'b01, // This state initializes the counter, once   
  49.                                     // the counter reaches C_M_START_COUNT count,        
  50.                                     // the state machine changes state to SEND_STREAM     
  51.                     SEND_STREAM   = 2'b10; // In this state the                          
  52.                                          // stream data is output through M_AXIS_TDATA   
  53.     // State variable                                                                    
  54.     reg [1:0] mst_exec_state;                                                            
  55.     // Example design FIFO read pointer                                                  
  56.     reg [bit_num-1:0] read_pointer;                                                      

  57.     // AXI Stream internal signals
  58.     //wait counter. The master waits for the user defined number of clock cycles before initiating a transfer.
  59.     reg [WAIT_COUNT_BITS-1 : 0]     count;
  60.     //streaming data valid
  61.     wire    axis_tvalid;
  62.     //Last of the streaming data
  63.     wire    axis_tlast;
  64.     wire    tx_en;
  65.     //The master has issued all the streaming data stored in FIFO
  66.     wire    tx_done;

  67.     // I/O Connections assignments
  68.     assign M_AXIS_TVALID    = axis_tvalid;
  69.     assign M_AXIS_TDATA = read_pointer;
  70.     assign M_AXIS_TLAST = axis_tlast;
  71.     assign M_AXIS_TSTRB = {(C_M_AXIS_TDATA_WIDTH/8){1'b1}};

  72.     // Control state machine implementation                             
  73.     always @(posedge M_AXIS_ACLK)                                             
  74.     begin                                                                     
  75.       if (!M_AXIS_ARESETN)                                                   
  76.       // Synchronous reset (active low)                                       
  77.         begin                                                                 
  78.           mst_exec_state <= IDLE;                                             
  79.           count    <= 0;                                                      
  80.         end                                                                  
  81.       else                                                                    
  82.         case (mst_exec_state)                                                
  83.           IDLE:                                                                                                            
  84.             mst_exec_state  <=                                                                                                                                    
  85.           INIT_COUNTER:                                                      
  86.             // The slave starts accepting tdata when                          
  87.             // there tvalid is asserted to mark the                           
  88.             // presence of valid streaming data                              
  89.             if ( count == C_M_START_COUNT - 1 )                              
  90.               begin                                                           
  91.                 mst_exec_state  <= SEND_STREAM;                              
  92.               end                                                            
  93.             else                                                              
  94.               begin                                                           
  95.                 count <= count + 1;                                          
  96.                 mst_exec_state  <= INIT_COUNTER;                              
  97.               end                                                            
  98.                                                                               
  99.           SEND_STREAM:                                                        
  100.             // The example design streaming master functionality starts      
  101.             // when the master drives output tdata from the FIFO and the slave
  102.             // has finished storing the S_AXIS_TDATA                          
  103.             if (tx_done)                                                      
  104.               begin                                                           
  105.                 mst_exec_state <= IDLE;                                       
  106.               end                                                            
  107.             else                                                              
  108.               begin                                                           
  109.                 mst_exec_state <= SEND_STREAM;                                
  110.               end                                                            
  111.         endcase                                                               
  112.     end                                                                       

  113.     //tvalid generation
  114.     //axis_tvalid is asserted when the control state machine's state is SEND_STREAM and
  115.     //number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS.                        
  116.     assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < NUMBER_OF_OUTPUT_WORDS));
  117.                                                                                                    
  118.     // AXI tlast generation                                                                                                                              
  119.                                                                                                 
  120.     assign axis_tlast = (read_pointer == NUMBER_OF_OUTPUT_WORDS - 1'b1)&& tx_en;  

  121.     assign tx_done = axis_tlast;

  122.     //FIFO read enable generation

  123.     assign tx_en = M_AXIS_TREADY && axis_tvalid;   

  124.         // Streaming output data is read from FIFO      
  125.         always @( posedge M_AXIS_ACLK )                  
  126.         begin                                            
  127.           if(!M_AXIS_ARESETN)                           
  128.             begin                                       
  129.               read_pointer <= 0;                     
  130.             end                                          
  131.           else if (tx_en)
  132.             begin                                       
  133.               read_pointer <= read_pointer + 32'b1;   
  134.             end                                          
  135.         end   

  136.     endmodule
复制代码

2:在Tcl Console中输入reset_project对工程IP复位
(, 下载次数: 251)
3:之后单击Refresh IP Catalog
(, 下载次数: 230)
最后单击upgrade Selected完成更新
(, 下载次数: 244)
在看saxis的源码,这部分代码非常简单
首先是状态机,当S_AXI_TVALID有效,saxis的状态机进入WRITE_FIFO
(, 下载次数: 245)
只要接收的数据小于(write_pointer <= NUMBER_OF_INPUT_WORDS-1)并且saxis状态机是WRITE_FIFO状态机,表示saxis可以接收数据,设置axis_tready==1如下:assign axis_tready = ((mst_exec_state == WRITE_FIFO) && (write_pointer <= NUMBER_OF_INPUT_WORDS-1));
write_pointer 用于写入了多少个数据。
(, 下载次数: 228)
写数据到fifo中
(, 下载次数: 205)
8实验结果
仿真结果
(, 下载次数: 245)









欢迎光临 UISRC工程师开源站 (https://www.uisrc.com/) Powered by Discuz! X3.5