Files
b210-k7-fpga/lib/xge_interface/axi_count_packets_in_fifo.v
T
Ben Hilburn fbbc991a7d Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
2014-02-14 12:05:07 -08:00

156 lines
3.8 KiB
Verilog

//
// Copyright 2013 Ettus Research LLC
//
//
// 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 = 0;
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