URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
Compare Revisions
- This comparison shows the changes necessary to convert path
/qaz_libs/trunk/axi4_stream_lib/src
- from Rev 30 to Rev 31
- ↔ Reverse comparison
Rev 30 → Rev 31
/axis_alias.sv
27,14 → 27,6
|
module |
axis_alias |
#( |
N = 8, // data bus width in bytes |
I = 1, // TID width |
D = 1, // TDEST width |
U = 1, // TUSER width |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0 // set to 1 to enable, 0 to disable |
) |
( |
axis_if axis_in, |
axis_if axis_out |
/axis_downsizer.sv
0,0 → 1,218
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_downsizer |
#( |
N, // data bus width in bytes |
I = 1, // TID width |
D = 1, // TDEST width |
U, // TUSER width |
S, // tdata size divisor |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0, // set to 1 to enable, 0 to disable |
BYTES_PER_TUSER // bytes per tuser bit. Set to 0 for transfer based. |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
a_divisor: assert(S > 1) else $fatal; |
a_tdata_mod: assert(N % S == 0) else $fatal; |
a_tstrb_unsuported: assert(USE_TSTRB == 0) else $fatal; |
a_tkeep_unsuported: assert(USE_TKEEP == 0) else $fatal; |
a_bytes_per_tuser: assert((BYTES_PER_TUSER == 0) | (N % BYTES_PER_TUSER == 0)) else $fatal; |
a_tuser: assert((BYTES_PER_TUSER == 0) | (U % S == 0)) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
localparam M_A = $clog2(S); |
localparam M_D = 2 ** M_A; |
localparam M_NW = (N*8)/ S; |
localparam M_UW = U / S; |
|
|
// -------------------------------------------------------------------- |
// |
localparam U_OUT = (BYTES_PER_TUSER == 0) ? U : U / (N / BYTES_PER_TUSER); |
axis_if #(.N(N/S), .U(U_OUT)) axis_downsizer_bus(.*); |
|
|
// -------------------------------------------------------------------- |
// |
wire almost_last_word; |
|
|
//--------------------------------------------------- |
// state machine binary definitions |
enum reg [2:0] |
{ |
GET_WORD_IN = 3'b001, |
MUX_WORD_OUT = 3'b010, |
LAST_WORD_OUT = 3'b100 |
} state, next_state; |
|
|
//--------------------------------------------------- |
// state machine flop |
always_ff @(posedge aclk) |
if(~aresetn) |
state <= GET_WORD_IN; |
else |
state <= next_state; |
|
|
//--------------------------------------------------- |
// state machine |
always_comb |
case(state) |
GET_WORD_IN: if(axis_in.tvalid) |
next_state <= MUX_WORD_OUT; |
else |
next_state <= GET_WORD_IN; |
|
MUX_WORD_OUT: if(almost_last_word & axis_downsizer_bus.tready) |
next_state <= LAST_WORD_OUT; |
else |
next_state <= MUX_WORD_OUT; |
|
LAST_WORD_OUT: if(~axis_downsizer_bus.tready) |
next_state <= LAST_WORD_OUT; |
else if(axis_in.tvalid) |
next_state <= MUX_WORD_OUT; |
else |
next_state <= GET_WORD_IN; |
|
default: next_state <= GET_WORD_IN; |
|
endcase |
|
|
// -------------------------------------------------------------------- |
// |
reg [(8*N)-1:0] tdata_r; |
reg [I-1:0] tid_r; |
reg [D-1:0] tdest_r; |
reg tlast_r; |
reg [U-1:0] tuser_r; |
|
always_ff @(posedge aclk) |
if(axis_in.tvalid & axis_in.tready) |
begin |
tdata_r <= axis_in.tdata; |
tid_r <= axis_in.tid; |
tdest_r <= axis_in.tdest; |
tlast_r <= axis_in.tlast; // packet width % S == 0 else tlast becomes invalid |
tuser_r <= axis_in.tuser; |
end |
|
|
// -------------------------------------------------------------------- |
// |
reg [M_A-1:0] select; |
assign almost_last_word = (select == S - 2); |
|
always_ff @(posedge aclk) |
if(~aresetn | (state == GET_WORD_IN)) |
select <= 0; |
else if(axis_downsizer_bus.tvalid & axis_downsizer_bus.tready) |
select <= select + 1; |
|
|
// -------------------------------------------------------------------- |
// |
wire [M_NW-1:0] mux_in_tdata [M_D-1:0]; |
wire [M_NW-1:0] mux_out_tdata; |
|
recursive_mux #(.A(M_A), .W(M_NW)) |
tdata_mux_i(.data_in(mux_in_tdata), .data_out(mux_out_tdata), .*); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: tdata_gen |
for(genvar j = 0; j < M_D; j++) |
assign mux_in_tdata[j] = tdata_r[j*M_NW +: M_NW]; |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: tuser_gen |
if(BYTES_PER_TUSER != 0) |
begin |
wire [M_UW-1:0] mux_in_tuser [M_D-1:0]; |
|
recursive_mux #(.A(M_A), .W(M_UW)) |
tuser_mux_i(.data_in(mux_in_tuser), .data_out(axis_downsizer_bus.tuser), .*); |
|
for(genvar j = 0; j < M_D; j++) |
assign mux_in_tuser[j] = tuser_r[j*M_UW +: M_UW] & {M_UW{axis_downsizer_bus.tvalid}}; |
end |
else |
assign axis_downsizer_bus.tuser = tuser_r & {U{axis_downsizer_bus.tvalid}}; |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = (state == GET_WORD_IN) | |
((state == LAST_WORD_OUT) & (next_state == MUX_WORD_OUT)); |
assign axis_downsizer_bus.tvalid = (state != GET_WORD_IN); |
|
assign axis_downsizer_bus.tdata = mux_out_tdata; |
assign axis_downsizer_bus.tid = tid_r; |
assign axis_downsizer_bus.tdest = tdest_r; |
assign axis_downsizer_bus.tlast = (select == S - 1) ? tlast_r : 1'b0; |
|
|
// -------------------------------------------------------------------- |
// |
axis_register_slice #(.N(N), .U(U)) |
axis_register_slice_i(.axis_in(axis_downsizer_bus), .*); |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
|
/axis_if.sv
29,7 → 29,7
interface |
axis_if |
#( |
N = 8, // data bus width in bytes |
N = 0, // data bus width in bytes |
I = 1, // TID width |
D = 1, // TDEST width |
U = 1 // TUSER width |
38,56 → 38,60
input aclk, |
input aresetn |
); |
wire tvalid; |
wire tready; |
wire [(8*N)-1:0] tdata; |
wire [N-1:0] tstrb; |
wire [N-1:0] tkeep; |
wire tlast; |
wire [I-1:0] tid; |
wire [D-1:0] tdest; |
wire [U-1:0] tuser; |
wire tvalid; |
wire tready; |
wire [(8*N)-1:0] tdata; |
wire [N-1:0] tstrb; |
wire [N-1:0] tkeep; |
wire tlast; |
wire [I-1:0] tid; |
wire [D-1:0] tdest; |
wire [U-1:0] tuser; |
|
|
// -------------------------------------------------------------------- |
// |
default clocking cb_m @(posedge aclk iff aresetn); |
input aresetn; |
input aclk; |
output tvalid; |
input tready; |
output tdata; |
output tstrb; |
output tkeep; |
output tlast; |
output tid; |
output tdest; |
output tuser; |
endclocking |
// -------------------------------------------------------------------- |
// synthesis translate_off |
default clocking cb_m @(posedge aclk iff aresetn); |
output tvalid; |
input tready; |
output tdata; |
output tstrb; |
output tkeep; |
output tlast; |
output tid; |
output tdest; |
output tuser; |
endclocking |
|
|
// -------------------------------------------------------------------- |
// |
clocking cb_s @(posedge aclk iff aresetn); |
input aresetn; |
input aclk; |
input tvalid; |
output tready; |
input tdata; |
input tstrb; |
input tkeep; |
input tlast; |
input tid; |
input tdest; |
input tuser; |
endclocking |
// -------------------------------------------------------------------- |
// |
clocking cb_s @(posedge aclk iff aresetn); |
input tvalid; |
output tready; |
input tdata; |
input tstrb; |
input tkeep; |
input tlast; |
input tid; |
input tdest; |
input tuser; |
endclocking |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
// |
`ifdef USE_MOD_PORTS |
modport |
master |
( |
// -------------------------------------------------------------------- |
// synthesis translate_off |
clocking cb_m, |
// synthesis translate_on |
// -------------------------------------------------------------------- |
input aresetn, |
input aclk, |
output tvalid, |
98,8 → 102,7
output tlast, |
output tid, |
output tdest, |
output tuser, |
clocking cb_m |
output tuser |
); |
|
|
108,6 → 111,11
modport |
slave |
( |
// -------------------------------------------------------------------- |
// synthesis translate_off |
clocking cb_s, |
// synthesis translate_on |
// -------------------------------------------------------------------- |
input aresetn, |
input aclk, |
input tvalid, |
118,11 → 126,24
input tlast, |
input tid, |
input tdest, |
input tuser, |
clocking cb_s |
input tuser |
); |
`endif |
|
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
task |
zero_cycle_delay; |
|
##0; |
|
endtask: zero_cycle_delay |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
endinterface: axis_if |
|
|
/axis_map_fifo.sv
0,0 → 1,141
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_map_fifo |
#( |
N = 8, // data bus width in bytes |
I = 0, // TID width |
D = 0, // TDEST width |
U = 1, // TUSER width |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0, // set to 1 to enable, 0 to disable |
USE_XID = 0, // set to 1 to enable, 0 to disable |
W = 0 |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
output [W-1:0] wr_data, |
input [W-1:0] rd_data, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
a_tid_unsuported: assert(I == 0) else $fatal; |
a_tdest_unsuported: assert(D == 0) else $fatal; |
a_xid_unsuported: assert(USE_XID == 0) else $fatal; |
a_w: assert(W == (N * 8) + (N * USE_TSTRB) + (N * USE_TKEEP) + I + D + U + 1) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: assign_gen |
if(USE_TSTRB & USE_TKEEP) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tstrb, |
axis_in.tkeep |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tstrb, |
axis_out.tkeep |
} = rd_data; |
end |
else if(USE_TSTRB) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tstrb |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tstrb |
} = rd_data; |
end |
else if(USE_TKEEP) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tkeep |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tkeep |
} = rd_data; |
end |
else |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser |
} = rd_data; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/axis_mux.sv
28,26 → 28,37
module |
axis_mux |
#( |
N = 8, // data bus width in bytes |
I = 1, // TID width |
D = 1, // TDEST width |
N, // data bus width in bytes |
I = 0, // TID width |
D = 0, // TDEST width |
U = 1, // TUSER width |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0 // set to 1 to enable, 0 to disable |
) |
( |
input mux_select, |
axis_if.slave axis_0_in, |
axis_if.slave axis_1_in, |
axis_if.master axis_out, |
input axis_en, |
input aclk, |
input aresetn |
input mux_select, |
axis_if axis_0_in, |
axis_if axis_1_in, |
axis_if axis_out, |
input axis_en, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
a_tid_unsuported: assert(I == 0) else $fatal; |
a_tdest_unsuported: assert(D == 0) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
axis_if #(.N(N), .I(I), .D(D), .U(U)) |
axis_if #(.N(N), .I(1), .D(1), .U(U)) |
axis_mux_out(.*); |
|
assign axis_0_in.tready = mux_select ? 0 : axis_mux_out.tready; |
/axis_register_slice.sv
36,48 → 36,49
USE_TKEEP = 0 // set to 1 to enable, 0 to disable |
) |
( |
input axis_en, |
axis_if.slave axis_in, |
axis_if.master axis_out, |
input aclk, |
input aresetn |
axis_if axis_in, |
axis_if axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
a_tid_unsuported: assert(I == 0) else $fatal; |
a_tdest_unsuported: assert(D == 0) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
localparam W = (N * 8) + (N * USE_TSTRB) + (N * USE_TKEEP) + I + D + U + 1; |
|
fifo_write_if #(.W(W)) fifo_sink(aclk, ~aresetn); |
fifo_read_if #(.W(W)) fifo_source(aclk, ~aresetn); |
|
tiny_sync_fifo #(.W(W)) |
tiny_sync_fifo_i(.source(fifo_sink.fifo), .sink(fifo_source.fifo)); |
|
|
// -------------------------------------------------------------------- |
// |
wire data_to_axis_fsm_error; |
wire wr_full; |
wire [W-1:0] wr_data; |
wire wr_en; |
|
data_to_axis_fsm |
data_to_axis_fsm_i |
( |
.axis_tvalid(axis_out.tvalid), |
.axis_tready(axis_out.tready), |
.fifo_empty(fifo_source.empty), |
.fifo_rd_en(fifo_source.rd_en), |
.fifo_watermark(1'b1), |
.* |
); |
wire rd_empty; |
wire [W-1:0] rd_data; |
wire rd_en; |
|
tiny_sync_fifo #(.W(W)) |
tiny_sync_fifo_i(.clk(aclk), .reset(~aresetn), .*); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: assign_gen |
|
if(USE_TSTRB & USE_TKEEP) |
begin |
assign fifo_sink.wr_data = |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
92,11 → 93,11
axis_out.tuser, |
axis_out.tstrb, |
axis_out.tkeep |
} = fifo_source.rd_data; |
} = rd_data; |
end |
else if(USE_TSTRB) |
begin |
assign fifo_sink.wr_data = |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
109,11 → 110,11
axis_out.tlast, |
axis_out.tuser, |
axis_out.tstrb |
} = fifo_source.rd_data; |
} = rd_data; |
end |
else if(USE_TKEEP) |
begin |
assign fifo_sink.wr_data = |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
126,11 → 127,11
axis_out.tlast, |
axis_out.tuser, |
axis_out.tkeep |
} = fifo_source.rd_data; |
} = rd_data; |
end |
else |
begin |
assign fifo_sink.wr_data = |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
141,9 → 142,8
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser |
} = fifo_source.rd_data; |
} = rd_data; |
end |
|
end |
endgenerate |
|
150,10 → 150,13
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = ~fifo_sink.full; |
assign fifo_sink.wr_en = axis_in.tvalid & ~fifo_sink.full; |
assign axis_in.tready = ~wr_full; |
assign wr_en = axis_in.tvalid & ~wr_full; |
assign axis_out.tvalid = ~rd_empty; |
assign rd_en = axis_out.tready & ~rd_empty; |
|
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/axis_synchronizer.sv
0,0 → 1,164
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_synchronizer |
#( |
N = 8, // data bus width in bytes |
I = 0, // TID width |
D = 0, // TDEST width |
U = 1, // TUSER width |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0 // set to 1 to enable, 0 to disable |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
input wr_clk, |
input wr_reset, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
a_tid_unsuported: assert(I == 0) else $fatal; |
a_tdest_unsuported: assert(D == 0) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
localparam W = (N * 8) + (N * USE_TSTRB) + (N * USE_TKEEP) + I + D + U + 1; |
|
|
// -------------------------------------------------------------------- |
// |
wire wr_full; |
wire [W-1:0] wr_data; |
wire wr_en; |
|
wire rd_empty; |
wire [W-1:0] rd_data; |
wire rd_en; |
|
tiny_async_fifo #(.W(W)) |
tiny_async_fifo_i(.rd_clk(aclk), .rd_reset(~aresetn), .*); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: assign_gen |
if(USE_TSTRB & USE_TKEEP) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tstrb, |
axis_in.tkeep |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tstrb, |
axis_out.tkeep |
} = rd_data; |
end |
else if(USE_TSTRB) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tstrb |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tstrb |
} = rd_data; |
end |
else if(USE_TKEEP) |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser, |
axis_in.tkeep |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser, |
axis_out.tkeep |
} = rd_data; |
end |
else |
begin |
assign wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser |
} = rd_data; |
end |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = ~wr_full; |
assign wr_en = axis_in.tvalid & axis_in.tready; |
assign axis_out.tvalid = ~rd_empty; |
assign rd_en = axis_out.tvalid & axis_out.tready; |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/axis_to_axi4_basic_dma.sv
0,0 → 1,193
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_to_axi4_basic_dma |
#( |
A, // address bus width |
N, // data bus width in bytes |
I, // ID width |
BASE_ADDRESS, // must be on 4K boundry |
BUFFER_SIZE, |
BURST_LENGTH, |
MAX_BURSTS, |
BYTES_PER_TUSER = 0 // bytes per tuser bit. Set to 0 for transfer based. |
) |
( |
axi4_if axi4_m, |
axis_if axis_in, // tuser[0] indicates first words of buffer. The rest of tuser is not used. |
input dma_enable, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
localparam W_D = BURST_LENGTH * MAX_BURSTS; |
localparam AW_D = 2; |
localparam WATERMARK = BURST_LENGTH; |
localparam STRIDE = N * BURST_LENGTH; |
localparam ADDRESS_END = BASE_ADDRESS + BUFFER_SIZE; |
localparam ADDRESS_STOP = (ADDRESS_END % STRIDE == 0) ? ADDRESS_END : ADDRESS_END + STRIDE; |
// localparam U = N / BYTES_PER_TUSER; |
|
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
localparam N_4K = 'h1000 / 'h8; // number of bytes in 4K |
initial |
begin |
a_4k_mod_base_address: assert(BASE_ADDRESS % 'h1000 == 0) else $fatal; |
a_4k_gt_eq_stride: assert(N_4K >= STRIDE) else $fatal; |
a_4k_mod_stride: assert('h1000 % STRIDE == 0) else $fatal; |
a_burst_length: assert(BURST_LENGTH > 1) else $fatal; |
// a_bytes_per_tuser: assert(N % BYTES_PER_TUSER == 0) else $fatal; |
end |
|
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
axi4_if #(.A(A), .N(N), .I(I)) axi4_write_fifo(.*); |
|
|
// -------------------------------------------------------------------- |
// |
wire axis_data_en = axis_in.tready & axis_in.tvalid; |
wire start = axis_data_en & axis_in.tuser[0]; |
|
|
// -------------------------------------------------------------------- |
// |
reg [(A-1):0] awaddr_r; |
wire send_waddr; |
wire awaddr_en = (awaddr_r < ADDRESS_STOP); |
wire aw_wr_full; |
wire aw_wr_en = ~aw_wr_full & dma_enable & awaddr_en & send_waddr; |
wire w_wr_full; |
wire w_wr_en = axis_in.tready & axis_in.tvalid; |
wire w_topped_off; |
wire w_watermark; |
wire b_rd_empty; |
wire b_rd_en = ~b_rd_empty; |
|
|
// -------------------------------------------------------------------- |
// |
reg [$clog2(W_D + 1):0] w_wr_counter; |
wire burst_ready = (w_wr_counter > BURST_LENGTH - 1); |
wire wlast = (w_wr_counter == BURST_LENGTH - 1); |
|
always_ff @(posedge aclk) |
if(~aresetn) |
w_wr_counter <= 0; |
else if(aw_wr_en) |
if(w_wr_en) |
w_wr_counter <= w_wr_counter - BURST_LENGTH + 1; |
else |
w_wr_counter <= w_wr_counter - BURST_LENGTH; |
else if(w_wr_en) |
w_wr_counter <= w_wr_counter + 1; |
|
|
// -------------------------------------------------------------------- |
// |
// reg [$clog2(AW_D + 1):0] aw_wr_counter; |
// assign send_waddr = (aw_wr_counter > 0); |
assign send_waddr = burst_ready; |
|
// always_ff @(posedge aclk) |
// if(~aresetn) |
// aw_wr_counter <= 0; |
// else if(aw_wr_en & ~burst_ready) |
// aw_wr_counter <= aw_wr_counter - 1; |
// else if(~aw_wr_en & burst_ready) |
// aw_wr_counter <= aw_wr_counter + 1; |
|
|
// -------------------------------------------------------------------- |
// |
always_ff @(posedge aclk) |
if(~aresetn | ~awaddr_en | start) |
awaddr_r <= BASE_ADDRESS; |
else if(aw_wr_en) |
awaddr_r <= awaddr_r + STRIDE; |
|
|
// -------------------------------------------------------------------- |
// |
axi4_m_to_write_fifos |
#( |
.A(A), |
.N(N), |
.I(I), |
.W_D(W_D), |
.B_D(AW_D), |
.AW_D(AW_D), |
.WATERMARK(WATERMARK) |
) |
axi4_m_to_write_fifos_i(.*); |
|
|
// -------------------------------------------------------------------- |
// |
assign axi4_write_fifo.awaddr = awaddr_r; |
assign axi4_write_fifo.awid = 0; |
assign axi4_write_fifo.awburst = 2'b01; |
assign axi4_write_fifo.awsize = $clog2(N); |
assign axi4_write_fifo.awlen = BURST_LENGTH - 1; |
|
|
// -------------------------------------------------------------------- |
// |
assign axi4_write_fifo.wdata = axis_in.tdata; |
assign axi4_write_fifo.wid = 0; |
assign axi4_write_fifo.wlast = wlast; |
assign axi4_write_fifo.wstrb = {N{1'b1}}; |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = ~w_wr_full & ~burst_ready; |
|
// -------------------------------------------------------------------- |
// |
assign axi4_m.arvalid = 0; |
assign axi4_m.rready = 0; |
assign axi4_m.awcache = 0; |
assign axi4_m.awlock = 0; |
assign axi4_m.awprot = 0; |
assign axi4_m.awqos = 0; |
assign axi4_m.awregion = 0; |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
/axis_upsizer.sv
0,0 → 1,180
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_upsizer |
#( |
N, // data bus width in bytes |
I = 1, // TID width |
D = 1, // TDEST width |
U, // TUSER width |
S, // tdata size multiplier |
USE_TSTRB = 0, // set to 1 to enable, 0 to disable |
USE_TKEEP = 0, // set to 1 to enable, 0 to disable |
BYTES_PER_TUSER // bytes per tuser bit. Set to 0 for transfer based. |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
|
initial |
begin |
a_multiplier: assert((S > 1) & (S % 2 == 0))else $fatal; |
a_tstrb_unsuported: assert(USE_TSTRB == 0) else $fatal; |
a_tkeep_unsuported: assert(USE_TKEEP == 0) else $fatal; |
a_bytes_per_tuser: assert((BYTES_PER_TUSER == 0) | (N % BYTES_PER_TUSER == 0)) else $fatal; |
a_tuser: assert((BYTES_PER_TUSER == 0) | (U % S == 0)) else $fatal; |
end |
|
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// |
localparam A = $clog2(S); |
localparam ED = 2 ** A; |
|
|
// -------------------------------------------------------------------- |
// |
axis_if #(.N(N*S), .U(U*S)) axis_upsizer_bus(.*); |
wire last_word; |
|
|
//--------------------------------------------------- |
// state machine binary definitions |
enum reg [1:0] |
{ |
GET_WORDS_IN = 2'b01, |
WORD_OUT = 2'b10 |
} state, next_state; |
|
|
//--------------------------------------------------- |
// state machine flop |
always_ff @(posedge aclk) |
if(~aresetn) |
state <= GET_WORDS_IN; |
else |
state <= next_state; |
|
|
//--------------------------------------------------- |
// state machine |
always_comb |
case(state) |
GET_WORDS_IN: if(axis_in.tvalid & last_word) |
next_state <= WORD_OUT; |
else |
next_state <= GET_WORDS_IN; |
|
WORD_OUT: if(axis_upsizer_bus.tready) |
next_state <= GET_WORDS_IN; |
else |
next_state <= WORD_OUT; |
|
default: next_state <= GET_WORDS_IN; |
|
endcase |
|
|
// -------------------------------------------------------------------- |
// |
reg [A-1:0] index; |
wire roll_over = ~(index < S - 1) & axis_in.tready & axis_in.tvalid; |
|
always_ff @(posedge aclk) |
if(~aresetn | roll_over) |
index <= 0; |
else if(axis_in.tready & axis_in.tvalid) |
index <= index + 1; |
|
|
// -------------------------------------------------------------------- |
// |
wire [ED-1:0] encoded; |
assign last_word = encoded[S-1]; |
|
one_hot_encoder #(A) |
one_hot_encoder_i(index, encoded); |
|
|
// -------------------------------------------------------------------- |
// |
reg tlast_in[S]; |
reg [U-1:0] tuser_in[S]; |
reg [(8*N)-1:0] tdata_in[S]; |
wire [S-1:0] tlast_out_w; |
wire [(U*S)-1:0] tuser_out_w; |
wire [(8*N*S)-1:0] tdata_out_w; |
genvar j; |
|
generate |
for(j = 0; j < S; j++) |
begin: tdata_gen |
always_ff @(posedge aclk) |
if(encoded[j] & axis_in.tready & axis_in.tvalid) |
begin |
tdata_in[j] <= axis_in.tdata; |
tuser_in[j] <= axis_in.tuser; |
tlast_in[j] <= axis_in.tlast; |
end |
|
assign tlast_out_w[j] = tlast_in[j]; |
assign tuser_out_w[j*U +: U] = tuser_in[j]; |
assign tdata_out_w[j*N*8 +: N*8] = tdata_in[j]; |
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = (state == GET_WORDS_IN) | (next_state == GET_WORDS_IN); |
assign axis_upsizer_bus.tvalid = (state == WORD_OUT); |
assign axis_upsizer_bus.tdata = tdata_out_w; |
assign axis_upsizer_bus.tuser = tuser_out_w; |
assign axis_upsizer_bus.tlast = tlast_out_w[S-1]; |
|
|
// -------------------------------------------------------------------- |
// |
axis_register_slice #(.N(N*S), .U(U*S)) |
axis_register_slice_i(.axis_in(axis_upsizer_bus), .*); |
|
|
// -------------------------------------------------------------------- |
// |
endmodule |
|
|
/axis_video_debug.sv
56,7 → 56,9
(* MARK_DEBUG = "TRUE" *) wire dbg_tvalid = axis_in.tvalid; |
(* MARK_DEBUG = "TRUE" *) wire dbg_tready = axis_in.tready; |
(* MARK_DEBUG = "TRUE" *) wire dbg_eol = axis_in.tlast; |
(* MARK_DEBUG = "TRUE" *) wire dbg_sof = axis_in.tuser; |
(* MARK_DEBUG = "TRUE" *) wire dbg_sof = axis_in.tuser[0]; |
(* MARK_DEBUG = "TRUE" *) wire dbg_sol = axis_in.tuser[1]; |
(* MARK_DEBUG = "TRUE" *) wire dbg_eof = axis_in.tuser[2]; |
|
|
endmodule |
/data_to_axis_fsm.sv
29,18 → 29,18
module |
data_to_axis_fsm |
( |
input axis_en, |
output axis_tvalid, |
input axis_tready, |
input axis_en, |
output axis_tvalid, |
input axis_tready, |
|
input fifo_watermark, // OK to use fifo_almost_full if FIFO is synchronous, assert to flush also |
input fifo_empty, |
output fifo_rd_en, |
input fifo_watermark, // OK to use fifo_almost_full if FIFO is synchronous, assert to flush also |
input fifo_empty, |
output fifo_rd_en, |
|
output data_to_axis_fsm_error, |
output data_to_axis_fsm_error, |
|
input aclk, |
input aresetn |
input aclk, |
input aresetn |
); |
|
//--------------------------------------------------- |