1//
2// Copyright 2018 Ettus Research, a National Instruments Company
3//
4// SPDX-License-Identifier: LGPL-3.0-or-later
5//
6// Description:
7//   A module to monitor a an AXI-Stream link and gather various
8//   metric about packets and the stream in general
9
10module axis_strm_monitor #(
11  parameter WIDTH         = 64,
12  parameter COUNT_W       = 32,
13  parameter PKT_LENGTH_EN = 0,
14  parameter PKT_CHKSUM_EN = 0,
15  parameter PKT_COUNT_EN  = 0,
16  parameter XFER_COUNT_EN = 0
17)(
18  // Clocks and resets
19  input  wire               clk,
20  input  wire               reset,
21  // Stream to monitor
22  input  wire [WIDTH-1:0]   axis_tdata,
23  input  wire               axis_tlast,
24  input  wire               axis_tvalid,
25  input  wire               axis_tready,
26  // Packet Stats
27  output wire               sop,
28  output wire               eop,
29  output reg  [15:0]        pkt_length = 16'd0,
30  output wire [WIDTH-1:0]   pkt_chksum,
31  // Stream Stats
32  output reg  [COUNT_W-1:0] pkt_count  = {COUNT_W{1'b0}},
33  output reg  [COUNT_W-1:0] xfer_count = {COUNT_W{1'b0}}
34);
35
36  //----------------------------
37  // Packet specific
38  //----------------------------
39
40  reg pkt_head = 1'b1;
41  wire xfer = axis_tvalid & axis_tready;
42
43  assign sop = pkt_head & xfer;
44  assign eop = xfer & axis_tlast;
45
46  always @(posedge clk) begin
47    if (reset) begin
48      pkt_head <= 1'b1;
49    end else begin
50      if (pkt_head) begin
51        if (xfer)
52          pkt_head <= ~eop;
53      end else begin
54        if (eop)
55          pkt_head <= 1'b0;
56      end
57    end
58  end
59
60  generate if (PKT_LENGTH_EN == 0) begin
61    // Count the number of lines (transfers) in a packet
62    always @(posedge clk) begin
63      if (reset | eop) begin
64        pkt_length <= 16'd1;
65      end else if (xfer) begin
66        pkt_length <= pkt_length + 1'b1;
67      end
68    end
69  end else begin
70    // Default packet length is 0
71    always @(*) pkt_length <= 16'd0;
72  end endgenerate
73
74  generate if (PKT_LENGTH_EN == 0) begin
75    // Compute the XOR checksum of the lines in a packet
76    reg [WIDTH-1:0] chksum_prev = {WIDTH{1'b0}};
77    always @(posedge clk) begin
78      if (reset) begin
79        chksum_prev <= {WIDTH{1'b0}};
80      end else if (xfer) begin
81        chksum_prev <= pkt_chksum;
82      end
83    end
84    assign pkt_chksum = chksum_prev ^ axis_tdata;
85  end else begin
86    // Default checksum is 0
87    assign pkt_chksum = {WIDTH{1'b0}};
88  end endgenerate
89
90  //----------------------------
91  // Stream specific
92  //----------------------------
93
94  always @(posedge clk) begin
95    if (reset | (PKT_COUNT_EN == 0)) begin
96      pkt_count <= {COUNT_W{1'b0}};
97    end else if (eop) begin
98      pkt_count <= pkt_count + 1'b1;
99    end
100  end
101
102  always @(posedge clk) begin
103    if (reset | (XFER_COUNT_EN == 0)) begin
104      xfer_count <= {COUNT_W{1'b0}};
105    end else if (xfer) begin
106      xfer_count <= xfer_count + 1'b1;
107    end
108  end
109
110 endmodule