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
- from Rev 45 to Rev 49
- ↔ Reverse comparison
Rev 45 → Rev 49
/sim/src/legacy/tb_axis_register_slice.sv
0,0 → 1,159
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 tb_top(); |
|
// -------------------------------------------------------------------- |
// test bench clock & reset |
wire clk_200mhz; |
wire tb_clk = clk_200mhz; |
wire tb_rst; |
wire aclk = tb_clk; |
wire aresetn = ~tb_rst; |
|
tb_base #( .PERIOD(5_000) ) tb( clk_200mhz, tb_rst ); |
|
|
// -------------------------------------------------------------------- |
// |
localparam TILES = 1; |
localparam WIDTH = 32; // tile width |
localparam HEIGHT = 16; // tile height |
localparam OUTPUTS_PER_TILE = 1; // outputs per tile |
localparam BYTES_PER_PIXEL = 2; |
localparam BITS_PER_PIXEL = 16; |
localparam VERTICAL_BLANKING = 20; |
|
|
// -------------------------------------------------------------------- |
// |
localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE; // data bus width in bytes |
localparam AVF_U = 1; // TUSER width |
|
axis_if #(.N(AVF_N), .U(AVF_U)) axis_in[TILES](.*); |
axis_if #(.N(AVF_N), .U(AVF_U)) axis_out[TILES](.*); |
|
|
// -------------------------------------------------------------------- |
// |
axis_register_slice #(.N(AVF_N), .U(AVF_U)) |
dut |
( |
.axis_en(1'b1), |
.axis_in(axis_in.slave[0]), |
.axis_out(axis_out.master[0]), |
.* |
); |
|
|
// -------------------------------------------------------------------- |
// |
import axis_video_frame_bfm_pkg::*; |
import avf_agent_class_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
avf_agent_config_class avf_agent_config_h; |
avf_agent_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE) avf_agent_h; |
|
initial |
begin |
|
avf_agent_config_h = new |
( |
.width(WIDTH), |
.height(HEIGHT), |
.bytes_per_pixel(BYTES_PER_PIXEL), |
.bits_per_pixel(BITS_PER_PIXEL), |
.tiles(TILES), |
.outputs_per_tile(OUTPUTS_PER_TILE), |
.name("AVF_"), |
.vertical_blanking(VERTICAL_BLANKING) |
); |
|
avf_agent_config_h.tile[0].direction = RIGHT_DOWN; |
|
avf_agent_h = new |
( |
.avf_agent_config(avf_agent_config_h), |
.avf_axis_in_if(axis_out), |
.avf_axis_out_if(axis_in) |
); |
|
avf_agent_h.init(); |
|
end |
|
|
// -------------------------------------------------------------------- |
// sim models |
// | | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/ |
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
|
// -------------------------------------------------------------------- |
// |
|
|
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
// /|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\ |
// | | | | | | | | | | | | | | | | | |
// sim models |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// debug wires |
for(genvar j = 0; j < TILES; j++) |
axis_video_debug #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE) avf_debug(axis_out[j]); |
|
|
// -------------------------------------------------------------------- |
// test |
the_test test( tb_clk, tb_rst ); |
|
initial |
begin |
|
test.run_the_test(); |
|
$display("^^^---------------------------------"); |
$display("^^^ %16.t | Testbench done.", $time); |
$display("^^^---------------------------------"); |
|
$display("^^^---------------------------------"); |
|
$stop(); |
|
end |
|
endmodule |
|
|
|
/sim/src/legacy/tb_axis_to_axi4_agent_class_pkg.sv
0,0 → 1,158
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
package tb_axis_to_axi4_agent_class_pkg; |
|
// -------------------------------------------------------------------- |
// |
import axi4_memory_pkg::*; |
import axis_bfm_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class tb_axis_to_axi4_agent_class #(N, A, I, D, U); |
|
axi4_memory_class #(A, N, I) m_h; |
axis_tx_bfm_class #(N, I, D, U) s_h; |
memory_tr_class #(A, N, I) m_tr_h; |
axis_tr_class #(N, I, D, U) s_tr_h; |
|
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m; |
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_in; |
|
mailbox #(memory_tr_class #(A, N, I)) q; |
|
|
// -------------------------------------------------------------------- |
// |
task wait_for_sof; |
@(posedge axis_in.cb_s.tuser); |
$display("^^^ %16.t | %m", $time); |
endtask: wait_for_sof |
|
|
// -------------------------------------------------------------------- |
// |
task wait_for_dma_done(int bvalid_count); |
repeat(bvalid_count) |
@(axi4_m.cb_s iff axi4_m.cb_m.bvalid & axi4_m.cb_s.bready); |
$display("^^^ %16.t | %m", $time); |
endtask: wait_for_dma_done |
|
|
// -------------------------------------------------------------------- |
// |
task random_transaction(int addr, int size, int stride); |
m_h.clear_all(); |
m_tr_h = new(); |
m_tr_h.random(addr, size); |
q.put(m_tr_h); |
|
$display("^^^ %16.t | %m | m_tr_h.data.size = %x", $time, m_tr_h.data.size); |
for(int i = 0; i < m_tr_h.data.size; i += N) |
begin |
s_tr_h = new(); |
for(int k = 0; k < N; k++) |
begin |
s_tr_h.tdata[k*8 +: 8] = m_tr_h.data[i + k]; |
end |
|
if(i == 0) |
s_tr_h.tuser = 'b1; |
else |
s_tr_h.tuser = 'b0; |
|
if(i + N < m_tr_h.data.size) |
s_tr_h.tlast = 1'b0; |
else |
s_tr_h.tlast = 1'b1; |
|
s_h.q.put(s_tr_h); |
end |
|
wait_for_dma_done(size / stride); |
endtask: random_transaction |
|
|
// -------------------------------------------------------------------- |
// |
task automatic compare(int offset); |
byte data[]; |
|
$display("^^^ %16.t | %m", $time); |
$display("^^^ %16.t | q.num = %d", $time, q.num); |
$display("^^^ %16.t | s_h.q.num = %d", $time, s_h.q.num); |
$display("^^^ %16.t | m_tr_h.data.size = %d", $time, m_tr_h.data.size); |
|
if(q.try_get(m_tr_h) == 0) |
begin |
$display("!!! %16.t | ERROR!!! try_get(m_tr_h) == 0", $time); |
$stop; |
end |
|
data = new[m_tr_h.data.size]; |
m_h.dump_words(offset, data); |
|
foreach(m_tr_h.data[i]) |
if(data[i] != m_tr_h.data[i]) |
begin |
$display("!!! %16.t | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", $time); |
$display("!!! %16.t | %x ", $time, i); |
$display("!!! %16.t | %x | %x |", $time, data[i], m_tr_h.data[i]); |
$stop; |
end |
|
$display("^^^ %16.t | %m | done!", $time); |
|
endtask: compare |
|
|
//-------------------------------------------------------------------- |
// |
function new |
( |
virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_m, |
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_in |
); |
|
this.axi4_m = axi4_m; |
this.axis_in = axis_in; |
m_h = new(axi4_m); |
s_h = new(axis_in); |
q = new(); |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: tb_axis_to_axi4_agent_class |
|
// -------------------------------------------------------------------- |
// |
endpackage: tb_axis_to_axi4_agent_class_pkg |
/sim/src/legacy/tb_axis_upsizer.sv
0,0 → 1,144
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 tb_top(); |
|
// -------------------------------------------------------------------- |
// test bench clock & reset |
wire clk_200mhz; |
wire tb_clk = clk_200mhz; |
wire tb_rst; |
|
tb_base #(.PERIOD(5_000)) tb(clk_200mhz, tb_rst); |
|
|
// -------------------------------------------------------------------- |
// |
wire tb_rst_s; |
wire aclk = tb_clk; |
wire aresetn = ~tb_rst_s; |
|
sync_reset |
sync_reset_i(aclk, tb_rst, tb_rst_s); |
|
|
// -------------------------------------------------------------------- |
// |
import tb_axis_upsizer_class_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
axis_if #(.N(AVF_N), .U(AVF_U)) axis_in(.*); |
axis_if #(.N(AVF_N * S), .U(AVF_U * S)) axis_out(.*); |
|
|
// -------------------------------------------------------------------- |
// |
axis_upsizer |
#( |
.N(AVF_N), // data bus width in bytes |
.I(1), // TID width |
.D(1), // TDEST width |
.U(AVF_U), // TUSER width |
.S(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(0) // bytes per tuser bit. Set to 0 for transfer based. |
) |
dut(.*); |
|
|
// -------------------------------------------------------------------- |
// sim models |
// | | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/ |
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
|
// -------------------------------------------------------------------- |
// |
axis_checker #(.N(AVF_N * S), .I(1), .D(1), .U(AVF_U)) |
axis_checker_i(.*); |
|
|
// -------------------------------------------------------------------- |
// |
axis_if #(.N(AVF_N * S), .U(AVF_U)) avf_axis_in_if(.*); |
|
assign axis_out.tready = avf_axis_in_if.tready; |
assign avf_axis_in_if.tvalid = axis_out.tvalid; |
assign avf_axis_in_if.tdata = axis_out.tdata; |
assign avf_axis_in_if.tuser = {axis_out.tuser[(AVF_U*S)-1], axis_out.tuser[1:0]}; |
assign avf_axis_in_if.tlast = axis_out.tlast; |
|
|
// -------------------------------------------------------------------- |
// |
tb_axis_upsizer_class a_h; |
|
initial |
a_h = new(.avf_axis_in_if(avf_axis_in_if), .avf_axis_out_if(axis_in)); |
|
|
// -------------------------------------------------------------------- |
// |
|
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' |
// /|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\-/|\ |
// | | | | | | | | | | | | | | | | | |
// sim models |
// -------------------------------------------------------------------- |
|
|
// -------------------------------------------------------------------- |
// debug wires |
|
|
// -------------------------------------------------------------------- |
// test |
the_test test( tb_clk, tb_rst ); |
|
initial |
begin |
|
test.run_the_test(); |
|
$display("^^^---------------------------------"); |
$display("^^^ %16.t | Testbench done.", $time); |
$display("^^^---------------------------------"); |
|
$display("^^^---------------------------------"); |
|
$stop(); |
|
end |
|
endmodule |
|
|
|
/sim/src/legacy/tb_axis_upsizer_agent_class_pkg.sv
0,0 → 1,129
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
package tb_axis_upsizer_agent_class_pkg; |
|
// -------------------------------------------------------------------- |
// |
import video_frame_pkg::*; |
import axis_video_frame_bfm_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
class tb_axis_upsizer_agent_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_N, AVF_U, S); |
|
virtual axis_if #(.N(AVF_N * S), .U(AVF_U)) avf_axis_in_if; |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if; |
|
avf_config_class c_h; |
|
avf_tx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_U) tx_h; |
avf_rx_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE * S, AVF_U) rx_h; |
|
video_frame_class clone_h; |
video_frame_class sent_f_h; |
video_frame_class rx_f_h; |
|
mailbox #(video_frame_class) q; |
|
|
// -------------------------------------------------------------------- |
// |
virtual task |
queue_frame |
( |
string pattern = "", |
int pixel = 0 |
); |
|
if(pattern != "") |
tx_h.make_frame(pattern, pixel); |
|
clone_h = tx_h.tx_bfm_h[0].f_h.clone(); |
tx_h.tx_bfm_h[0].put(clone_h); |
q.put(clone_h); |
|
$display("^^^ %16.t | %m | using %s pattern", $time, pattern); |
|
endtask: queue_frame |
|
|
// -------------------------------------------------------------------- |
// |
virtual task automatic |
compare_frame; |
|
int mismatch_count; |
|
$display("^^^ %16.t | %m", $time); |
|
q.get(sent_f_h); |
rx_h.rx_bfm_h[0].get(rx_f_h); |
mismatch_count = sent_f_h.compare(8, rx_f_h); |
|
endtask: compare_frame |
|
|
//-------------------------------------------------------------------- |
// |
function void init(avf_config_class in_c_h, avf_config_class out_c_h); |
|
rx_h = new(in_c_h, '{avf_axis_in_if}); |
tx_h = new(out_c_h, '{avf_axis_out_if}); |
|
this.q = new(); |
|
endfunction: init |
|
|
//-------------------------------------------------------------------- |
// |
function new |
( |
virtual axis_if #(.N(AVF_N * S), .U(AVF_U)) avf_axis_in_if, |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if |
); |
|
this.avf_axis_in_if = avf_axis_in_if; |
this.avf_axis_out_if = avf_axis_out_if; |
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: tb_axis_upsizer_agent_class |
|
// -------------------------------------------------------------------- |
// |
endpackage: tb_axis_upsizer_agent_class_pkg |
|
|
|
|
|
/sim/src/legacy/tb_axis_upsizer_class_pkg.sv
0,0 → 1,114
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
package tb_axis_upsizer_class_pkg; |
|
// -------------------------------------------------------------------- |
// |
import axis_video_frame_bfm_pkg::*; |
import tb_axis_upsizer_agent_class_pkg::*; |
|
|
// -------------------------------------------------------------------- |
// |
localparam WIDTH = 32; // tile width |
localparam HEIGHT = 16; // tile height |
localparam OUTPUTS_PER_TILE = 1; // outputs per tile |
localparam BYTES_PER_PIXEL = 2; |
localparam BITS_PER_PIXEL = 16; |
localparam VERTICAL_BLANKING = 20; |
|
localparam S = 4; // tdata size multiplier |
localparam AVF_N = BYTES_PER_PIXEL * OUTPUTS_PER_TILE; // data bus width in bytes |
localparam AVF_U = 3; // TUSER width |
|
|
// -------------------------------------------------------------------- |
// |
class tb_axis_upsizer_class |
extends tb_axis_upsizer_agent_class #(BYTES_PER_PIXEL, OUTPUTS_PER_TILE, AVF_N, AVF_U, S); |
|
avf_config_class in_c_h; |
avf_config_class out_c_h; |
avf_tile_config_t tile_config[]; |
|
|
//-------------------------------------------------------------------- |
// |
function new |
( |
virtual axis_if #(.N(AVF_N * S), .U(AVF_U)) avf_axis_in_if, |
virtual axis_if #(.N(AVF_N), .U(AVF_U)) avf_axis_out_if |
); |
|
super.new(avf_axis_in_if, avf_axis_out_if); |
|
this.tile_config = new[1]; |
this.tile_config[0].direction = RIGHT_DOWN; |
|
this.in_c_h = new |
( |
.width(WIDTH), |
.height(HEIGHT), |
.bytes_per_pixel(BYTES_PER_PIXEL), |
.bits_per_pixel(BITS_PER_PIXEL), |
.pixels_per_clk(OUTPUTS_PER_TILE * S), |
.name("IN_"), |
.vertical_blanking(VERTICAL_BLANKING), |
.tile(tile_config) |
); |
|
this.out_c_h = new |
( |
.width(WIDTH), |
.height(HEIGHT), |
.bytes_per_pixel(BYTES_PER_PIXEL), |
.bits_per_pixel(BITS_PER_PIXEL), |
.pixels_per_clk(OUTPUTS_PER_TILE), |
.name("OUT_"), |
.vertical_blanking(VERTICAL_BLANKING), |
.tile(tile_config) |
); |
|
super.init(in_c_h, out_c_h); |
|
endfunction: new |
|
|
// -------------------------------------------------------------------- |
// |
endclass: tb_axis_upsizer_class |
|
// -------------------------------------------------------------------- |
// |
endpackage: tb_axis_upsizer_class_pkg |
|
|
|
|
|
/src/axis_down_shift.sv
0,0 → 1,178
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2019 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_down_shift_tuser_mux |
#( |
U = 1, // TUSER width |
logic [U-1:0] TUSER_MASK[3] = '{ {U{1'b0}}, // first |
{U{1'b0}}, // middle |
{U{1'b0}} } // last |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
endmodule |
|
// -------------------------------------------------------------------- |
module |
axis_down_shift |
#( |
N, // axis_in tdata bus width in bytes |
S, // tdata size divisor |
I = 1, // TID width |
D = 1, // TDEST width |
U = 1, // TUSER width |
logic [U-1:0] TUSER_MASK[3] = '{ {U{1'b0}}, // first |
{U{1'b0}}, // middle |
{U{1'b0}} } // last |
) |
( |
axis_if axis_in, |
axis_if axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// synthesis translate_off |
initial |
begin |
assert(S > 1) else $fatal; |
assert(N % S == 0) else $fatal; |
end |
// synthesis translate_on |
// -------------------------------------------------------------------- |
|
// -------------------------------------------------------------------- |
localparam N_OUT = (N / S); // width of axis_out.tdata in bytes |
localparam W = N_OUT * 8; // width of axis_out.tdata in bits |
localparam UB = (W*(S-1))-1; |
|
// -------------------------------------------------------------------- |
axis_if #(.N(N_OUT), .I(I), .D(D), .U(U)) a_down(.*); |
wire almost_last; |
|
// -------------------------------------------------------------------- |
enum reg [2:0] |
{ |
FIRST = 3'b001, |
MIDDLE = 3'b010, |
LAST = 3'b100 |
} state, next_state; |
|
// -------------------------------------------------------------------- |
always_ff @(posedge aclk) |
if(~aresetn) |
state <= FIRST; |
else |
state <= next_state; |
|
// -------------------------------------------------------------------- |
always_comb |
case(state) |
FIRST: if(axis_in.tvalid & a_down.tready) |
if(almost_last) |
next_state <= LAST; |
else |
next_state <= MIDDLE; |
else |
next_state <= FIRST; |
|
MIDDLE: if(almost_last & a_down.tready) |
next_state <= LAST; |
else |
next_state <= MIDDLE; |
|
LAST: if(a_down.tready) |
next_state <= FIRST; |
else |
next_state <= LAST; |
|
default: next_state <= FIRST; |
endcase |
|
// -------------------------------------------------------------------- |
reg [$clog2(S)-1:0] index; |
assign almost_last = (index >= S - 2); |
|
always_ff @(posedge aclk) |
if(next_state == FIRST) |
index <= 0; |
else if(a_down.tready) |
index <= index + 1; |
|
// -------------------------------------------------------------------- |
reg [UB:0] remainder; |
wire [W-1:0] tdata_pass = axis_in.tdata[W-1:0]; |
wire [W-1:0] tdata_shift = remainder[W-1:0]; |
|
always_ff @(posedge aclk) |
if(state == FIRST) |
remainder <= axis_in.tdata[(N*8)-1:W]; |
else if(a_down.tready) |
remainder <= { {W{1'b0}}, remainder[UB:W]}; |
|
// -------------------------------------------------------------------- |
reg [U-1:0] tuser; |
|
generate |
for(genvar j = 0; j < U; j++) |
begin: tuser_gen |
always_comb |
case(state) |
FIRST: tuser[j] = TUSER_MASK[0][j] ? axis_in.tuser[j] : 0; |
MIDDLE: tuser[j] = TUSER_MASK[1][j] ? axis_in.tuser[j] : 0; |
LAST: tuser[j] = TUSER_MASK[2][j] ? axis_in.tuser[j] : 0; |
default: tuser[j] = 0; |
endcase |
end |
endgenerate |
|
// -------------------------------------------------------------------- |
assign axis_in.tready = (state == LAST) & (next_state != LAST); |
// assign a_down.tstrb = axis_in.tstrb; |
// assign a_down.tkeep = axis_in.tkeep; |
assign a_down.tid = axis_in.tid; |
assign a_down.tdest = axis_in.tdest; |
assign a_down.tvalid = axis_in.tvalid; |
assign a_down.tlast = (state == LAST) ? axis_in.tlast : 0; |
assign a_down.tuser = tuser; |
assign a_down.tdata = (state == FIRST) ? tdata_pass : tdata_shift; |
|
// -------------------------------------------------------------------- |
axis_register_slice #(.N(N_OUT), .I(I), .D(D), .U(U)) |
slice_i(.axis_in(a_down), .*); |
|
// -------------------------------------------------------------------- |
endmodule |
/src/axis_fanout.sv
0,0 → 1,110
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2019 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_fanout #(F) |
( |
axis_if axis_in, |
axis_if axis_out[F], |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
wire [F-1:0] handshake; |
wire [F-1:0] stalled; |
reg [F-1:0] transfer_stalled; |
wire [F-1:0] out_tready; |
wire all_ready = &out_tready; |
wire [F-1:0] done; |
wire all_done = &done; |
|
// -------------------------------------------------------------------- |
enum reg [1:0] |
{ |
FANOUT = 2'b01, |
STALL = 2'b10 |
} state, next_state; |
|
// -------------------------------------------------------------------- |
always_ff @(posedge aclk) |
if(~aresetn) |
state <= FANOUT; |
else |
state <= next_state; |
|
// -------------------------------------------------------------------- |
always_comb |
case(state) |
FANOUT: if(~axis_in.tvalid) |
next_state = FANOUT; |
else if(all_ready) |
next_state = FANOUT; |
else |
next_state = STALL; |
|
STALL: if(all_done) |
next_state = FANOUT; |
else |
next_state = STALL; |
|
default: next_state = FANOUT; |
endcase |
|
// -------------------------------------------------------------------- |
generate |
for(genvar j = 0; j < F; j++) |
begin: tready_gen |
// -------------------------------------------------------------------- |
assign handshake[j] = axis_in.tvalid & axis_out[j].tready; |
assign stalled[j] = axis_in.tvalid & ~axis_out[j].tready; |
assign done[j] = ~transfer_stalled[j] | handshake[j]; |
|
always_ff @(posedge aclk) |
if(handshake[j]) |
transfer_stalled[j] <= 0; |
else if(stalled[j]) |
transfer_stalled[j] <= 1; |
|
// -------------------------------------------------------------------- |
assign out_tready[j] = axis_out[j].tready; |
assign axis_out[j].tlast = axis_in.tlast; |
assign axis_out[j].tuser = axis_in.tuser; |
assign axis_out[j].tdata = axis_in.tdata; |
assign axis_out[j].tstrb = axis_in.tstrb; |
assign axis_out[j].tkeep = axis_in.tkeep; |
assign axis_out[j].tid = axis_in.tid; |
assign axis_out[j].tdest = axis_in.tdest; |
assign axis_out[j].tvalid = (state == FANOUT) ? axis_in.tvalid : transfer_stalled[j]; |
end |
endgenerate |
|
// -------------------------------------------------------------------- |
assign axis_in.tready = (state == FANOUT) ? all_ready : (next_state == FANOUT); |
|
// -------------------------------------------------------------------- |
endmodule |