aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/fifo/monitor_axi_fifo.v
blob: 504296e92d10040891254685c63920716f1b2c5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Copyright 2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

//
// This module is instantiated in parallel with a FIFO with AXI4-STREAM interfaces.
// It tracks how many complete packets are contained within the FIFO, and also indicates
// when the first word of a packet is presented on the FIFO outputs.
//

 
module monitor_axi_fifo
  #(
    parameter COUNT_BITS=8
    )
  (
   input clk,
   input reset,
   input clear,
   // Monitored FIFO signals
   input i_tvalid,
   input i_tready,
   input i_tlast,
   input o_tvalid,
   input o_tready,
   input o_tlast,
   // FIFO status outputs
   output reg [COUNT_BITS-1:0] pkt_count, // Exact whole packet count
   output pkt_present // Flags any whole packets present
 
   );

   localparam WAIT_SOF = 0;
   localparam WAIT_EOF = 1;
    
   
   reg        in_state, out_state;
   reg        pause_tx;
                
   //
   // Count packets arriving into large FIFO
   //
   always @(posedge clk)
     if (reset | clear) begin
        in_state <= WAIT_SOF;
     end else
       case(in_state)
	 //
	 // After RESET or the EOF of previous packet, the first cycle with
	 // input valid and input ready asserted is the SOF.
	 //
         WAIT_SOF: 
           if (i_tvalid && i_tready) begin
              in_state <= WAIT_EOF;
           end else begin
              in_state <= WAIT_SOF;
           end
	 //
	 // EOF is signalled by the assertion i_tlast whilst input valid and ready are asserted.
	 //
         WAIT_EOF: 
           if (i_tlast && i_tvalid && i_tready) begin
              in_state <= WAIT_SOF;
           end else begin
              in_state <= WAIT_EOF;
           end
       endcase // case(in_state)
   


   //
   // Count packets leaving large FIFO
   //
   always @(posedge clk)
     if (reset | clear) begin
        out_state <= WAIT_SOF;
     end else
       case(out_state)
	 //
	 // After RESET or the EOF of previous packet, the first cycle with
	 // output valid and output ready asserted is the SOF.
	 //
         WAIT_SOF: 
           if (o_tvalid && o_tready) begin
              out_state <= WAIT_EOF;
           end else begin
              out_state <= WAIT_SOF;
           end
	 //
	 // EOF is signalled by o_tlast asserted whilst output valid and ready asserted.
	 //
         WAIT_EOF: 
           if (o_tlast && o_tvalid && o_tready) begin
              out_state <= WAIT_SOF;
           end else begin
              out_state <= WAIT_EOF;
           end
       endcase // case(in_state)
   

   //
   // Count packets in FIFO.
   // No protection on counter wrap, 
   // unclear how to gracefully deal with it.
   // Perhaps generate Error IRQ so that S/W could clean up?
   // Configure so that the pkt_count is ample for the application.
   //
   always @(posedge clk)
     if (reset | clear)
       pkt_count <= 0;
     else if (((out_state==WAIT_EOF) && o_tlast && o_tvalid && o_tready ) &&
	      ((in_state==WAIT_EOF) && i_tlast && i_tvalid && i_tready))
       pkt_count <= pkt_count;
     else if ((out_state==WAIT_EOF) && o_tlast && o_tvalid && o_tready)
       pkt_count <= pkt_count - 1;
     else if ((in_state==WAIT_EOF)  && i_tlast && i_tvalid && i_tready)
       pkt_count <= pkt_count + 1;

   // Non-zero packet count indicates packet(s) present.
   assign pkt_present = |pkt_count;
 
endmodule // count_tx_packets