fpga: lib: Add zero-length option to axi_fifo
Original-commit: 6ea4e4808e09e55bb2ba05e787e79ec3c5fe4340
This commit is contained in:
+128
-59
@@ -1,71 +1,140 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2012-2014 Ettus Research LLC
|
// Copyright 2025 Ettus Research, a National Instruments Brand
|
||||||
// Copyright 2018 Ettus Research, a National Instruments Company
|
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
//
|
//
|
||||||
|
// Module: axi_fifo
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
//
|
||||||
|
// General FIFO block
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// WIDTH : Width of tdata in bits
|
||||||
|
// SIZE : Log base 2 of the depth of the FIFO. In other words, the size of
|
||||||
|
// the FIFO is 2**SIZE elements deep. The implementation changes
|
||||||
|
// depending on the FIFO size, as described below.
|
||||||
|
//
|
||||||
|
// SIZE < 0 : No FIFO (data passes through without any buffer)
|
||||||
|
// SIZE == 0 : Uses a single stage flop (axi_fifo_flop)
|
||||||
|
// SIZE == 1 : Uses a two-stage flop (axi_fifo_flop2). Best choice for single
|
||||||
|
// stage pipelining. Breaks combinatorial paths on the AXI stream
|
||||||
|
// data / control lines at the cost of additional registers. Maps
|
||||||
|
// to SLICELs (i.e. does not use distributed RAM).
|
||||||
|
// SIZE <= 5 : Uses SRL32 to efficient maps a 32 deep FIFO to SLICEMs
|
||||||
|
// (axi_fifo_short). Not recommended for pipelining as most
|
||||||
|
// devices have twice as many SLICELs as SLICEMs.
|
||||||
|
// SIZE > 5 : Uses BRAM FIFO (axi_fifo_bram)
|
||||||
|
//
|
||||||
|
|
||||||
// General FIFO block
|
`default_nettype none
|
||||||
// Size == 0: Uses a single stage flop (axi_fifo_flop).
|
|
||||||
// Size == 1: Uses a two stage flop (axi_fifo_flop2). Best choice for single stage pipelining.
|
|
||||||
// Breaks combinatorial paths on the AXI stream data / control lines at the cost of
|
|
||||||
// additional registers. Maps to SLICELs (i.e. does not use distributed RAM).
|
|
||||||
// Size <= 5: Uses SRL32 to efficient maps a 32 deep FIFO to SLICEMs (axi_fifo_short). Not
|
|
||||||
// recommended for pipelining as most devices have twice as many SLICELs as SLICEMs.
|
|
||||||
// Size > 5: Uses BRAM fifo (axi_fifo_bram)
|
|
||||||
|
|
||||||
module axi_fifo
|
|
||||||
#(parameter WIDTH=32, SIZE=5)
|
|
||||||
(input clk, input reset, input clear,
|
|
||||||
input [WIDTH-1:0] i_tdata,
|
|
||||||
input i_tvalid,
|
|
||||||
output i_tready,
|
|
||||||
output [WIDTH-1:0] o_tdata,
|
|
||||||
output o_tvalid,
|
|
||||||
input o_tready,
|
|
||||||
|
|
||||||
output [15:0] space,
|
module axi_fifo #(
|
||||||
output [15:0] occupied);
|
parameter WIDTH = 32,
|
||||||
|
parameter SIZE = 5
|
||||||
|
) (
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
input wire clear,
|
||||||
|
|
||||||
|
input wire [WIDTH-1:0] i_tdata,
|
||||||
|
input wire i_tvalid,
|
||||||
|
output wire i_tready,
|
||||||
|
|
||||||
|
output wire [WIDTH-1:0] o_tdata,
|
||||||
|
output wire o_tvalid,
|
||||||
|
input wire o_tready,
|
||||||
|
|
||||||
|
output wire [ 15:0] space,
|
||||||
|
output wire [ 15:0] occupied
|
||||||
|
);
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if(SIZE==0)
|
if (SIZE < 0) begin : gen_no_fifo
|
||||||
begin
|
assign o_tdata = i_tdata;
|
||||||
axi_fifo_flop #(.WIDTH(WIDTH)) fifo_flop
|
assign o_tvalid = i_tvalid;
|
||||||
(.clk(clk), .reset(reset), .clear(clear),
|
assign i_tready = o_tready;
|
||||||
.i_tdata(i_tdata), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
end
|
||||||
.o_tdata(o_tdata), .o_tvalid(o_tvalid), .o_tready(o_tready),
|
if (SIZE == 0) begin : gen_fifo_flop
|
||||||
.space(space[0]), .occupied(occupied[0]));
|
axi_fifo_flop #(
|
||||||
assign space[15:1] = 15'd0;
|
.WIDTH(WIDTH)
|
||||||
assign occupied[15:1] = 15'd0;
|
) fifo_flop (
|
||||||
end
|
.clk (clk),
|
||||||
else if(SIZE==1)
|
.reset (reset),
|
||||||
begin
|
.clear (clear),
|
||||||
axi_fifo_flop2 #(.WIDTH(WIDTH)) fifo_flop2
|
.i_tdata (i_tdata),
|
||||||
(.clk(clk), .reset(reset), .clear(clear),
|
.i_tvalid(i_tvalid),
|
||||||
.i_tdata(i_tdata), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
.i_tready(i_tready),
|
||||||
.o_tdata(o_tdata), .o_tvalid(o_tvalid), .o_tready(o_tready),
|
.o_tdata (o_tdata),
|
||||||
.space(space[1:0]), .occupied(occupied[1:0]));
|
.o_tvalid(o_tvalid),
|
||||||
assign space[15:2] = 14'd0;
|
.o_tready(o_tready),
|
||||||
assign occupied[15:2] = 14'd0;
|
.space (space[0]),
|
||||||
end
|
.occupied(occupied[0])
|
||||||
else if(SIZE<=5)
|
);
|
||||||
begin
|
assign space[15:1] = 15'd0;
|
||||||
axi_fifo_short #(.WIDTH(WIDTH)) fifo_short
|
assign occupied[15:1] = 15'd0;
|
||||||
(.clk(clk), .reset(reset), .clear(clear),
|
end
|
||||||
.i_tdata(i_tdata), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
else if (SIZE == 1) begin : gen_fifo_flop2
|
||||||
.o_tdata(o_tdata), .o_tvalid(o_tvalid), .o_tready(o_tready),
|
axi_fifo_flop2 #(
|
||||||
.space(space[5:0]), .occupied(occupied[5:0]));
|
.WIDTH(WIDTH)
|
||||||
assign space[15:6] = 10'd0;
|
) fifo_flop2 (
|
||||||
assign occupied[15:6] = 10'd0;
|
.clk (clk),
|
||||||
end
|
.reset (reset),
|
||||||
else
|
.clear (clear),
|
||||||
begin
|
.i_tdata (i_tdata),
|
||||||
axi_fifo_bram #(.WIDTH(WIDTH), .SIZE(SIZE)) fifo_bram
|
.i_tvalid(i_tvalid),
|
||||||
(.clk(clk), .reset(reset), .clear(clear),
|
.i_tready(i_tready),
|
||||||
.i_tdata(i_tdata), .i_tvalid(i_tvalid), .i_tready(i_tready),
|
.o_tdata (o_tdata),
|
||||||
.o_tdata(o_tdata), .o_tvalid(o_tvalid), .o_tready(o_tready),
|
.o_tvalid(o_tvalid),
|
||||||
.space(space), .occupied(occupied));
|
.o_tready(o_tready),
|
||||||
end
|
.space (space[1:0]),
|
||||||
|
.occupied(occupied[1:0])
|
||||||
|
);
|
||||||
|
assign space[15:2] = 14'd0;
|
||||||
|
assign occupied[15:2] = 14'd0;
|
||||||
|
end
|
||||||
|
else if (SIZE <= 5) begin : gen_fifo_short
|
||||||
|
axi_fifo_short #(
|
||||||
|
.WIDTH(WIDTH)
|
||||||
|
) fifo_short (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.clear (clear),
|
||||||
|
.i_tdata (i_tdata),
|
||||||
|
.i_tvalid(i_tvalid),
|
||||||
|
.i_tready(i_tready),
|
||||||
|
.o_tdata (o_tdata),
|
||||||
|
.o_tvalid(o_tvalid),
|
||||||
|
.o_tready(o_tready),
|
||||||
|
.space (space[5:0]),
|
||||||
|
.occupied(occupied[5:0])
|
||||||
|
);
|
||||||
|
assign space[15:6] = 10'd0;
|
||||||
|
assign occupied[15:6] = 10'd0;
|
||||||
|
end
|
||||||
|
else begin : gen_fifo_bram
|
||||||
|
axi_fifo_bram #(
|
||||||
|
.WIDTH(WIDTH),
|
||||||
|
.SIZE (SIZE)
|
||||||
|
) fifo_bram (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.clear (clear),
|
||||||
|
.i_tdata (i_tdata),
|
||||||
|
.i_tvalid(i_tvalid),
|
||||||
|
.i_tready(i_tready),
|
||||||
|
.o_tdata (o_tdata),
|
||||||
|
.o_tvalid(o_tvalid),
|
||||||
|
.o_tready(o_tready),
|
||||||
|
.space (space),
|
||||||
|
.occupied(occupied)
|
||||||
|
);
|
||||||
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
endmodule // axi_fifo
|
endmodule // axi_fifo
|
||||||
|
|
||||||
|
|
||||||
|
`default_nettype wire
|
||||||
|
|||||||
Reference in New Issue
Block a user