//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
module
|
module
|
axi4_m_to_read_fifos
|
axi4_m_to_read_fifos
|
#(
|
#(
|
A = 32, // address bus width
|
A, // address bus width
|
N = 8, // data bus width in bytes
|
N, // data bus width in bytes
|
I = 1, // ID width
|
I, // ID width
|
R_D = 32,
|
R_D,
|
AR_D = 2,
|
AR_D,
|
WATERMARK = 0,
|
WATERMARK = 0,
|
USE_ADVANCED_PROTOCOL = 0
|
USE_ADVANCED_PROTOCOL = 0
|
)
|
)
|
(
|
(
|
axi4_if axi4_m,
|
axi4_if axi4_m,
|
axi4_if axi4_read_fifo,
|
axi4_if axi4_read_fifo,
|
|
|
output ar_wr_full,
|
output ar_wr_full,
|
input ar_wr_en,
|
input ar_wr_en,
|
output r_rd_empty,
|
output r_rd_empty,
|
input r_rd_en,
|
input r_rd_en,
|
output r_topped_off,
|
output r_topped_off,
|
output r_watermark,
|
output r_watermark,
|
|
|
input aclk,
|
input aclk,
|
input aresetn
|
input aresetn
|
);
|
);
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
localparam UB = $clog2(R_D);
|
localparam UB = $clog2(R_D);
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
localparam R_W =
|
localparam R_W =
|
8*N + // logic [(8*N)-1:0] rdata;
|
8*N + // logic [(8*N)-1:0] rdata;
|
I + // logic [(I-1):0] rid;
|
I + // logic [(I-1):0] rid;
|
1 + // logic rlast;
|
1 + // logic rlast;
|
2; // logic [1:0] rresp;
|
2; // logic [1:0] rresp;
|
|
|
localparam AX_BASIC_W =
|
localparam AX_BASIC_W =
|
A + // logic [(A-1):0] axaddr;
|
A + // logic [(A-1):0] axaddr;
|
2 + // logic [1:0] axburst;
|
2 + // logic [1:0] axburst;
|
I + // logic [(I-1):0] axid;
|
I + // logic [(I-1):0] axid;
|
8 + // logic [7:0] axlen;
|
8 + // logic [7:0] axlen;
|
3; // logic [2:0] axsize;
|
3; // logic [2:0] axsize;
|
|
|
localparam AX_ADVANCED_W =
|
localparam AX_ADVANCED_W =
|
4 + // logic [3:0] axcache;
|
4 + // logic [3:0] axcache;
|
1 + // logic axlock;
|
1 + // logic axlock;
|
3 + // logic [2:0] axprot;
|
3 + // logic [2:0] axprot;
|
4 + // logic [3:0] axqos;
|
4 + // logic [3:0] axqos;
|
4; // logic [3:0] axregion;
|
4; // logic [3:0] axregion;
|
|
|
localparam AR_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W;
|
localparam AR_W = USE_ADVANCED_PROTOCOL ? AX_BASIC_W + AX_ADVANCED_W : AX_BASIC_W;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire [AR_W-1:0] ar_rd_data;
|
wire [AR_W-1:0] ar_rd_data;
|
wire [AR_W-1:0] ar_wr_data;
|
wire [AR_W-1:0] ar_wr_data;
|
|
|
generate
|
generate
|
begin: ar_data_gen
|
begin: ar_data_gen
|
if(USE_ADVANCED_PROTOCOL)
|
if(USE_ADVANCED_PROTOCOL)
|
begin
|
begin
|
assign ar_wr_data =
|
assign ar_wr_data =
|
{
|
{
|
axi4_read_fifo.araddr,
|
axi4_read_fifo.araddr,
|
axi4_read_fifo.arburst,
|
axi4_read_fifo.arburst,
|
axi4_read_fifo.arid,
|
axi4_read_fifo.arid,
|
axi4_read_fifo.arlen,
|
axi4_read_fifo.arlen,
|
axi4_read_fifo.arsize,
|
axi4_read_fifo.arsize,
|
axi4_read_fifo.arcache,
|
axi4_read_fifo.arcache,
|
axi4_read_fifo.arlock,
|
axi4_read_fifo.arlock,
|
axi4_read_fifo.arprot,
|
axi4_read_fifo.arprot,
|
axi4_read_fifo.arqos,
|
axi4_read_fifo.arqos,
|
axi4_read_fifo.arregion
|
axi4_read_fifo.arregion
|
};
|
};
|
|
|
assign
|
assign
|
{
|
{
|
axi4_m.araddr,
|
axi4_m.araddr,
|
axi4_m.arburst,
|
axi4_m.arburst,
|
axi4_m.arid,
|
axi4_m.arid,
|
axi4_m.arlen,
|
axi4_m.arlen,
|
axi4_m.arsize,
|
axi4_m.arsize,
|
axi4_m.arcache,
|
axi4_m.arcache,
|
axi4_m.arlock,
|
axi4_m.arlock,
|
axi4_m.arprot,
|
axi4_m.arprot,
|
axi4_m.arqos,
|
axi4_m.arqos,
|
axi4_m.arregion
|
axi4_m.arregion
|
} = ar_rd_data;
|
} = ar_rd_data;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
assign ar_wr_data =
|
assign ar_wr_data =
|
{
|
{
|
axi4_read_fifo.araddr,
|
axi4_read_fifo.araddr,
|
axi4_read_fifo.arburst,
|
axi4_read_fifo.arburst,
|
axi4_read_fifo.arid,
|
axi4_read_fifo.arid,
|
axi4_read_fifo.arlen,
|
axi4_read_fifo.arlen,
|
axi4_read_fifo.arsize
|
axi4_read_fifo.arsize
|
};
|
};
|
|
|
assign axi4_read_fifo.arcache = 0;
|
assign axi4_read_fifo.arcache = 0;
|
assign axi4_read_fifo.arlock = 0;
|
assign axi4_read_fifo.arlock = 0;
|
assign axi4_read_fifo.arprot = 0;
|
assign axi4_read_fifo.arprot = 0;
|
assign axi4_read_fifo.arqos = 0;
|
assign axi4_read_fifo.arqos = 0;
|
assign axi4_read_fifo.arregion = 0;
|
assign axi4_read_fifo.arregion = 0;
|
|
|
assign
|
assign
|
{
|
{
|
axi4_m.araddr,
|
axi4_m.araddr,
|
axi4_m.arburst,
|
axi4_m.arburst,
|
axi4_m.arid,
|
axi4_m.arid,
|
axi4_m.arlen,
|
axi4_m.arlen,
|
axi4_m.arsize
|
axi4_m.arsize
|
} = ar_rd_data;
|
} = ar_rd_data;
|
|
|
assign axi4_m.arcache = 0;
|
assign axi4_m.arcache = 0;
|
assign axi4_m.arlock = 0;
|
assign axi4_m.arlock = 0;
|
assign axi4_m.arprot = 0;
|
assign axi4_m.arprot = 0;
|
assign axi4_m.arqos = 0;
|
assign axi4_m.arqos = 0;
|
assign axi4_m.arregion = 0;
|
assign axi4_m.arregion = 0;
|
|
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire ar_rd_empty;
|
wire ar_rd_empty;
|
wire ar_rd_en = axi4_m.arready & axi4_m.arvalid;
|
wire ar_rd_en = axi4_m.arready & axi4_m.arvalid;
|
assign axi4_m.arvalid = ~ar_rd_empty;
|
assign axi4_m.arvalid = ~ar_rd_empty;
|
|
|
sync_fifo #(.W(AR_W), .D(AR_D))
|
sync_fifo #(.W(AR_W), .D(AR_D))
|
ar_fifo
|
ar_fifo
|
(
|
(
|
.wr_full(ar_wr_full),
|
.wr_full(ar_wr_full),
|
.wr_data(ar_wr_data),
|
.wr_data(ar_wr_data),
|
.wr_en(ar_wr_en),
|
.wr_en(ar_wr_en),
|
.rd_empty(ar_rd_empty),
|
.rd_empty(ar_rd_empty),
|
.rd_data(ar_rd_data),
|
.rd_data(ar_rd_data),
|
.rd_en(ar_rd_en),
|
.rd_en(ar_rd_en),
|
.count(),
|
.count(),
|
.clk(aclk),
|
.clk(aclk),
|
.reset(~aresetn)
|
.reset(~aresetn)
|
);
|
);
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire [R_W-1:0] r_rd_data;
|
wire [R_W-1:0] r_rd_data;
|
wire [R_W-1:0] r_wr_data;
|
wire [R_W-1:0] r_wr_data;
|
|
|
assign r_wr_data =
|
assign r_wr_data =
|
{
|
{
|
axi4_m.rdata,
|
|
axi4_m.rid,
|
axi4_m.rid,
|
|
axi4_m.rresp,
|
axi4_m.rlast,
|
axi4_m.rlast,
|
axi4_m.rresp
|
axi4_m.rdata
|
};
|
};
|
|
|
assign
|
assign
|
{
|
{
|
axi4_read_fifo.rdata,
|
|
axi4_read_fifo.rid,
|
axi4_read_fifo.rid,
|
|
axi4_read_fifo.rresp,
|
axi4_read_fifo.rlast,
|
axi4_read_fifo.rlast,
|
axi4_read_fifo.rresp
|
axi4_read_fifo.rdata
|
} = r_rd_data;
|
} = r_rd_data;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire [UB:0] r_count;
|
wire [UB:0] r_count;
|
|
|
generate
|
generate
|
begin: r_watermark_gen
|
begin: r_watermark_gen
|
if(WATERMARK == 0)
|
if(WATERMARK == 0)
|
begin
|
begin
|
assign r_topped_off = 1;
|
assign r_topped_off = 1;
|
assign r_watermark = 0;
|
assign r_watermark = 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
reg r_topped_off_r;
|
reg r_topped_off_r;
|
assign r_topped_off = r_topped_off_r;
|
assign r_topped_off = r_topped_off_r;
|
assign r_watermark = r_count > WATERMARK - 1;
|
assign r_watermark = r_count > WATERMARK - 1;
|
|
|
always_ff @(posedge aclk)
|
always_ff @(posedge aclk)
|
if(~aresetn | r_rd_empty)
|
if(~aresetn | r_rd_empty)
|
r_topped_off_r <= 0;
|
r_topped_off_r <= 0;
|
else if(r_watermark)
|
else if(r_watermark)
|
r_topped_off_r <= 1;
|
r_topped_off_r <= 1;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire r_wr_full;
|
wire r_wr_full;
|
wire r_wr_en = axi4_m.rready & axi4_m.rvalid;
|
wire r_wr_en = axi4_m.rready & axi4_m.rvalid;
|
assign axi4_m.rready = ~r_wr_full;
|
assign axi4_m.rready = ~r_wr_full;
|
|
|
sync_fifo #(.W(R_W), .D(R_D))
|
sync_fifo #(.W(R_W), .D(R_D))
|
r_fifo
|
r_fifo
|
(
|
(
|
.wr_full(r_wr_full),
|
.wr_full(r_wr_full),
|
.wr_data(r_wr_data),
|
.wr_data(r_wr_data),
|
.wr_en(r_wr_en),
|
.wr_en(r_wr_en),
|
.rd_empty(r_rd_empty),
|
.rd_empty(r_rd_empty),
|
.rd_data(r_rd_data),
|
.rd_data(r_rd_data),
|
.rd_en(r_rd_en),
|
.rd_en(r_rd_en),
|
.count(r_count),
|
.count(r_count),
|
.clk(aclk),
|
.clk(aclk),
|
.reset(~aresetn)
|
.reset(~aresetn)
|
);
|
);
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
|
|
endmodule
|
endmodule
|
|
|
|
|