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
    from Rev 30 to Rev 31
    Reverse comparison

Rev 30 → Rev 31

/sim/src/BP063-BU-01000-r0p1-00rel0/BP063-BU-01000-r0p1-00rel0.txt
0,0 → 1,6
 
extract the AMBA 4 AXI4, AXI4-Lite, and AXI4-Stream Protocol, (BP063-BU-01000-r0p1-00rel0.tgz), into this directory.
 
goto https://silver.arm.com/browse/BP063 to download. requires
an free account to login.
 
/sim/src/BP063-BU-01000-r0p1-00rel0/axis_checker.sv
0,0 → 1,123
//////////////////////////////////////////////////////////////////////
//// ////
//// 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_checker
#(
N, // data bus width in bytes
I = 1, // TID width
D = 1, // TDEST width
U = 1, // TUSER width
MAXWAITS = 16,
RecommendOn = 1'b1,
RecMaxWaitOn = 1'b1
)
(
axis_if axis_in
);
 
//---------------------------------------------------
//
localparam DATA_WIDTH_BYTES = N; // data bus width
localparam DEST_WIDTH = D; // TDEST width
 
// Select the number of ID bits required
localparam ID_WIDTH = I; // (T)ID width
 
// Select the size of the USER buses
localparam USER_WIDTH = U; // width of the user sideband field
 
 
//---------------------------------------------------
//
// INDEX: - Calculated (user should not override)
// =====
// Do not override the following parameters: they must be calculated exactly
// as shown below
// data max index
localparam DATA_MAX = DATA_WIDTH_BYTES ? (DATA_WIDTH_BYTES*8)-1:0;
localparam DEST_MAX = DEST_WIDTH ? DEST_WIDTH-1:0; // dest max index
localparam STRB_WIDTH = DATA_WIDTH_BYTES; // TSTRB width
localparam STRB_MAX = STRB_WIDTH ? STRB_WIDTH-1:0; // TSTRB max index
localparam KEEP_MAX = STRB_WIDTH ? STRB_WIDTH-1:0; // TKEEP max index
localparam ID_MAX = ID_WIDTH ? ID_WIDTH-1:0; // ID max index
localparam TUSER_MAX = USER_WIDTH? USER_WIDTH-1:0; // TUSER max index
 
 
//---------------------------------------------------
//
// INDEX: - Global Signals
// =====
wire ACLK = axis_in.aclk; // AXI Clock
wire ARESETn = axis_in.aresetn; // AXI Reset
 
 
// INDEX: - AXI4-Stream Interface
// =====
wire [DATA_MAX:0] TDATA = axis_in.tdata;
wire [STRB_MAX:0] TSTRB = axis_in.tstrb;
wire [KEEP_MAX:0] TKEEP = axis_in.tkeep;
wire TLAST = axis_in.tlast;
wire [ID_MAX:0] TID = axis_in.tid;
wire [DEST_MAX:0] TDEST = axis_in.tdest;
wire [TUSER_MAX:0] TUSER = axis_in.tuser;
wire TVALID = axis_in.tvalid;
wire TREADY = axis_in.tready;
 
 
//---------------------------------------------------
//
Axi4StreamPC
#(
// Set DATA_WIDTH to the data-bus width required
.DATA_WIDTH_BYTES(DATA_WIDTH_BYTES), // data bus width
.DEST_WIDTH(DEST_WIDTH), // TDEST width
 
// Select the number of ID bits required
.ID_WIDTH(ID_WIDTH), // (T)ID width
 
// Select the size of the USER buses
.USER_WIDTH(USER_WIDTH), // width of the user sideband field
 
// Maximum number of cycles between VALID -> READY high before a warning is
// generated
.MAXWAITS(MAXWAITS),
 
// Recommended Rules Enable
// enable/disable reporting of all AXI4STREAM_REC*_* rules
.RecommendOn(RecommendOn),
// enable/disable reporting of just AXI4STREAM_REC*_MAX_WAIT rules
.RecMaxWaitOn(RecMaxWaitOn)
)
Axi4StreamPC_i(.*);
 
 
//---------------------------------------------------
//
endmodule
 
