diff options
Diffstat (limited to 'fpga/usrp3/lib/axi/axi_fast_fifo.v')
-rw-r--r-- | fpga/usrp3/lib/axi/axi_fast_fifo.v | 108 |
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 |