AXI-Stream System simulation


  • Previously, I designed AXI-Stream Master and Slave. This post is about connecting AXI-Stream Master and Slave.
  •  Exchange data between them.
Tasks for this system design:

  • Connect the ports with each other.
  • Develope the TB which will drive all the user ports (data, send, finish, ready, data, and finish) in this module.

Testbench Code (.sv):


`timescale 1ns / 1ps
module axis_s_m_tb();

default clocking cb@(posedge aclk);
endclocking

bit aclk, areset_neg, send;
logic finish;
logic slave_finish;

logic tready;
logic tvalid, tlast;
logic [31:0] tdata;

logic [31:0] data;
logic [31:0] slave_data;
logic slave_ready;

//axi stream slave instantiation
axi_stream_master inst_axi_stream_master (.areset_neg(areset_neg), .aclk(aclk),
                .data(data),
                .send(send),
                .tready(tready),
                .tvalid(tvalid),
                .tlast(tlast),
                .tdata(tdata),
                .finish(finish)
                );

//axi stream slave instantiation     
axis_slave inst_axis_slave (.areset_neg(areset_neg), .aclk(aclk),
                .data(slave_data),
                .ready(slave_ready),
                .tready(tready),
                .tvalid(tvalid),
                .tlast(tlast), .tdata(tdata),
                .finish(slave_finish)
                );
                
//////////Verification IP////////////
/*wire [31:0] pc_status;

axi_stream_protocol_checker_0 inst_axiCheck(
            .aclk(aclk), //input wire aclk
            .aresetn(~areset_neg), //input wire aresetn
            .pc_axis_tvalid(tvalid), //input wire pc_axis_tvalid
            .pc_axis_tready(tready), //input wire pc_axis_tready
            .pc_axis_tdata((5'd0,tdata)), // input wire [7:0] pc_axis_tdata
            .pc_asserted(pc_asserted), //output wire pc_asserted
            .pc_status(pc_status) //output wire [31:0] pc_status
            );
*/

initial
forever #2 aclk++;

initial
begin
    areset_neg <= 0;
    ##4 areset_neg <= 1;
    end
    
initial
begin
##10 send = 1;
##1 send = 0;
##20 send = 1;
##1 send = 0;
end

initial
begin
    slave_ready <= 0;
    ##15 slave_ready <= 1;
    ##5 slave_ready <= 0;
end

initial
begin
data <= 32'haaaa_bbbb;
##25
data <= 32'hcccc_dddd;
end

initial
##40 $finish;
    
endmodule



=> After completing the above tasks, below is the simulated waveform:

*Slave ports not shown.

Now, let us understand the behavior of the above wave:
  • Master:
    • Begining of the testbench: apply data[31:0] which is 'aaaabbbb'.
    • Then, enable the 'send' signal.
    • AXI master gets the data to its 'tdata', and enables 'tlast' and 'tvalid' saying hey slave!  I have new data for you
    • And then it waits until Slave enables its 'tready'.
  • Slave:
    • 'ready' signal provided by the user.
    • When user is able to take signal from Slave - it enables 'ready' signal.
    • When 'ready' signal is enabled that means our slave takes this ready signal and enables its own ready signal saying - I am slave and I am ready to accept data from you.
    • After that, the handshake is happening (in the next clock cycle) - Final Step >> Data exchange happened.
    • 'finish' - data received.
Hence, Master is sending the data and Slave is receiving the data.

Comments