aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/fifo/monitor_axi_fifo.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/fifo/monitor_axi_fifo.v')
-rw-r--r--fpga/usrp3/lib/fifo/monitor_axi_fifo.v123
1 files changed, 123 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/fifo/monitor_axi_fifo.v b/fpga/usrp3/lib/fifo/monitor_axi_fifo.v
new file mode 100644
index 000000000..f5d73455f
--- /dev/null
+++ b/fpga/usrp3/lib/fifo/monitor_axi_fifo.v
@@ -0,0 +1,123 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+
+
+//
+// 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