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/libs/sync_fifo_verilog/tiny_fifo.f
File deleted
/sim/libs/axi4_stream_lib_verilog/axi4_stream_lib.f
File deleted
/sim/libs/sim_verilog/tb_lib.f
File deleted
/sim/libs/sim_verilog/avf.f
File deleted
/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 |
|
|