1//
2// Copyright 2012 Ettus Research LLC
3// Copyright 2018 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6//
7
8
9//
10// This module is connected to the output port of an AXI4-STREAM FIFO that is used to move packetized data.
11// It extracts and indicates the header (first word) of a packet in the FIFO. The header and flag are pipelined
12// for timing closure.
13//
14
15module axi_fifo_header
16  #(
17    parameter WIDTH=64  // Bit width of FIFO word.
18    )
19    (
20     input clk,
21     input reset,
22     input clear,
23     // Monitored FIFO signals
24     input [WIDTH-1:0] o_tdata,
25     input o_tvalid,
26     input o_tready,
27     input o_tlast,
28     input pkt_present,
29     // Header signals
30     output reg [WIDTH-1:0] header,
31     output reg header_valid
32     );
33
34   localparam WAIT_SOF = 0;
35   localparam WAIT_EOF = 1;
36
37   reg 	    out_state;
38
39
40    //
41    // Monitor packets leaving FIFO
42    //
43    always @(posedge clk)
44      if (reset | clear) begin
45         out_state <= WAIT_SOF;
46      end else
47	case(out_state)
48	  //
49	  // After RESET or the EOF of previous packet, the first cycle with
50	  // output valid asserted is the SOF and presents the Header word.
51	  // The cycle following the concurrent presentation of asserted output
52	  // valid and output ready presents the word following the header.
53	  //
54          WAIT_SOF:
55            if (o_tvalid && o_tready) begin
56               out_state <= WAIT_EOF;
57            end else begin
58               out_state <= WAIT_SOF;
59            end
60	  //
61	  // EOF is signalled by o_tlast asserted whilst output valid and ready asserted.
62	  //
63          WAIT_EOF:
64            if (o_tlast && o_tvalid && o_tready) begin
65               out_state <= WAIT_SOF;
66            end else begin
67               out_state <= WAIT_EOF;
68            end
69	endcase // case(in_state)
70
71   //
72   // Pipeline Header signals
73   //
74   always @(posedge clk)
75     if (reset | clear) begin
76	header <= 0;
77	header_valid <= 0;
78     end else if (o_tvalid && (out_state == WAIT_SOF) && pkt_present) begin
79	// Header will remian valid until o_tready is asserted as this will cause a state transition.
80	header <= o_tdata;
81	header_valid <= 1;
82     end else begin
83	header_valid <= 0;
84     end
85
86
87endmodule // axi_fifo_header
88