1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
//
// Copyright 2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
module chdr_fifo_large #(
parameter SIZE = 12,
parameter DEVICE = "7SERIES"
) (
input clk,
input reset,
input clear,
input [63:0] i_tdata,
input i_tlast,
input i_tvalid,
output i_tready,
output [63:0] o_tdata,
output o_tlast,
output o_tvalid,
input o_tready
);
localparam SIZE_THRESHOLD = (
(DEVICE == "7SERIES") ? 14 : (
(DEVICE == "VIRTEX6") ? 14 : (
(DEVICE == "SPARTAN6") ? 12 : (
12
))));
wire [63:0] i_tdata_pre;
wire i_tlast_pre, i_tvalid_pre, i_tready_pre;
// SRL based FIFO to break timing paths to BRAM resources
axi_fifo_flop2 #(.WIDTH(65)) pre_fifo (
.clk(clk), .reset(reset), .clear(clear),
.i_tdata({i_tlast, i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
.o_tdata({i_tlast_pre, i_tdata_pre}), .o_tvalid(i_tvalid_pre), .o_tready(i_tready_pre),
.space(), .occupied()
);
generate
if (SIZE <= SIZE_THRESHOLD) begin
wire [63:0] o_tdata_int;
wire o_tlast_int, o_tvalid_int, o_tready_int;
// Instantiate a single axi_fifo if size is not larger than threshold
axi_fifo #(.WIDTH(65), .SIZE(SIZE)) main_fifo (
.clk(clk), .reset(reset), .clear(clear),
.i_tdata({i_tlast_pre, i_tdata_pre}), .i_tvalid(i_tvalid_pre), .i_tready(i_tready_pre),
.o_tdata({o_tlast_int, o_tdata_int}), .o_tvalid(o_tvalid_int), .o_tready(o_tready_int),
.space(), .occupied()
);
axi_fifo_flop2 #(.WIDTH(65)) fifo_flop2 (
.clk(clk), .reset(reset), .clear(clear),
.i_tdata({o_tlast_int, o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
.o_tdata({o_tlast, o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
.space(), .occupied()
);
end else begin
// Instantiate a cascade of axi_fifos if size is larger than threshold
localparam CDEPTH = 2**(SIZE - SIZE_THRESHOLD); //Cascade Depth
wire [63:0] c_tdata[CDEPTH:0], int_tdata[CDEPTH-1:0];
wire c_tlast[CDEPTH:0], c_tvalid[CDEPTH:0], c_tready[CDEPTH:0];
wire int_tlast[CDEPTH-1:0], int_tvalid[CDEPTH-1:0], int_tready[CDEPTH-1:0];
//Connect input to first cascade state
assign {c_tdata[0], c_tlast[0], c_tvalid[0]} = {i_tdata_pre, i_tlast_pre, i_tvalid_pre};
assign i_tready_pre = c_tready[0];
//Connect output to last cascade state
assign {o_tdata, o_tlast, o_tvalid} = {c_tdata[CDEPTH], c_tlast[CDEPTH], c_tvalid[CDEPTH]};
assign c_tready[CDEPTH] = o_tready;
genvar i;
for (i=0; i<CDEPTH; i=i+1) begin: fifo_stages
axi_fifo #(.WIDTH(65), .SIZE(SIZE_THRESHOLD)) main_fifo (
.clk(clk), .reset(reset), .clear(clear),
.i_tdata({c_tlast[i], c_tdata[i]}), .i_tvalid(c_tvalid[i]), .i_tready(c_tready[i]),
.o_tdata({int_tlast[i], int_tdata[i]}), .o_tvalid(int_tvalid[i]), .o_tready(int_tready[i]),
.space(), .occupied()
);
axi_fifo_flop2 #(.WIDTH(65)) fifo_flop2 (
.clk(clk), .reset(reset), .clear(clear),
.i_tdata({int_tlast[i], int_tdata[i]}), .i_tvalid(int_tvalid[i]), .i_tready(int_tready[i]),
.o_tdata({c_tlast[i+1], c_tdata[i+1]}), .o_tvalid(c_tvalid[i+1]), .o_tready(c_tready[i+1]),
.space(), .occupied()
);
end
end
endgenerate
endmodule // axi_fifo_large
|