mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
fpga: lib: enable XPM fifo for all Xilinx FPGAs
This commit is contained in:
parent
0b80e7f011
commit
04bb66663e
@ -88,18 +88,6 @@ module axi_fifo_2clk #(
|
||||
wire o_ext_tvalid;
|
||||
wire o_ext_tready;
|
||||
|
||||
// Derive constants based on device. The XPM-based FIFO is not yet supported
|
||||
// on some devices. Deriving a local parameter to use for later checks.
|
||||
`ifdef X300
|
||||
localparam USE_LEGACY_FIFO = 1;
|
||||
`elsif X310
|
||||
localparam USE_LEGACY_FIFO = 1;
|
||||
`elsif B310
|
||||
localparam USE_LEGACY_FIFO = 1;
|
||||
`else
|
||||
localparam USE_LEGACY_FIFO = 0;
|
||||
`endif
|
||||
|
||||
// First triple of values is for Intel's MAX10 FPGAs. The FIFO generator for
|
||||
// those devices supports embedded memory only (SRL_THRESHOLD = 0).
|
||||
// The later triple has been optimized for Xilinx 7Series FPGAs. They also
|
||||
@ -123,10 +111,15 @@ module axi_fifo_2clk #(
|
||||
|
||||
generate
|
||||
// XPM-based FIFO for Xilinx FPGAs, except for the certain devices.
|
||||
if (DEVICE != "MAX10" && !USE_LEGACY_FIFO) begin: xpm_fifo_section
|
||||
if (DEVICE != "MAX10") begin: xpm_fifo_section
|
||||
localparam XPM_SIZE = (SIZE < SRL_THRESHOLD) ? SRL_THRESHOLD : SIZE;
|
||||
localparam TYPE = (SIZE < RAM_THRESHOLD) ? "distributed" : "block";
|
||||
|
||||
fifo_xpm_2clk #(.WIDTH(WIDTH), .DEPTH(1 << XPM_SIZE)) impl_xpm_i (
|
||||
fifo_xpm_2clk #(
|
||||
.WIDTH(WIDTH),
|
||||
.DEPTH(2**XPM_SIZE),
|
||||
.TYPE(TYPE)
|
||||
) impl_xpm_i (
|
||||
.rst (i_arst),
|
||||
.wr_clk (i_aclk),
|
||||
.din (i_pipe_tdata),
|
||||
@ -139,6 +132,9 @@ module axi_fifo_2clk #(
|
||||
.empty (fifo_empty),
|
||||
.rd_data_count()
|
||||
);
|
||||
|
||||
assign {o_pipe_tdata, o_pipe_tvalid} = {o_ext_tdata, o_ext_tvalid};
|
||||
assign o_ext_tready = o_pipe_tready;
|
||||
end else begin: legacy_fifo_section
|
||||
wire [INT_WIDTH-1:0] wr_data, rd_data;
|
||||
wire [NUM_FIFOS-1:0] full, empty;
|
||||
@ -180,38 +176,28 @@ module axi_fifo_2clk #(
|
||||
);
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//----------------------------------------------
|
||||
// Extension FIFO (for large sizes)
|
||||
//----------------------------------------------
|
||||
|
||||
generate
|
||||
if (SIZE > RAM_THRESHOLD) begin
|
||||
wire [WIDTH-1:0] ext_pipe_tdata;
|
||||
wire ext_pipe_tvalid;
|
||||
wire ext_pipe_tready;
|
||||
|
||||
// Add a register slice between BRAM cascades
|
||||
axi_fifo_flop2 #(.WIDTH(WIDTH)) ext_fifo_pipe_i (
|
||||
.clk(o_aclk), .reset(o_arst), .clear(1'b0),
|
||||
.i_tdata(o_ext_tdata), .i_tvalid(o_ext_tvalid), .i_tready(o_ext_tready),
|
||||
.o_tdata(ext_pipe_tdata), .o_tvalid(ext_pipe_tvalid), .o_tready(ext_pipe_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
// Bolt on an extension FIFO if the requested depth is larger than the BRAM
|
||||
// 2clk FIFO primitive (IP)
|
||||
axi_fifo_bram #(.WIDTH(WIDTH), .SIZE(SIZE)) ext_fifo_i (
|
||||
.clk(o_aclk), .reset(o_arst), .clear(1'b0),
|
||||
.i_tdata(ext_pipe_tdata), .i_tvalid(ext_pipe_tvalid), .i_tready(ext_pipe_tready),
|
||||
.o_tdata(o_pipe_tdata), .o_tvalid(o_pipe_tvalid), .o_tready(o_pipe_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
end else begin
|
||||
assign {o_pipe_tdata, o_pipe_tvalid} = {o_ext_tdata, o_ext_tvalid};
|
||||
assign o_ext_tready = o_pipe_tready;
|
||||
//----------------------------------------------
|
||||
// Extension FIFO (for large sizes)
|
||||
//----------------------------------------------
|
||||
if (SIZE > RAM_THRESHOLD) begin
|
||||
// Bolt on an extension FIFO if the requested depth is larger than the BRAM
|
||||
// 2clk FIFO primitive (IP)
|
||||
axi_fifo_large #(
|
||||
.WIDTH(WIDTH),
|
||||
.DEPTH(2**SIZE - 2**RAM_THRESHOLD),
|
||||
.DEVICE(DEVICE),
|
||||
.MAX_NUM_URAM_BLOCKS(0)
|
||||
) ext_fifo_i (
|
||||
.clk(o_aclk), .reset(o_arst), .clear(1'b0),
|
||||
.i_tdata(o_ext_tdata), .i_tvalid(o_ext_tvalid), .i_tready(o_ext_tready),
|
||||
.o_tdata(o_pipe_tdata), .o_tvalid(o_pipe_tvalid), .o_tready(o_pipe_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
end else begin
|
||||
assign {o_pipe_tdata, o_pipe_tvalid} = {o_ext_tdata, o_ext_tvalid};
|
||||
assign o_ext_tready = o_pipe_tready;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
@ -9,18 +9,20 @@
|
||||
//
|
||||
// Asynchronous dual-clock FIFO implemented with Xilinx XPM FIFO
|
||||
// primitives. The FIFO uses first-word fall-through read mode and
|
||||
// provides the interface used by fifo_short_2clk.
|
||||
// provides the dual-clock FIFO interface used by the FPGA projects.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// WIDTH: Width of the input and output data buses.
|
||||
// DEPTH: Number of entries in the FIFO. Must be a power of two between
|
||||
// 16 and 4194304.
|
||||
// TYPE: Type of memory to use for the FIFO. Can be "auto", "block", or "distributed".
|
||||
//
|
||||
|
||||
module fifo_xpm_2clk #(
|
||||
int WIDTH = 72,
|
||||
int DEPTH = 32
|
||||
int DEPTH = 32,
|
||||
string TYPE = "auto"
|
||||
)(
|
||||
input logic rst,
|
||||
input logic wr_clk,
|
||||
@ -46,12 +48,20 @@ module fifo_xpm_2clk #(
|
||||
|
||||
localparam int COUNT_WIDTH = $clog2(DEPTH) + 1;
|
||||
|
||||
logic xpm_full;
|
||||
logic xpm_empty;
|
||||
logic wr_rst_busy;
|
||||
logic rd_rst_busy;
|
||||
|
||||
assign full = xpm_full | wr_rst_busy;
|
||||
assign empty = xpm_empty | rd_rst_busy;
|
||||
|
||||
xpm_fifo_async #(
|
||||
.CASCADE_HEIGHT (0),
|
||||
.CDC_SYNC_STAGES (3),
|
||||
.DOUT_RESET_VALUE ("0"),
|
||||
.ECC_MODE ("no_ecc"),
|
||||
.FIFO_MEMORY_TYPE ("auto"),
|
||||
.FIFO_MEMORY_TYPE (TYPE),
|
||||
.FIFO_READ_LATENCY (0),
|
||||
.FIFO_WRITE_DEPTH (DEPTH),
|
||||
.FULL_RESET_VALUE (1),
|
||||
@ -72,18 +82,18 @@ module fifo_xpm_2clk #(
|
||||
.data_valid (),
|
||||
.dbiterr (),
|
||||
.dout (dout),
|
||||
.empty (empty),
|
||||
.full (full),
|
||||
.empty (xpm_empty),
|
||||
.full (xpm_full),
|
||||
.overflow (),
|
||||
.prog_empty (),
|
||||
.prog_full (),
|
||||
.rd_data_count (rd_data_count),
|
||||
.rd_rst_busy (),
|
||||
.rd_rst_busy (rd_rst_busy),
|
||||
.sbiterr (),
|
||||
.underflow (),
|
||||
.wr_ack (),
|
||||
.wr_data_count (wr_data_count),
|
||||
.wr_rst_busy (),
|
||||
.wr_rst_busy (wr_rst_busy),
|
||||
.din (din),
|
||||
.injectdbiterr (1'b0),
|
||||
.injectsbiterr (1'b0),
|
||||
|
||||
@ -169,6 +169,9 @@ proc ::vivado_utils::synthesize_design {args} {
|
||||
variable g_verilog_defs
|
||||
variable g_include_dirs
|
||||
|
||||
# automatically detect xpm libraries and include the respective libraries
|
||||
auto_detect_xpm
|
||||
|
||||
set vdef_args ""
|
||||
foreach vdef $g_verilog_defs {
|
||||
set vdef_args [concat $vdef_args "-verilog_define $vdef"]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user