AMBA协议AXI-Stream(协议信号、设计实践)

这篇具有很好参考价值的文章主要介绍了AMBA协议AXI-Stream(协议信号、设计实践)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、AXI-Stream简介

  AXI-Stream(以下简称AXIS)是AMBA协议的AXI协议三个版本中(AXI4-FULL、AXI4-Lite、AXI4-Stream)最简单的一个协议;是AXI4中定义的面向数据流的协议,常用于对数据流的处理,如:

  • 摄像头
  • 高速AD
  • Xilinx的AXI-DMA模块

  在进行SOC设计中需要高速数据传输处理的场合,常常使用AXIS协议;
  AXIS与AXI-FULL的区别:

  • 取消了Address Write/Address Read通道;

  • 取消了反馈响应信号Bresp和Rresp;

  • 半双工,仅能读或者写;

  • 不允许乱序;

  • 无最大突发传输长度;

  • 包含TID信号指示源,TDEST指示目的地;

  • 包括一个用于插入和溢出空字节的TKEEP信号;


二、AXI-Stream端口信号(Master)

  以AXIS主机接口的信号为例,AXIS的信号表如下:
AMBA协议AXI-Stream(协议信号、设计实践)AXIS的所有信号都在ACLK的上升沿被采样;
这里讲解下几个比较重要的信号:
TVALID:TVALID是数据有效信号,若TVALID为高电平,标志着TDATA数据线上的数据是有效的,能够被取走,TVALID信号与TREADY信号是一组握手信号;;
TREADY:TREADY是指从机是否准备好接收数据,若TREADY为高电平,则标志着从机此时已经准备好接收数据,TREADY信号与TVALID信号是一组握手信号;
TDATA:数据通道,位宽可以是8、16、32;当TVALID与TREADY均为高电平(有效)时,TDATA数据被传递;
TLAST:数据流结束信号,当TLAST为高电平时,说明此时传输的数据为数据流的最后一个数据;在Xilinx的AXI-DMA中,TLAST信号可以控制整个数据流传输的结束(当传输过程中TLAST为高,则结束一次DMA传输);

AMBA协议AXI-Stream(协议信号、设计实践)   我们可以发现,本质上AXIS协议也就是握手协议,只不过增加了一个TLAST信号,和一些其他的附带指示其他信息的信号;如TID、TDEST、TUSER等都是用于多级通讯的,在单一数据流方向的系统中,我们只需要关注上述几个重要的信号即可;


三、AXI-Stream数据字节类型和流格式

  • 数据字节(Data Byte):包含在源和目标之间传输的有效信息的数据字节。
  • 占位字节 (Position byte):表示流内部数据字节的相对位置的字节。 这是一个不包含在源和目标之间传输的任何相关数据值的占位符。
  • 空字节(Null byte):不包含任何数据信息的字节或关于流内数据字节的相对位置的任何信息。

字节流
在每次握手之后,可以传输任何数量的数据字节,NULL字节没有含义,可以插入或删除。
AMBA协议AXI-Stream(协议信号、设计实践)连续对齐流
即数据本身就是对其的,可以直接写入内存
AMBA协议AXI-Stream(协议信号、设计实践)连续不对齐流
数据包只有18B,但是对齐需要20B/24B,这个时候就需要引入占位字节:
AMBA协议AXI-Stream(协议信号、设计实践)
稀疏流
允许数据流的中间也有占位符;
AMBA协议AXI-Stream(协议信号、设计实践)不同字节类型指示
AMBA协议AXI-Stream(协议信号、设计实践)可自定义省略的信号:
TID、TDEST、TUSER:自定义,多传输系统中使用
TLAST:常为1或0;
TKEEP和TSTRB:全部为1或0;
TREADY:时刻准备接收,数据反压问题;


四、数据反压

数据流源源不断涌入,但从机处理数据能力有限,导致输入数据量大于输出数据量。

  • 发送端:当保留TREADY信号时,从机若处理不了数据时,可以将数据缓存。若去掉TREADY信号,则处理不了的数据只能溢出。
  • 接收端:若去除TREADY信号,则说明接收端的处理数据速度大于发送端,数据可以持续输入。

五、实验设计