/sim/src/axis_bfm_pkg.sv
0,0 → 1,220
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 axis_bfm_pkg;
 
 
// --------------------------------------------------------------------
//
import q_pkg::*;
import bfm_pkg::*;
 
 
// --------------------------------------------------------------------
//
class axis_tr_class #(N, I, D, U)
extends transaction_class #(axis_tr_class #(N, I, D, U));
 
rand logic [(8*N)-1:0] tdata;
rand logic [N-1:0] tstrb;
rand logic [N-1:0] tkeep;
rand logic tlast;
rand logic [I-1:0] tid;
rand logic [D-1:0] tdest;
rand logic [U-1:0] tuser;
 
// --------------------------------------------------------------------
//
function void copy(TR_T from);
// delay_class delay_h;
this.tdata = from.tdata;
this.tstrb = from.tstrb;
this.tkeep = from.tkeep;
this.tlast = from.tlast;
this.tid = from.tid;
this.tdest = from.tdest;
this.tuser = from.tuser;
endfunction: copy
 
 
// --------------------------------------------------------------------
//
endclass: axis_tr_class
 
 
// --------------------------------------------------------------------
//
class axis_tx_bfm_class #(N, I, D, U)
extends blocking_transmission_q_class #(axis_tr_class #(.N(N), .I(I), .D(D), .U(U)));
 
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_out;
 
 
//--------------------------------------------------------------------
//
function void set_default;
axis_out.cb_m.tvalid <= 0;
axis_out.cb_m.tdata <= 'bx;
axis_out.cb_m.tstrb <= 'bx;
axis_out.cb_m.tkeep <= 'bx;
axis_out.cb_m.tlast <= 'bx;
axis_out.cb_m.tid <= 'bx;
axis_out.cb_m.tdest <= 'bx;
axis_out.cb_m.tuser <= 'bx;
endfunction: set_default
 
 
//--------------------------------------------------------------------
//
task tx_transaction(axis_tr_class #(.N(N), .I(I), .D(D), .U(U)) tr_h);
axis_out.zero_cycle_delay();
repeat(tr_h.delay_h.delay) @(axis_out.cb_m);
 
axis_out.cb_m.tvalid <= 1;
axis_out.cb_m.tdata <= tr_h.tdata;
axis_out.cb_m.tstrb <= 0;
axis_out.cb_m.tkeep <= 0;
axis_out.cb_m.tlast <= tr_h.tlast;
axis_out.cb_m.tid <= 0;
axis_out.cb_m.tdest <= 0;
axis_out.cb_m.tuser <= tr_h.tuser;
 
@(axis_out.cb_m);
wait(axis_out.cb_m.tready);
// @(axis_out.cb_m iff axis_out.cb_m.tready);
 
set_default();
endtask: tx_transaction
 
 
// --------------------------------------------------------------------
//
event tx_done;
 
task automatic transmit(ref Q_T tr_h);
tx_transaction(tr_h);
->tx_done;
endtask: transmit
 
 
//--------------------------------------------------------------------
//
task init;
set_default();
endtask: init
 
 
//--------------------------------------------------------------------
//
function new(virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_out);
this.axis_out = axis_out;
tr_h = new();
fork
init();
join_none
$display("^^^ %16.t | %m", $time);
endfunction: new
 
// --------------------------------------------------------------------
//
endclass: axis_tx_bfm_class
 
 
// --------------------------------------------------------------------
//
class axis_rx_bfm_class #(N, I, D, U)
extends blocking_receiver_q_class #(axis_tr_class #(.N(N), .I(I), .D(D), .U(U)));
 
virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_in;
 
 
//--------------------------------------------------------------------
//
function void set_tready(bit value);
axis_in.cb_s.tready <= value;
endfunction: set_tready
 
 
//--------------------------------------------------------------------
//
task rx_transaction(axis_tr_class #(.N(N), .I(I), .D(D), .U(U)) tr_h);
repeat(tr_h.delay_h.delay) @(axis_in.cb_s);
axis_in.cb_s.tready <= 1;
 
@(axis_in.cb_s);
wait(axis_in.cb_s.tvalid);
// @(axis_in.cb_s iff axis_in.cb_s.tvalid);
 
tr_h.tdata <= axis_in.cb_s.tdata;
tr_h.tstrb <= axis_in.cb_s.tstrb;
tr_h.tkeep <= axis_in.cb_s.tkeep;
tr_h.tlast <= axis_in.cb_s.tlast;
tr_h.tid <= axis_in.cb_s.tid;
tr_h.tdest <= axis_in.cb_s.tdest;
tr_h.tuser <= axis_in.cb_s.tuser;
 
axis_in.cb_s.tready <= 0;
endtask: rx_transaction
 
 
// --------------------------------------------------------------------
//
event rx_frame_done;
 
virtual task receive(ref Q_T tr_h);
tr_h = new();
void'(tr_h.delay_h.next());
rx_transaction(tr_h);
->rx_frame_done;
endtask: receive
 
 
//--------------------------------------------------------------------
//
task init;
set_tready(0);
endtask: init
 
 
//--------------------------------------------------------------------
//
function new (virtual axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_in);
this.axis_in = axis_in;
fork
init();
join_none
$display("^^^ %16.t | %m", $time);
endfunction: new
 
endclass: axis_rx_bfm_class
 
 
// --------------------------------------------------------------------
//
endpackage: axis_bfm_pkg
 
/sim/src/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/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/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/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
 
 
 
 
 
/sim/tests/tb_axis_to_axi4_basic_dma/init_test.do
0,0 → 1,34
# ------------------------------------
#
# ------------------------------------
 
global env
 
# setup environment
do ../../../../scripts/sim_env.do
set env(SIM_TARGET) fpga
set env(SIM_TB) tb_axis_to_axi4_basic_dma
 
radix -hexadecimal
 
make_lib work 1
 
sim_compile_all tb_packages
sim_compile_all bfm_packages
sim_compile_all axi4_lib
sim_compile_all qaz_lib
sim_compile_all sim
 
# compile simulation files
vlog -f ./$env(SIM_TB).f
 
# simulation $root
vlog ./$env(SIM_TB)_pkg.sv
vlog ./$env(SIM_TB).sv
 
# compile test last
vlog ./the_test.sv
 
# run the sim
sim_run_test
 
/sim/tests/tb_axis_to_axi4_basic_dma/sim.do
0,0 → 1,13
#
#
 
quit -sim
 
vsim -novopt work.tb_top
 
# log all signals
log -r *
 
# run -all
 
 
/sim/tests/tb_axis_to_axi4_basic_dma/tb_axis_to_axi4_basic_dma.f
0,0 → 1,12
#
 
${LIB_BASE_DIR}/axi4_stream_lib/sim/src/axis_bfm_pkg.sv
${LIB_BASE_DIR}/axi4_lib/sim/src/axi4_models/axi4_memory_pkg.sv
 
${PROJECT_DIR}/sim/src/tb_axis_to_axi4_agent_class_pkg.sv
 
${PROJECT_DIR}/src/axis_to_axi4_basic_dma.sv
 
./${SIM_TB}_pkg.sv
./${SIM_TB}.sv
 
/sim/tests/tb_axis_to_axi4_basic_dma/tb_axis_to_axi4_basic_dma.sv
0,0 → 1,115
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
 
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_to_axi4_basic_dma_pkg::*;
 
 
// --------------------------------------------------------------------
//
axi4_if #(.A(A), .N(N), .I(I)) axi4_m(.*);
axis_if #(.N(N), .I(I), .D(D), .U(U)) axis_in(.*);
 
 
// --------------------------------------------------------------------
//
logic dma_enable = 0;
 
axis_to_axi4_basic_dma
#(
.A(A),
.N(N),
.I(I),
.BASE_ADDRESS(BASE_ADDRESS),
.BUFFER_SIZE(BUFFER_SIZE),
.BURST_LENGTH(BURST_LENGTH),
.MAX_BURSTS(MAX_BURSTS),
.BYTES_PER_TUSER(BYTES_PER_TUSER)
)
dut(.*);
 
 
// --------------------------------------------------------------------
// sim models
// | | | | | | | | | | | | | | | | |
// \|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/-\|/
// ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
 
// --------------------------------------------------------------------
//
axi4_checker #(.A(A), .N(N), .MAXWAITS(64))
axi4_checker_i(.axi4_in(axi4_m));
 
 
// --------------------------------------------------------------------
//
axis_checker #(.N(N), .I(I), .D(D), .U(U), .MAXWAITS(64))
axis_checker_i(.axis_in(axis_in));
 
 
// --------------------------------------------------------------------
//
tb_axis_to_axi4_basic_dma_class a_h;
 
initial
a_h = new(axi4_m, 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/tests/tb_axis_to_axi4_basic_dma/tb_axis_to_axi4_basic_dma_pkg.sv
0,0 → 1,58
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
 
package tb_axis_to_axi4_basic_dma_pkg;
 
// --------------------------------------------------------------------
//
import tb_axis_to_axi4_agent_class_pkg::*;
 
 
// --------------------------------------------------------------------
//
localparam BASE_ADDRESS = 32'h0000_0000; // must be on 4K boundry
localparam BUFFER_SIZE = 'h800;
localparam BURST_LENGTH = 8'h08;
localparam MAX_BURSTS = 4;
localparam BYTES_PER_TUSER = 2; // bytes per tuser bit. Set to 0 for transfer based.
 
localparam N = 8; // data bus width in bytes
localparam A = 32; // address bus width
localparam I = 1; // ID width
localparam D = 1; // TDEST width
localparam U = N / BYTES_PER_TUSER; // TUSER width
 
 
// --------------------------------------------------------------------
//
class tb_axis_to_axi4_basic_dma_class
extends tb_axis_to_axi4_agent_class #(N, A, I, D, U);
 
 
//--------------------------------------------------------------------
//
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
);
 
super.new(.axi4_m(axi4_m), .axis_in(axis_in));
 
endfunction: new
 
 
// --------------------------------------------------------------------
//
endclass: tb_axis_to_axi4_basic_dma_class
 
// --------------------------------------------------------------------
//
endpackage: tb_axis_to_axi4_basic_dma_pkg
 
 
 
 
 
/sim/tests/tb_axis_to_axi4_basic_dma/the_test.sv
0,0 → 1,60
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
`timescale 1ps/1ps
 
 
module
the_test(
input tb_clk,
input tb_rst
);
 
// --------------------------------------------------------------------
//
import tb_axis_to_axi4_basic_dma_pkg::*;
 
 
// --------------------------------------------------------------------
//
task run_the_test;
 
// --------------------------------------------------------------------
// insert test below
// --------------------------------------------------------------------
$display("^^^---------------------------------");
$display("^^^ %16.t | Testbench begun.", $time);
$display("^^^---------------------------------");
 
// --------------------------------------------------------------------
tb_top.tb.timeout_stop(50us);
 
// --------------------------------------------------------------------
wait(tb_top.aresetn);
#200ns;
 
// --------------------------------------------------------------------
force tb_top.dma_enable = 1;
#100ns;
 
// --------------------------------------------------------------------
repeat(8)
begin
tb_top.a_h.random_transaction(BASE_ADDRESS, BUFFER_SIZE, N * BURST_LENGTH);
tb_top.a_h.compare(BASE_ADDRESS);
end
 
// --------------------------------------------------------------------
#200ns;
 
// --------------------------------------------------------------------
// insert test above
// --------------------------------------------------------------------
 
endtask
 
// --------------------------------------------------------------------
//
endmodule
 
/sim/tests/tb_axis_to_axi4_basic_dma/wip.do
0,0 → 1,11
#
 
vlog -f ./tb_axis_to_axi4_basic_dma.f
 
# simulation $root
vlog ./tb_axis_to_axi4_basic_dma.sv
 
# compile test last
vlog ./the_test.sv
 
/sim/tests/tb_axis_upsizer/init_test.do
0,0 → 1,37
# ------------------------------------
#
# ------------------------------------
 
global env
 
set env(ROOT_DIR) ../../../../..
set env(PROJECT_DIR) ../../..
set env(SIM_TARGET) fpga
 
# load sim procedures
do $env(ROOT_DIR)/qaz_libs/scripts/sim_procs.do
 
radix -hexadecimal
 
make_lib work 1
 
sim_compile_all tb_packages
sim_compile_all bfm_packages
sim_compile_all axi4_lib
sim_compile_all qaz_libs
sim_compile_all sim
vlog -f ./tb_axis_upsizer.f
 
# simulation $root
vlog $env(PROJECT_DIR)/sim/src/tb_axis_upsizer.sv
 
# compile test last
vlog ./the_test.sv
 
# vopt work.glbl tb_top -L secureip -L simprims_ver -L unisims_ver -f opt_tb_top.f -o opt_tb_top
 
# run the sim
sim_run_test
 
 
 
/sim/tests/tb_axis_upsizer/sim.do
0,0 → 1,16
#
#
 
 
quit -sim
 
# vsim opt_tb_top
vsim -novopt work.tb_top
# vsim -novopt -L secureip -L simprims_ver -L unisims_ver work.glbl work.tb_top
 
# log all signals
log -r *
 
# run -all
 
 
/sim/tests/tb_axis_upsizer/tb_axis_upsizer.f
0,0 → 1,6
#
 
${PROJECT_DIR}/sim/src/tb_axis_upsizer_agent_class_pkg.sv
${PROJECT_DIR}/sim/src/tb_axis_upsizer_class_pkg.sv
${PROJECT_DIR}/src/axis_upsizer.sv
/sim/tests/tb_axis_upsizer/the_test.sv
0,0 → 1,98
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ps/1ps
 
 
module
the_test(
input tb_clk,
input tb_rst
);
 
// --------------------------------------------------------------------
//
int mismatch_count = 0;
 
 
// --------------------------------------------------------------------
//
task run_the_test;
 
// --------------------------------------------------------------------
// insert test below
// --------------------------------------------------------------------
$display("^^^---------------------------------");
$display("^^^ %16.t | Testbench begun.\n", $time);
$display("^^^---------------------------------");
 
// --------------------------------------------------------------------
tb_top.tb.timeout_stop(50us);
 
 
// --------------------------------------------------------------------
wait(tb_top.aresetn);
#1us;
 
// --------------------------------------------------------------------
repeat(3) tb_top.a_h.queue_frame("counting");
repeat(3) tb_top.a_h.compare_frame();
 
// --------------------------------------------------------------------
tb_top.a_h.tx_h.make_frame("constant", 16'habba);
tb_top.a_h.queue_frame();
tb_top.a_h.compare_frame();
 
tb_top.a_h.queue_frame("random");
tb_top.a_h.compare_frame();
 
tb_top.a_h.queue_frame("constant", 16'hbeef);
tb_top.a_h.compare_frame();
 
tb_top.a_h.queue_frame("random");
tb_top.a_h.rx_h.wait_for_rx_frames(1);
tb_top.a_h.compare_frame();
 
tb_top.a_h.queue_frame("counting");
tb_top.a_h.compare_frame();
 
repeat(3) tb_top.a_h.queue_frame("random");
repeat(3) tb_top.a_h.compare_frame();
 
// --------------------------------------------------------------------
#1us;
// #6us;
 
// --------------------------------------------------------------------
// insert test above
// --------------------------------------------------------------------
 
endtask
 
 
endmodule
 
/src/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
/src/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
 
 
/src/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
 
 
/src/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
 
/src/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;
/src/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
 
/src/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
 
/src/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
 
/src/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
 
 
/src/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
/src/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
);
 
//---------------------------------------------------
/syn/src/axis_if.sv
49,8 → 49,38
wire [U-1:0] tuser;
 
 
// --------------------------------------------------------------------
// 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 tvalid;
output tready;
input tdata;
input tstrb;
input tkeep;
input tlast;
input tid;
input tdest;
input tuser;
endclocking
 
 
// --------------------------------------------------------------------
//
modport
master
(
64,7 → 94,8
output tlast,
output tid,
output tdest,
output tuser
output tuser,
clocking cb_m
);
 
 
83,10 → 114,15
input tlast,
input tid,
input tdest,
input tuser
input tuser,
clocking cb_s
);
 
 
// synthesis translate_on
// --------------------------------------------------------------------
 
 
endinterface: axis_if
 
 

powered by: WebSVN 2.1.0

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