aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/axi/axi_fast_fifo.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/axi/axi_fast_fifo.v')
-rw-r--r--fpga/usrp3/lib/axi/axi_fast_fifo.v108
1 files changed, 108 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/axi/axi_fast_fifo.v b/fpga/usrp3/lib/axi/axi_fast_fifo.v
new file mode 100644
index 000000000..5ff303b11
--- /dev/null
+++ b/fpga/usrp3/lib/axi/axi_fast_fifo.v
@@ -0,0 +1,108 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+//
+// Ultra fast critical path FIFO.
+// Only 2 entrys but no combinatorial feed through paths
+//
+
+
+module axi_fast_fifo
+ #(parameter WIDTH=64)
+ (
+ input clk,
+ input reset,
+ input clear,
+ //
+ input [WIDTH-1:0] i_tdata,
+ input i_tvalid,
+ output reg i_tready,
+ //
+ output [WIDTH-1:0] o_tdata,
+ output reg o_tvalid,
+ input o_tready
+ );
+
+ reg [WIDTH-1:0] data_reg1, data_reg2;
+
+ reg [1:0] state;
+
+ localparam EMPTY = 0;
+ localparam HALF = 1;
+ localparam FULL = 2;
+
+ always @(posedge clk)
+ if (reset | clear) begin
+ state <= EMPTY;
+ data_reg1 <= 0;
+ data_reg2 <= 0;
+ o_tvalid <= 1'b0;
+ i_tready <= 1'b0;
+
+ end else begin
+ case (state)
+ // Nothing in either register.
+ // Upstream can always push data to us.
+ // Downstream has nothing to take from us.
+ EMPTY: begin
+ if (i_tvalid) begin
+ data_reg1 <= i_tdata;
+ state <= HALF;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b1;
+ end else begin
+ state <= EMPTY;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b0;
+ end
+ end
+ // First Register Full.
+ // Upstream can always push data to us.
+ // Downstream can always read from us.
+ HALF: begin
+ if (i_tvalid && o_tready) begin
+ data_reg1 <= i_tdata;
+ state <= HALF;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b1;
+ end else if (i_tvalid) begin
+ data_reg1 <= i_tdata;
+ data_reg2 <= data_reg1;
+ state <= FULL;
+ i_tready <= 1'b0;
+ o_tvalid <= 1'b1;
+ end else if (o_tready) begin
+ state <= EMPTY;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b0;
+ end else begin
+ state <= HALF;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b1;
+ end
+ end // case: HALF
+ // Both Registers Full.
+ // Upstream can not push to us in this state.
+ // Downstream can always read from us.
+ FULL: begin
+ if (o_tready) begin
+ state <= HALF;
+ i_tready <= 1'b1;
+ o_tvalid <= 1'b1;
+ end
+ else begin
+ state <= FULL;
+ i_tready <= 1'b0;
+ o_tvalid <= 1'b1;
+ end
+ end
+ endcase // case(state)
+ end // else: !if(reset | clear)
+
+ assign o_tdata = (state == FULL) ? data_reg2 : data_reg1;
+
+
+endmodule // axi_fast_fifo