File: axi_count_packets_in_fifo.v

package info (click to toggle)
uhd 4.8.0.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 183,172 kB
  • sloc: cpp: 279,415; python: 109,850; ansic: 103,348; vhdl: 57,230; tcl: 20,007; xml: 8,581; makefile: 2,863; sh: 2,797; pascal: 230; javascript: 120; csh: 94; asm: 20; perl: 11
file content (158 lines) | stat: -rw-r--r-- 4,026 bytes parent folder | download | duplicates (5)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
// Copyright 2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


//
// Tracks the number of complete packets in an AXI FIFO so that
// the XGE MAC can commit to transmitting a packet.
//
 
module axi_count_packets_in_fifo
  (
   input clk,
   input reset,
   input in_axis_tvalid,
   input in_axis_tready,
   input in_axis_tlast,
   input out_axis_tvalid,
   input out_axis_tready,
   input out_axis_tlast,
   input pkt_tx_full,
   output enable_tx
   );

   localparam WAIT_SOF = 0;
   localparam WAIT_EOF = 1;
   
   localparam WAIT_FULL = 0;
   localparam DELAY_TO_EOF = 1;
   localparam WAIT_SPACE = 2;
   
   
   reg 	      in_state, out_state;
   reg [1:0]  full_state;
   reg 	      pause_tx;
   	      
   reg [7:0] pkt_count;

   
   //
   // Count packets arriving into large FIFO
   //
   always @(posedge clk)
     if (reset) begin
	in_state <= WAIT_SOF;
     end else
       case(in_state)
	 WAIT_SOF: 
	   if (in_axis_tvalid && in_axis_tready) begin
	      in_state <= WAIT_EOF;
	   end else begin
	      in_state <= WAIT_SOF;
	   end
	 WAIT_EOF: 
	   if (in_axis_tlast && in_axis_tvalid && in_axis_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) begin
	out_state <= WAIT_SOF;
     end else
       case(out_state)
	 WAIT_SOF: 
	   if (out_axis_tvalid && out_axis_tready) begin
	      out_state <= WAIT_EOF;
	   end else begin
	      out_state <= WAIT_SOF;
	   end
	 WAIT_EOF: 
	   if (out_axis_tlast && out_axis_tvalid && out_axis_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 such an error could occur or how to gracefully deal with it.
   //
   always @(posedge clk)
     if (reset)
       pkt_count <= 0;
     else if (((out_state==WAIT_EOF) && out_axis_tlast && out_axis_tvalid && out_axis_tready) 
	      && ((in_state==WAIT_EOF) && in_axis_tlast && in_axis_tvalid && in_axis_tready))
       pkt_count <= pkt_count;
     else if ((out_state==WAIT_EOF) && out_axis_tlast && out_axis_tvalid && out_axis_tready)
       pkt_count <= pkt_count - 1;
     else if ((in_state==WAIT_EOF) && in_axis_tlast && in_axis_tvalid && in_axis_tready)
       pkt_count <= pkt_count + 1;
   

   //
   // Guard against Tx MAC overflow (as indicated by pkt_tx_full)
   //
   always @(posedge clk)
     if (reset) begin
	pause_tx <= 0;
	full_state <= WAIT_FULL;
     end	
     else begin
	pause_tx <= 0;	
	case(full_state)
	  WAIT_FULL:
	    // Search for pkt_tx_full going asserted
	    if (pkt_tx_full && (out_state == WAIT_SOF)) begin
	       full_state <= WAIT_SPACE;
	       pause_tx <= 1;
	    end else if (pkt_tx_full && (out_state == WAIT_EOF)) begin
	       full_state <= DELAY_TO_EOF;
	    end
	  
	  DELAY_TO_EOF:
	    // pkt_tx_full has gone asserted during Tx of a packet from FIFO.
	    // Wait until either FIFO has space again and transition direct to WAIT_FULL
	    // or at EOF if pkt_tx_full is still asserted the transition to WAIT_SPACE until
	    // MAC flags there is space again.
	    if (pkt_tx_full && out_axis_tlast && out_axis_tvalid && out_axis_tready) begin
	       full_state <= WAIT_SPACE;
	       pause_tx <= 1;
	    end else if (pkt_tx_full) begin
	       full_state <= DELAY_TO_EOF;
	    end else
	      full_state <= WAIT_FULL;
	  
	  WAIT_SPACE:
	    // Wait for MAC to flag space in internal Tx FIFO again then transition to WAIT_FULL.
	    if (pkt_tx_full) begin
	       full_state <= WAIT_SPACE;
	       pause_tx <= 1;
	    end else
	      full_state <= WAIT_FULL;
	  
	endcase // case(full_state)
     end
	

   // Enable Tx to MAC
   assign enable_tx = (pkt_count != 0) && ~pause_tx;
   
   
   

endmodule // count_tx_packets