5.1 情景描述与分析

  假设现在需要一个加解密模块对数据流进行加解密处理,其输入为128bit信息,输出为128bit信息

  分析:如果采用地址映射的方式输入和读取信息,则需要CPU介入向IP核写入或读取信息,当需要加密的数据量过大时,则会占用大量的CPU资源来搬运数据;
  此时就需要DMA介入了,DMA可以对连续的内存进行访问,并将内存数据以数据流的方式搬运到指定地址的IP核;假设DMA以AXIS的协议将数据搬运到IP核内,假设TDATA位宽为32位,则在模块内部需要进行4个数据的缓冲,直到加解密模块将数据处理完毕,再以AXIS数据流方式写出;

5.2 硬件架构设计

  这里我们不探讨DMA的原理,假设我们已经知道了DMA的数据流输出为AXIS协议的,我们对从机进行接口设计;
AMBA协议AXI-Stream(协议信号、设计实践)数据流以AXIS协议流入IP核的Slave接口,其次由Buffer缓冲4个字的数据(128bits);
当缓冲满4个字数据后,AXIS-Slave Interface将从机TREADY信号拉低,此时来自DMA Master接口的数据流阻塞,并且加解密码模块进入工作状态;
若干时间后,加解密模块完成任务后,将输出数据打入Buffer out,此时AXI-Master Interface将TVALID信号拉高,AXI-Slave Interface将TREADY信号拉高,将输出寄存器中处理后的数据回传回DMA,并将新的数据读入输入缓冲区;
其数据流如下:
DATA(IN)为输入的数据,DATA(OUT)为输出的数据;
Encoder Module为加解密模块所占用的时间;
AMBA协议AXI-Stream(协议信号、设计实践)

