1// 2// Copyright 2019 Ettus Research, A National Instruments Company 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6// Module: chdr_pad_packet 7// Description: 8// This module pads extra data on the AXI-Stream bus 9// to the requested packet size. This module is for 10// creating len-sized packets, for DMA engines that 11// do not support partial transfers. 12// 13// Parameters: 14// - CHDR_W: Width of the CHDR tdata bus in bits 15// 16// Signals: 17// - s_axis_* : Input AXI-Stream CHDR bus 18// - m_axis_* : Output AXI-Stream CHDR bus 19// - len : Requested number of CHDR_W lines in the packet (must be > 1) 20 21`default_nettype none 22module chdr_pad_packet #( 23 parameter CHDR_W = 256 24)( 25 input wire clk, 26 input wire rst, 27 input wire [15:0] len, 28 input wire [CHDR_W-1:0] s_axis_tdata, 29 input wire s_axis_tlast, 30 input wire s_axis_tvalid, 31 output reg s_axis_tready, 32 output wire [CHDR_W-1:0] m_axis_tdata, 33 output reg m_axis_tlast, 34 output reg m_axis_tvalid, 35 input wire m_axis_tready 36); 37 38 localparam [1:0] ST_HEADER = 2'd0; 39 localparam [1:0] ST_BODY = 2'd1; 40 localparam [1:0] ST_PAD = 2'd2; 41 localparam [1:0] ST_DROP = 2'd3; 42 43 reg [1:0] state; 44 reg [15:0] lines_left; 45 46 always @(posedge clk) begin 47 if (rst || (len <= 16'd1)) begin 48 state <= ST_HEADER; 49 end else begin 50 case(state) 51 ST_HEADER: begin 52 lines_left <= len - 16'd1; 53 if (s_axis_tvalid && m_axis_tready) begin 54 if (!s_axis_tlast) begin 55 // Packet is more than one line and length not reached 56 state <= ST_BODY; 57 end else begin 58 // Packet is only one line and length not reached 59 state <= ST_PAD; 60 end 61 end 62 end 63 ST_BODY: begin 64 if (s_axis_tvalid && m_axis_tready) begin 65 lines_left <= lines_left - 16'd1; 66 if (s_axis_tlast && (lines_left == 16'd1)) begin 67 // End of input and reached length 68 state <= ST_HEADER; 69 end else if (s_axis_tlast && (lines_left != 16'd1)) begin 70 // End of input, but length not reached 71 state <= ST_PAD; 72 end else if (!s_axis_tlast && (lines_left == 16'd1)) begin 73 // Reached length, but input continues... 74 state <= ST_DROP; 75 end 76 end 77 end 78 ST_PAD: begin 79 if (m_axis_tready) begin 80 lines_left <= lines_left - 16'd1; 81 if (lines_left == 16'd1) begin 82 state <= ST_HEADER; 83 end 84 end 85 end 86 ST_DROP: begin 87 if (s_axis_tvalid && s_axis_tlast) begin 88 state <= ST_HEADER; 89 end 90 end 91 default: begin 92 // We should never get here 93 state <= ST_HEADER; 94 end 95 endcase 96 end 97 end 98 99 assign m_axis_tdata = s_axis_tdata; 100 101 always @(*) begin 102 case(state) 103 ST_HEADER: begin 104 if (len <= 16'd1) begin 105 s_axis_tready <= 1'b0; 106 m_axis_tvalid <= 1'b0; 107 end else begin 108 s_axis_tready <= m_axis_tready; 109 m_axis_tvalid <= s_axis_tvalid; 110 end 111 m_axis_tlast <= 1'b0; 112 end 113 ST_BODY: begin 114 s_axis_tready <= m_axis_tready; 115 m_axis_tvalid <= s_axis_tvalid; 116 m_axis_tlast <= (lines_left == 16'd1); 117 end 118 ST_PAD: begin 119 s_axis_tready <= 1'b0; 120 m_axis_tvalid <= 1'b1; 121 m_axis_tlast <= (lines_left == 16'd1); 122 end 123 ST_DROP: begin 124 s_axis_tready <= 1'b1; 125 m_axis_tvalid <= 1'b0; 126 m_axis_tlast <= 1'b0; 127 end 128 endcase 129 end 130 131endmodule // chdr_pad_packet 132`default_nettype wire 133