1// 2// Copyright 2012 Ettus Research, a National Instruments Company 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6 7// 8// axi_loopback.v 9// 10// Loopback all data assuming it's in CHDR format, and swap SRC/DST in the SID in the process 11// thus reflecting it back to it's origin...in theory! 12// 13 14module axi_loopback 15 #( 16 parameter WIDTH = 64 17 ) 18 ( 19 input clk, 20 input reset, 21 // Input AXIS 22 input [WIDTH-1:0] i_tdata, 23 input i_tlast, 24 input i_tvalid, 25 output i_tready, 26 // Output AXIS 27 output [WIDTH-1:0] o_tdata, 28 output o_tlast, 29 output o_tvalid, 30 input o_tready 31 ); 32 33 wire [WIDTH-1:0] fifoin_tdata,fifoout_tdata,dmux_tdata; 34 wire fifoin_tlast,dmux_tlast; 35 wire fifoin_tvalid,dmux_tvalid; 36 wire fifoin_tready,dmux_tready; 37 38 // Since most real endpoints go via Demux4 place one in here to look for bugs. 39 axi_demux4 #(.ACTIVE_CHAN(4'b0001), .WIDTH(WIDTH)) demux 40 (.clk(clk), .reset(reset), .clear(1'b0), 41 .header(), .dest(2'b00), 42 .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready), 43 .o0_tdata(dmux_tdata), .o0_tlast(dmux_tlast), .o0_tvalid(dmux_tvalid), .o0_tready(dmux_tready), 44 .o1_tdata(), .o1_tlast(), .o1_tvalid(), .o1_tready(1'b1), 45 .o2_tdata(), .o2_tlast(), .o2_tvalid(), .o2_tready(1'b1), 46 .o3_tdata(), .o3_tlast(), .o3_tvalid(), .o3_tready(1'b1)); 47 48 axi_fifo_short #(.WIDTH(WIDTH+1)) axi_fifo_short1 49 (.clk(clk), .reset(reset), .clear(1'b0), 50 .i_tdata({dmux_tlast,dmux_tdata}), .i_tvalid(dmux_tvalid), .i_tready(dmux_tready), 51 .o_tdata({fifoin_tlast,fifoin_tdata}), .o_tvalid(fifoin_tvalid), .o_tready(fifoin_tready), 52 .space(), .occupied()); 53 54 reg header; 55 always @(posedge clk) begin 56 if(reset) begin 57 header <= 1'b1; 58 end else if (header) begin 59 if(fifoin_tvalid & fifoin_tready & ~fifoin_tlast) header <= 1'b0; 60 end else begin 61 if(fifoin_tvalid & fifoin_tready & fifoin_tlast) header <= 1'b1; 62 end 63 end 64 65 assign fifoout_tdata = header ? 66 {fifoin_tdata[63:32] ,fifoin_tdata[15:0],fifoin_tdata[31:16]} : 67 fifoin_tdata; 68 69 axi_fifo_short #(.WIDTH(WIDTH+1)) axi_fifo_short2 70 (.clk(clk), .reset(reset), .clear(1'b0), 71 .i_tdata({fifoin_tlast,fifoout_tdata}), .i_tvalid(fifoin_tvalid), .i_tready(fifoin_tready), 72 .o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready), 73 .space(), .occupied()); 74 75endmodule // axi_loopback 76