5.3 源码设计

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/03/01 19:34:56
// Design Name: 
// Module Name: axi_stream_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module axi_stream_test #
    (
        parameter integer C_S_AXIS_TDATA_WIDTH    = 32,
        // parameter integer C_M_AXIS_TDATA_WIDTH    = 32,
        parameter integer C_M_AXIS_BURST_LEN    = 8,
        parameter integer COMB_LEN = 4
    )
    (
        //AXI_Stream receiver ports
        input wire                                   S_AXIS_ACLK,
        input wire                                S_AXIS_ARESETN,
        output wire                                S_AXIS_TREADY,
        input wire [C_S_AXIS_TDATA_WIDTH-1 : 0]     S_AXIS_TDATA,
        input wire [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB,
        input wire                                  S_AXIS_TLAST,
        input wire                                 S_AXIS_TVALID,
        //AXI_Stream send ports
        // input wire                                   M_AXIS_ACLK,
        // input wire                                M_AXIS_ARESETN,
        output wire                                M_AXIS_TVALID,
        output wire    [C_S_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,
        output wire[(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,
        output wire                                 M_AXIS_TLAST,
        input wire                                 M_AXIS_TREADY
    );
    //----------------------------------Slave Logic------------------------------------//
    reg [C_S_AXIS_TDATA_WIDTH-1 : 0]  axi_s_m2s_data;
    (* MARK_DEBUG="true" *)reg [C_S_AXIS_TDATA_WIDTH-1 : 0]  axi_s_m2s_data_buffer [0:COMB_LEN-1];
    (* MARK_DEBUG="true" *)reg [C_S_AXIS_TDATA_WIDTH-1 : 0]  axi_s_data_deal_buffer [0:COMB_LEN-1];
    reg [COMB_LEN-1 : 0] tdata_index;
    wire                 s_axis_tready;
   (* MARK_DEBUG="true" *) reg                  done_flg;

    wire recv_flg;

    assign s_axis_tready = (tdata_index == COMB_LEN) ? 1'b0:1'b1;
    assign S_AXIS_TREADY = s_axis_tready;
    assign recv_flg = s_axis_tready & S_AXIS_TVALID;

    always @(posedge S_AXIS_ACLK) begin : axi_s_recv_proc_
        if(~S_AXIS_ARESETN) begin
            axi_s_m2s_data <= 0;
        end else begin
            if(recv_flg)
            begin
                axi_s_m2s_data <= S_AXIS_TDATA;
            end
        end
    end

    always@(posedge S_AXIS_ACLK)begin
        if(~S_AXIS_ARESETN) begin
            tdata_index <= 'd0;
        end
        else begin
            if((tdata_index != COMB_LEN) & recv_flg)
                tdata_index <= tdata_index + 1'd1;
            else if((tdata_index == COMB_LEN)&(done_flg == 1'b1))
                tdata_index <= 'd0;
        end
    end

    integer index;
    always@(posedge S_AXIS_ACLK)begin
        if(~S_AXIS_ARESETN) begin
            for(index = 0;index < COMB_LEN ; index = index+1)
            begin
                axi_s_m2s_data_buffer[index] <= 'd0;
                axi_s_data_deal_buffer[index] <= 'd0;
            end
        end
        else begin
            if((tdata_index != COMB_LEN) & recv_flg)
                axi_s_m2s_data_buffer[tdata_index] <= S_AXIS_TDATA;
            else if(tdata_index == COMB_LEN)
                for(index = 0;index < COMB_LEN ; index = index+1)
                begin
                   axi_s_data_deal_buffer[index] <= axi_s_m2s_data_buffer[index];
                end
        end
    end

    //----------------------------------Master Logic------------------------------------//
    reg [C_S_AXIS_TDATA_WIDTH-1 : 0]  axi_s_s2m_data_buffer [0:COMB_LEN-1];
    reg  [COMB_LEN-1:0]  m_tdata_index;
    reg  [$clog2(C_M_AXIS_BURST_LEN)-1:0] burst_len_cnt;
    wire m_axis_tlast;
    wire batch_last;
    reg txd_flg;

    assign batch_last = (m_tdata_index == COMB_LEN-1) ? 1'b1:1'b0;
    assign m_axis_tlast = (burst_len_cnt == C_M_AXIS_BURST_LEN-1) ? 1'b1:1'b0;
    assign M_AXIS_TVALID = txd_flg;//(m_tdata_index == COMB_LEN) ? 1'b0:1'b1;
    assign M_AXIS_TSTRB = {(C_S_AXIS_TDATA_WIDTH/8){1'b1}};
    assign M_AXIS_TLAST = m_axis_tlast;
    assign M_AXIS_TDATA = axi_s_s2m_data_buffer[m_tdata_index];

    integer s_index;
    always@(*)
    begin
        for(s_index = 0;s_index < COMB_LEN ; s_index = s_index+1)
        begin
           axi_s_s2m_data_buffer[s_index] <= axi_s_data_deal_buffer[s_index];
        end
    end

    always@(posedge S_AXIS_ACLK)
    begin
        if(~S_AXIS_ARESETN)
        begin
            txd_flg <= 1'b0;
        end
        else
        begin
            if((txd_flg == 1'b0) & (done_flg == 1'b1))
                txd_flg <= 1'b1;
            else if((txd_flg==1'b1) & batch_last)
                txd_flg <= 1'b0;
        end
    end

    always@(posedge S_AXIS_ACLK)
    begin
        if(~S_AXIS_ARESETN)
        begin
            m_tdata_index <= 'b0;
        end
        else
        begin
            if((txd_flg == 1'b1) & (m_tdata_index != COMB_LEN) & (M_AXIS_TREADY == 1'b1))
                m_tdata_index <= m_tdata_index+1'b1;
            else if((m_tdata_index == COMB_LEN))
                m_tdata_index <= 'b0;
        end
    end

    always@(posedge S_AXIS_ACLK)
    begin
        if(~S_AXIS_ARESETN)
        begin
            burst_len_cnt <= 'b0;
        end
        else
        begin
            if((txd_flg == 1'b1) & (burst_len_cnt != C_M_AXIS_BURST_LEN) & (M_AXIS_TREADY == 1'b1))
                burst_len_cnt <= burst_len_cnt+1'b1;
            else if((burst_len_cnt == C_M_AXIS_BURST_LEN))
                burst_len_cnt <= 'b0;
        end
    end

    /--------------------application--------------------------/
    reg [15:0] deal_cnt;
    always@(posedge S_AXIS_ACLK)begin
        if(~S_AXIS_ARESETN) begin
            for(index = 0;index < COMB_LEN ; index = index+1)
            begin
                deal_cnt <= 'd0;
                done_flg <= 1'b0;
            end
        end
        else begin
            if((done_flg == 1'b0) & (s_axis_tready == 1'b0))
            begin
                if(deal_cnt!=32)
                begin
                    deal_cnt <= deal_cnt+'d1;
                    done_flg <= 1'b0;
                end
                else
                begin
                    deal_cnt <= 'd0;
                    done_flg <= 1'b1;
                end
            end
            else if(done_flg == 1'b1)
            begin
                done_flg <= 1'b0;
            end
        end
    end
endmodule

参数说明
  C_M_AXIS_BURST_LEN:最大传输长度,默认为8,与TLAST信号的产生有关,当传输数据个数达到C_M_AXIS_BURST_LEN后,TLAST拉高;
  COMB_LEN:缓冲的长度,表示缓冲的数据数;
  C_S_AXIS_TDATA_WIDTH:传输数据位宽,默认为32位;

代码说明:
  Slave Logic为从机接口逻辑;
  Slave Master为主机接口逻辑;
  application为应用程序逻辑;
说明:假设application逻辑需要32个clk完成加解密(加解密模块);

5.4 仿真

仿真源码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/03/01 19:46:39
// Design Name: 
// Module Name: AXI_Stream_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module AXI_Stream_tb(
    );
        parameter integer C_S_AXIS_TDATA_WIDTH    = 32;
        parameter integer C_M_AXIS_TDATA_WIDTH    = 32;

        reg                                   S_AXIS_ACLK;
        reg                                S_AXIS_ARESETN;
        wire                                S_AXIS_TREADY;
        reg [C_S_AXIS_TDATA_WIDTH-1 : 0]     S_AXIS_TDATA;
        reg [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB;
        reg                                  S_AXIS_TLAST;
        reg                                 S_AXIS_TVALID;

        wire                                  M_AXIS_ACLK;
        wire                               M_AXIS_ARESETN;
        wire                                M_AXIS_TVALID;
        wire    [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA;
        wire[(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB;
        wire                                 M_AXIS_TLAST;
        reg                                 M_AXIS_TREADY;

        assign M_AXIS_ACLK = S_AXIS_ACLK;
        assign M_AXIS_ARESETN = S_AXIS_ARESETN;
        // assign M_AXIS_TREADY = 1'b1;

        initial begin
            S_AXIS_ACLK = 0;
            forever begin
                #1 S_AXIS_ACLK = ~S_AXIS_ACLK;
            end
        end
        
        initial begin
            S_AXIS_ARESETN = 1'b0;
            #2 S_AXIS_ARESETN = 1'b1;
        end

        always @(posedge S_AXIS_ACLK) begin : proc_
            if(~S_AXIS_ARESETN) begin
                S_AXIS_TLAST <= 1'b0;
                S_AXIS_TVALID <= 0;
                S_AXIS_TDATA <= 0;
            end else begin
                S_AXIS_TVALID <= 1;
                if((S_AXIS_TDATA!='d32)&(S_AXIS_TREADY == 1'b1))
                    S_AXIS_TDATA <= S_AXIS_TDATA+1'b1;
            end
        end

        initial begin
            M_AXIS_TREADY = 1;
            // #100 M_AXIS_TREADY = 0;
            // #100 M_AXIS_TREADY = 1;
        end

     axi_stream_test #
    (
        .C_S_AXIS_TDATA_WIDTH (C_S_AXIS_TDATA_WIDTH)
    )axi_stream_test_inist0
    (
       .   S_AXIS_ACLK(   S_AXIS_ACLK),
       .S_AXIS_ARESETN(S_AXIS_ARESETN),
       . S_AXIS_TREADY( S_AXIS_TREADY),
       .  S_AXIS_TDATA(  S_AXIS_TDATA),
       .  S_AXIS_TSTRB(  S_AXIS_TSTRB),
       .  S_AXIS_TLAST(  S_AXIS_TLAST),
       . S_AXIS_TVALID( S_AXIS_TVALID),

       // .   M_AXIS_ACLK(   M_AXIS_ACLK),
       // .M_AXIS_ARESETN(M_AXIS_ARESETN),
       . M_AXIS_TVALID( M_AXIS_TVALID),
       .  M_AXIS_TDATA(  M_AXIS_TDATA),
       .  M_AXIS_TSTRB(  M_AXIS_TSTRB),
       .  M_AXIS_TLAST(  M_AXIS_TLAST),
       . M_AXIS_TREADY( M_AXIS_TREADY)
    );

endmodule

仿真波形:
我们可以看到,输出是连续的递增的,对应了连续的输入;
AMBA协议AXI-Stream(协议信号、设计实践)通过仿真,其基本原理正确;
后续将给出模块IP封装和上板后实际运行的过程;文章来源地址https://www.toymoban.com/news/detail-460781.html


到了这里,关于AMBA协议AXI-Stream(协议信号、设计实践)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AMBA协议- AXI协议指南(1)

    目录 1.概述 2.什么是amba协议, 为什么使用它?  AMBA 如何发展 3.axi 协议概述  AXI in a multi-manager system 4.Channel transfers and transactions  5. 通道信号 本文介绍了一个名为Advanced Microcontroller Bus Architecture (AMBA) AXI的协议,它是现代SoC(System-on-Chip)设计中非常流行的一个协议。这个指

    2024年01月23日
    浏览(37)
  • AMBA总线协议AXI——学习笔记

    2023.3.25 2023.4.23 AXI :高级可拓展接口 高性能、高带宽、低延迟 单向通道体系结构 独立的地址和数据通道 支持多项数据交换。通过 并行执行burst操作 ,极大地提高了数据吞吐能力。 AXI4 :高性能内存映射需求(如读写DDR、使用BRAM控制器读写BRAM等),为了区别,有时候也叫这

    2023年04月23日
    浏览(52)
  • <AMBA总线篇> AXI总线协议介绍

    目录 01 AXI协议简介 AXI协议特性 AXI协议传输特性 02 AXI协议架构 AXI协议架构 write transaction(写传输) read tramsaction(读传输) Interface and interconnect 典型的AXI系统拓扑 03 文章总结 大家好,这里是程序员 杰克 。一名平平无奇的嵌入式软件工程师。 对于学习Xilinx FPGA(ZYNQ)而言,官方提

    2024年02月10日
    浏览(44)
  • AMBA协议AXI-Lite(AXI-Lite介绍)

    AXI_Lite顾名思义即简化版的AXI协议,是对完整的AXI协议裁剪后的AXI协议; 特点: 突发长度永远是1,即只能单次读写,无法连续读写,常用于配置寄存器; 由于删减了逻辑,其资源也消耗较少; 地址映射,相较于AXI-Stream,AXI-Lite的每个数据读写都需要对应的地址; AXI_Lite的系

    2024年02月13日
    浏览(58)
  • 【ARM AMBA AXI 入门 3 - AXI 协议中的 Outstanding transfer 】

    请阅读 【ARM AMBA AXI 总线 文章专栏导读】 上篇文章:ARM AMBA AXI 入门 2 - AXI协议中的BURST 下篇文章:ARM AMBA AXI 入门 4 - AXI 协议中的 Out-of-Order transfer and interleave 介绍

    2024年02月16日
    浏览(46)
  • FPGA-AMBA协议、APB协议、AHB规范、AXI4协议规范概述及它们之间的关系

    笔记记录,AMBA协议、APB协议、AHB规范、AXI4协议规范概述,只是概述描述,具体详细的协议地址传输、数据传输等内容将在下一章节详细说明。 AMBA(Advanced Microcontroller Bus Architecture)是一种由ARM公司提出的处理器总线架构,它定义了处理器、内存和外设之间的通信标准 。

    2024年02月04日
    浏览(34)
  • 【AXI】解读AXI协议的额外信号(QOS信号,REGION信号,与USER信号)

    芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球 四社区 联合力荐 !近500篇 数字IC精品文章收录 ! 【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍 AXI协议 相较于

    2024年01月18日
    浏览(164)
  • AXI协议详解(7)-响应信号

    本章描述了 AXI 读写事务中的四个从响应。 它包含以下部分: 关于响应信令 响应类型 AXI 协议允许读取和写入事务的响应信号。 对于读取事务,来自Slave的响应信息与读取数据本身一起传递,但是对于写入,响应信息沿写入响应通道传送。 AXI 协议响应为: OKAY EXOKAY SLVERR D

    2024年02月16日
    浏览(60)
  • 深入浅出AXI协议(2)——通道及信号

            在之前的文章中,我们主要介绍了什么是AXI协议,AXI协议的特点与优点,然后对于AXI协议非常重要的五通道结构进行了介绍,了解了5个通道各自的作用。本文我们继续AXI协议的学习,我们将讨论5个通道的具体内容和相对应的信号。这一部分的内容现在对于大家来说

    2024年02月11日
    浏览(40)
  • FPGA中AXI协议的理解及接口信号的中文描述

    AXI简介 AXI4 所采用的是一种 READY , VALID 握手通信机制,即主从模块进行数据通信前, 先根据操作对各所用到的数据、地址通道进行握手。主要操作包括传输发送者 A 等到传输接受者 B 的 READY 信号后, A 将数据与 VALID 信号同时发送给 B ,这是一种典型的握手机制。 AXI 总线支

    2024年02月01日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包