ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AXI STREAM协议学习

2021-06-13 22:33:54  阅读:287  来源: 互联网

标签:协议 ACLK STREAM output ARESETn start logic input AXI


axi stream协议的具体内容可参见从零学习AXI4总线(二):AXI4-Stream 介绍AXI4-Stream协议总结
以下是一个简单的HDL示例,完成的功能是master向slave写入512个数据(1,2,3,…,511,512)
主机代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/13 20:42:20
// Design Name: 
// Module Name: axis_master
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module axis_master(
input logic ACLK,
input logic ARESETn,
input logic start,
input logic TREADY,
output logic done,
output logic TVALID,
output logic [31:0] TDATA,
output logic [3:0] TSTRB,
output logic [3:0] TKEEP,
output logic TLAST,
output logic TID,                       
output logic TDEST,                    
output logic TUSER                      //TID,TDEST,TUSER用于多机通信
    );
    
parameter N=512;
logic [31:0] tx_buffer [0:N-1];        //待传输的值
logic [31:0] tx_cnt;
//初始化tx_buffer
always_ff@(posedge ACLK,negedge ARESETn) 
if(~ARESETn)
begin
    for(int i=0;i<N;i++)
        tx_buffer[i]<=i+1;
end
else
begin
    ;
end
//TVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    TVALID<=0;
else if(start)
    TVALID<=1;
else if(TVALID&&TREADY&&TLAST)               //最后一个数据传输完成,拉低TVALID
    TVALID<=0;
//tx_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
   tx_cnt<=0;
else if(start)
   tx_cnt<=0;
else if(TVALID&&TREADY)                //每完成一次数据传输,tx_cnt加1
   tx_cnt<=tx_cnt+1;
//TLAST
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    TLAST<=0;
else if(tx_cnt==N-2&&TVALID&&TREADY)   //倒数第二个数据传输完成,拉高TLAST
    TLAST<=1;
else if(TVALID&&TREADY&&TLAST)         //最后一个数据传输完成后,拉低                           
    TLAST<=0;
//TDATA
always_comb
begin
    TDATA=tx_buffer[tx_cnt];
end
//TSTRB
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    TSTRB<=4'b0000;
else if(start)
    TSTRB<=4'b1111;
//TKEEP
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    TKEEP<=4'b0000;
else if(start)
    TKEEP<=4'b1111;
//done
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    done<=0;
else if(TVALID&&TLAST&&TREADY)          //最后一个数据传输完成
    done<=1;
else 
    done<=0;
endmodule

从机代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/13 20:43:04
// Design Name: 
// Module Name: axis_slave
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module axis_slave(
input logic ACLK,
input logic ARESETn,
input logic start,                  //可以开始接收数据
input logic TVALID,
input logic TLAST,
input logic [31:0] TDATA,
input logic [3:0] TSTRB,
input logic [3:0] TKEEP,
input logic TID,
input logic TDEST,
input logic TUSER,
output logic TREADY,
output logic done                   //数据接收完毕
    );

parameter N = 1024;
logic [31:0] rx_buffer [0:N-1];     //接收缓冲区
logic [31:0] rx_cnt;                //接收计数器
logic [3:0] bytemask;

//rx_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    rx_cnt<=0;
else if(start)
    rx_cnt<=0;
else if(TVALID&&TREADY)              //每完成一次数据传输,rx_cnt加1
    rx_cnt<=rx_cnt+1;
//done
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
    done<=0;
else if(TVALID&&TREADY&&TLAST)              //最后一个数据接收完成,done拉高
    done<=1;
else
    done<=0;
//bytemask
assign bytemask=TSTRB & TKEEP;             //tstrb和tkeep同时为高时才是有效字节
//rx_buffer
always_ff@(posedge ACLK)
if(TVALID&&TREADY)                         //接收数据
begin
    for(int i=0;i<4;i++)
    begin
        rx_buffer[rx_cnt][(8*i+7) -:8]<=((bytemask[i]==1'b1)?TDATA[(8*i+7)-:8]:8'h00);
    end
end
//TREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(~ARESETn)
   TREADY<=0;
else if(start)
   TREADY<=1;
else if(TLAST&&TREADY&&TVALID)        //最后一个数据传输完成
   TREADY<=0;
//
always_ff@(posedge ACLK)
if(done)
begin
    for(int i=0;i<512;i++)
    begin
        $display("%d",rx_buffer[i]);
    end
end       
endmodule

测试文件代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/06/13 21:43:09
// Design Name: 
// Module Name: axis_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module axis_tb;
logic ACLK;
logic ARESETn;
logic TVALID;
logic TREADY;
logic TLAST;
logic [31:0] TDATA;
logic [3:0] TSTRB;
logic [3:0] TKEEP;
logic TID;
logic TUSER;
logic TDEST;
logic master_start;
logic master_done;
logic slave_start;
logic slave_done;
//ACLK
initial 
begin
    ACLK=0;
    forever begin
        #5 ACLK=~ACLK;
    end
end
//ARESETn
initial 
begin
    ARESETn=0;
    #20
    ARESETn=1;
end
//start
initial 
begin
    master_start=0;
    slave_start=0;
    #100
    master_start=1;
    slave_start=1;
    #10
    master_start=0;
    slave_start=0;
end
//instance
axis_master M(
.ACLK(ACLK),
.ARESETn(ARESETn),
.start(master_start),
.TREADY(TREADY),
.done(master_done),
.TVALID(TVALID),
.TDATA(TDATA),
.TSTRB(TSTRB),
.TKEEP(TKEEP),
.TLAST(TLAST),
.TID(TID),                       
.TDEST(TDEST),                    
.TUSER(TUSER)                      //TID,TDEST,TUSER用于多机通信
);

axis_slave S(
.ACLK(ACLK),
.ARESETn(ARESETn),
.start(slave_start),                  //可以开始接收数据
.TVALID(TVALID),
.TLAST(TLAST),
.TDATA(TDATA),
.TSTRB(TSTRB),
.TKEEP(TKEEP),
.TID(TID),
.TDEST(TDEST),
.TUSER(TUSER),
.TREADY(TREADY),
.done(slave_done)                   //数据接收完毕
);
endmodule

标签:协议,ACLK,STREAM,output,ARESETn,start,logic,input,AXI
来源: https://blog.csdn.net/qq_40268672/article/details/117886267

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有