aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v')
-rw-r--r--fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v128
1 files changed, 128 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v b/fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v
new file mode 100644
index 000000000..4d9178052
--- /dev/null
+++ b/fpga/usrp3/lib/axi/axi_extract_tlast_tkeep.v
@@ -0,0 +1,128 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: axi_extract_tlast_tkeep
+//
+// Description:
+//
+// This module extracts the TLAST and TKEEP values that were embedded by the
+// axi_embed_tlast_tkeep module. See axi_embed_tlast_tkeep for a description
+// of how the data is encoded.
+//
+// Here are some extraction examples for DATA_W = 64.
+//
+// 0x1234567887654321 becomes
+// 0x1234567887654321 (no changes)
+//
+// 0xDEADBEEF00000001 0x1234567887654321 becomes
+// 0x1234567887654321 with TLAST=1 and TKEEP=0
+//
+// 0xDEADBEEF00000005 0x1234567887654321 becomes
+// 0x1234567887654321 with TLAST=1 and TKEEP=2
+//
+// 0xDEADBEEF00000000 0xDEADBEEFFEEDCAFE
+// 0xDEADBEEFFEEDCAFE without TLAST=0 and TKEEP=0 becomes
+//
+// 0xDEADBEEF00000002 0xDEADBEEFFEEDCAFE
+// 0xDEADBEEFFEEDCAFE with TLAST=0 and TKEEP=1 becomes
+//
+
+module axi_extract_tlast_tkeep #(
+ parameter DATA_W = 64,
+ parameter KEEP_W = DATA_W /8
+) (
+ input clk,
+ input rst,
+
+ // Input AXI-Stream
+ input [DATA_W-1:0] i_tdata,
+ input i_tvalid,
+ output reg i_tready,
+
+ // Output AXI-Stream
+ output reg [DATA_W-1:0] o_tdata,
+ output reg [KEEP_W-1:0] o_tkeep,
+ output reg o_tlast,
+ output reg o_tvalid,
+ input o_tready
+);
+
+ localparam ESC_WORD_W = 32;
+ localparam [ESC_WORD_W-1:0] ESC_WORD = 'hDEADBEEF;
+
+
+ //---------------------------------------------------------------------------
+ // TKEEP and TLAST Holding Register
+ //---------------------------------------------------------------------------
+
+ reg save_flags;
+ reg tlast_saved;
+ reg [KEEP_W-1:0] tkeep_saved;
+
+ always @(posedge clk) begin
+ if (save_flags) begin
+ // Save the TLAST and TKEEP values embedded in the escape word
+ tlast_saved <= i_tdata[0];
+ tkeep_saved <= i_tdata[1 +: KEEP_W];
+ end
+ end
+
+
+ //--------------------------------------------------------------------------
+ // State Machine
+ //--------------------------------------------------------------------------
+
+ localparam ST_IDLE = 0;
+ localparam ST_DATA = 1;
+
+ reg [0:0] state = ST_IDLE;
+ reg [0:0] next_state;
+
+ always @(posedge clk) begin
+ if (rst) begin
+ state <= ST_IDLE;
+ end else begin
+ state <= next_state;
+ end
+ end
+
+ always @(*) begin
+ // Default assignments (pass through)
+ o_tdata = i_tdata;
+ o_tlast = 1'b0;
+ o_tkeep = {KEEP_W{1'b1}};
+ save_flags = 1'b0;
+ next_state = state;
+ o_tvalid = i_tvalid;
+ i_tready = o_tready;
+
+ case(state)
+ //
+ // Search for escape code. If found don't pass data downstream but
+ // transition to next state. Otherwise, pass data downstream.
+ //
+ ST_IDLE: begin
+ if ((i_tdata[DATA_W-1 -: ESC_WORD_W] == ESC_WORD) && i_tvalid) begin
+ save_flags = 1'b1;
+ next_state = ST_DATA;
+ o_tvalid = 1'b0;
+ i_tready = 1'b1;
+ end
+ end
+
+ //
+ // Output data word with the saved TLAST and TKEEP values
+ //
+ ST_DATA: begin
+ o_tlast = tlast_saved;
+ o_tkeep = tkeep_saved;
+ if (i_tvalid & o_tready) begin
+ next_state = ST_IDLE;
+ end
+ end
+ endcase
+ end
+
+endmodule