1// 2// Copyright 2019 Ettus Research, a National Instruments Brand 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6// Module: axi_extract_tlast_tkeep 7// 8// Description: 9// 10// This module extracts the TLAST and TKEEP values that were embedded by the 11// axi_embed_tlast_tkeep module. See axi_embed_tlast_tkeep for a description 12// of how the data is encoded. 13// 14// Here are some extraction examples for DATA_W = 64. 15// 16// 0x1234567887654321 becomes 17// 0x1234567887654321 (no changes) 18// 19// 0xDEADBEEF00000001 0x1234567887654321 becomes 20// 0x1234567887654321 with TLAST=1 and TKEEP=0 21// 22// 0xDEADBEEF00000005 0x1234567887654321 becomes 23// 0x1234567887654321 with TLAST=1 and TKEEP=2 24// 25// 0xDEADBEEF00000000 0xDEADBEEFFEEDCAFE 26// 0xDEADBEEFFEEDCAFE without TLAST=0 and TKEEP=0 becomes 27// 28// 0xDEADBEEF00000002 0xDEADBEEFFEEDCAFE 29// 0xDEADBEEFFEEDCAFE with TLAST=0 and TKEEP=1 becomes 30// 31 32module axi_extract_tlast_tkeep #( 33 parameter DATA_W = 64, 34 parameter KEEP_W = DATA_W /8 35) ( 36 input clk, 37 input rst, 38 39 // Input AXI-Stream 40 input [DATA_W-1:0] i_tdata, 41 input i_tvalid, 42 output reg i_tready, 43 44 // Output AXI-Stream 45 output reg [DATA_W-1:0] o_tdata, 46 output reg [KEEP_W-1:0] o_tkeep, 47 output reg o_tlast, 48 output reg o_tvalid, 49 input o_tready 50); 51 52 localparam ESC_WORD_W = 32; 53 localparam [ESC_WORD_W-1:0] ESC_WORD = 'hDEADBEEF; 54 55 56 //--------------------------------------------------------------------------- 57 // TKEEP and TLAST Holding Register 58 //--------------------------------------------------------------------------- 59 60 reg save_flags; 61 reg tlast_saved; 62 reg [KEEP_W-1:0] tkeep_saved; 63 64 always @(posedge clk) begin 65 if (save_flags) begin 66 // Save the TLAST and TKEEP values embedded in the escape word 67 tlast_saved <= i_tdata[0]; 68 tkeep_saved <= i_tdata[1 +: KEEP_W]; 69 end 70 end 71 72 73 //-------------------------------------------------------------------------- 74 // State Machine 75 //-------------------------------------------------------------------------- 76 77 localparam ST_IDLE = 0; 78 localparam ST_DATA = 1; 79 80 reg [0:0] state = ST_IDLE; 81 reg [0:0] next_state; 82 83 always @(posedge clk) begin 84 if (rst) begin 85 state <= ST_IDLE; 86 end else begin 87 state <= next_state; 88 end 89 end 90 91 always @(*) begin 92 // Default assignments (pass through) 93 o_tdata = i_tdata; 94 o_tlast = 1'b0; 95 o_tkeep = {KEEP_W{1'b1}}; 96 save_flags = 1'b0; 97 next_state = state; 98 o_tvalid = i_tvalid; 99 i_tready = o_tready; 100 101 case(state) 102 // 103 // Search for escape code. If found don't pass data downstream but 104 // transition to next state. Otherwise, pass data downstream. 105 // 106 ST_IDLE: begin 107 if ((i_tdata[DATA_W-1 -: ESC_WORD_W] == ESC_WORD) && i_tvalid) begin 108 save_flags = 1'b1; 109 next_state = ST_DATA; 110 o_tvalid = 1'b0; 111 i_tready = 1'b1; 112 end 113 end 114 115 // 116 // Output data word with the saved TLAST and TKEEP values 117 // 118 ST_DATA: begin 119 o_tlast = tlast_saved; 120 o_tkeep = tkeep_saved; 121 if (i_tvalid & o_tready) begin 122 next_state = ST_IDLE; 123 end 124 end 125 endcase 126 end 127 128endmodule 129