OpenCores
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
);
 
//---------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.