URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
Compare Revisions
- This comparison shows the changes necessary to convert path
/qaz_libs/trunk/axi4_stream_lib/src
- from Rev 23 to Rev 28
- ↔ Reverse comparison
Rev 23 → Rev 28
/axis_flow_control.sv
0,0 → 1,127
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_flow_control |
#( |
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 |
) |
( |
input axis_en, |
input flow_enable, // enable / disable incoming tready & tvalid |
input [1:0] tready_to_master_select, // 00:force 0, 01:force 1, 1X:from_slave |
input [1:0] tvalid_to_master_select, // 00:force 0, 01:force 1, 1X:from_slave |
output tready_from_slave, // from input of mux |
output tvalid_from_slave, // from input of mux |
axis_if.slave axis_in, |
axis_if.master axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
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; |
|
data_to_axis_fsm |
data_to_axis_fsm_i |
( |
.axis_tvalid(tvalid_from_slave), // axis_out.tvalid |
.axis_tready(flow_enable & axis_out.tready), |
.fifo_empty(fifo_source.empty), |
.fifo_rd_en(fifo_source.rd_en), |
.fifo_watermark(1'b1), |
.* |
); |
|
|
// -------------------------------------------------------------------- |
// |
reg axis_in_tready_r; |
assign axis_in.tready = axis_in_tready_r; |
|
always_comb |
case(tready_to_master_select) |
2'b00: axis_in_tready_r = 0; |
2'b01: axis_in_tready_r = 1; |
2'b10: axis_in_tready_r = tready_from_slave; |
2'b11: axis_in_tready_r = tready_from_slave; |
endcase |
|
|
// -------------------------------------------------------------------- |
// |
reg axis_out_tvalid_r; |
assign axis_out.tvalid = axis_out_tvalid_r; |
|
always_comb |
case(tvalid_to_master_select) |
2'b00: axis_out_tvalid_r = 0; |
2'b01: axis_out_tvalid_r = 1; |
2'b10: axis_out_tvalid_r = tvalid_from_slave; |
2'b11: axis_out_tvalid_r = tvalid_from_slave; |
endcase |
|
|
// -------------------------------------------------------------------- |
// |
assign tready_from_slave = ~fifo_sink.full; // axis_in.tready |
|
assign fifo_sink.wr_en = flow_enable & axis_in.tvalid & ~fifo_sink.full; |
assign fifo_sink.wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser |
}; |
|
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser |
} = fifo_source.rd_data; |
|
|
endmodule |
|
/axis_mux.sv
0,0 → 1,91
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_mux |
#( |
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 |
) |
( |
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 |
); |
|
// -------------------------------------------------------------------- |
// |
axis_if #(.N(N), .I(I), .D(D), .U(U)) |
axis_mux_out(.*); |
|
assign axis_0_in.tready = mux_select ? 0 : axis_mux_out.tready; |
assign axis_1_in.tready = mux_select ? axis_mux_out.tready : 0; |
|
assign axis_mux_out.tvalid = mux_select ? axis_1_in.tvalid : axis_0_in.tvalid; |
assign axis_mux_out.tdata = mux_select ? axis_1_in.tdata : axis_0_in.tdata; |
assign axis_mux_out.tstrb = mux_select ? axis_1_in.tstrb : axis_0_in.tstrb; |
assign axis_mux_out.tkeep = mux_select ? axis_1_in.tkeep : axis_0_in.tkeep; |
assign axis_mux_out.tlast = mux_select ? axis_1_in.tlast : axis_0_in.tlast; |
assign axis_mux_out.tid = mux_select ? axis_1_in.tid : axis_0_in.tid; |
assign axis_mux_out.tdest = mux_select ? axis_1_in.tdest : axis_0_in.tdest; |
assign axis_mux_out.tuser = mux_select ? axis_1_in.tuser : axis_0_in.tuser; |
|
|
// -------------------------------------------------------------------- |
// |
axis_register_slice |
#( |
.N(N), |
.I(I), |
.D(D), |
.U(U), |
.USE_TSTRB(USE_TSTRB), |
.USE_TKEEP(USE_TKEEP) |
) |
axis_register_slice_i |
( |
.axis_in(axis_mux_out), // .slave |
.axis_out(axis_out), // .master |
.* |
); |
|
|
// -------------------------------------------------------------------- |
// |
|
|
endmodule |
|
|
/axis_register_slice.sv
0,0 → 1,159
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2015 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module |
axis_register_slice |
#( |
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 |
) |
( |
input axis_en, |
axis_if.slave axis_in, |
axis_if.master axis_out, |
input aclk, |
input aresetn |
); |
|
// -------------------------------------------------------------------- |
// |
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; |
|
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), |
.* |
); |
|
|
// -------------------------------------------------------------------- |
// |
generate |
begin: assign_gen |
|
if(USE_TSTRB & USE_TKEEP) |
begin |
assign fifo_sink.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 |
} = fifo_source.rd_data; |
end |
else if(USE_TSTRB) |
begin |
assign fifo_sink.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 |
} = fifo_source.rd_data; |
end |
else if(USE_TKEEP) |
begin |
assign fifo_sink.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 |
} = fifo_source.rd_data; |
end |
else |
begin |
assign fifo_sink.wr_data = |
{ |
axis_in.tdata, |
axis_in.tlast, |
axis_in.tuser |
}; |
assign |
{ |
axis_out.tdata, |
axis_out.tlast, |
axis_out.tuser |
} = fifo_source.rd_data; |
end |
|
end |
endgenerate |
|
|
// -------------------------------------------------------------------- |
// |
assign axis_in.tready = ~fifo_sink.full; |
assign fifo_sink.wr_en = axis_in.tvalid & ~fifo_sink.full; |
|
|
|
endmodule |
|
/axis_to_vid_fsm.sv
0,0 → 1,136
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
|
module |
axis_to_vid_fsm |
( |
input axis_to_vid_fsm_en, |
input [31:0] reg_active_size, |
input [15:0] reg_hblanking, |
input [15:0] reg_vblanking, |
|
input vid_sof, |
input vid_eol, |
input vid_stall_at_vblank, |
|
output fifo_rd_en, |
|
output vid_timing_fsm_idle, |
output vid_active_video, |
output vid_hblank, |
output vid_vblank, |
output vid_timing_fsm_error, |
|
input vid_clk, |
input vid_clk_en, |
input vid_reset |
); |
|
// -------------------------------------------------------------------- |
// |
reg [15:0] pixel_counter; |
reg [15:0] line_counter; |
wire [15:0] active_hsize = reg_active_size[15:0]; |
wire [15:0] active_vsize = reg_active_size[31:16]; |
|
|
//--------------------------------------------------- |
// state machine binary definitions |
enum reg [4:0] { |
IDLE_STATE = 5'b0_0001, |
PIXEL_DATA = 5'b0_0010, |
HORIZONTAL_BLANKING = 5'b0_0100, |
VERTICAL_BLANKING = 5'b0_1000, |
ERROR_STATE = 5'b1_0000 |
} state, next_state; |
|
|
//--------------------------------------------------- |
// state machine flop |
always_ff @(posedge vid_clk) |
if(vid_reset) |
state <= IDLE_STATE; |
else if(vid_clk_en) |
state <= next_state; |
|
|
//--------------------------------------------------- |
// state machine |
always_comb |
case(state) |
IDLE_STATE: if(axis_to_vid_fsm_en) |
if(vid_stall_at_vblank) |
next_state <= VERTICAL_BLANKING; |
else |
next_state <= PIXEL_DATA; |
else |
next_state <= IDLE_STATE; |
|
PIXEL_DATA: if(vid_eol) |
next_state <= HORIZONTAL_BLANKING; |
else |
next_state <= PIXEL_DATA; |
|
HORIZONTAL_BLANKING: if(pixel_counter < reg_hblanking) |
next_state <= HORIZONTAL_BLANKING; |
else if(line_counter < active_vsize) |
next_state <= PIXEL_DATA; |
else |
next_state <= VERTICAL_BLANKING; |
|
VERTICAL_BLANKING: if(pixel_counter < reg_vblanking) |
next_state <= VERTICAL_BLANKING; |
else if(axis_to_vid_fsm_en) |
if(vid_stall_at_vblank) |
next_state <= VERTICAL_BLANKING; |
else |
next_state <= PIXEL_DATA; |
else |
next_state <= IDLE_STATE; |
|
ERROR_STATE: next_state <= IDLE_STATE; |
|
default: next_state <= ERROR_STATE; |
|
endcase |
|
|
// -------------------------------------------------------------------- |
// |
wire pixel_counter_reset = vid_reset | (state == IDLE_STATE) | (state != next_state); |
|
always_ff @(posedge vid_clk) |
if(pixel_counter_reset) |
pixel_counter <= 1; |
else if(vid_clk_en) |
pixel_counter <= pixel_counter + 1; |
|
|
// -------------------------------------------------------------------- |
// |
wire line_counter_reset = vid_reset | |
(state == IDLE_STATE) | |
(vid_sof & (state != next_state)); |
|
always_ff @(posedge vid_clk) |
if(line_counter_reset) |
line_counter <= 0; |
else if(vid_clk_en & (state == PIXEL_DATA) & vid_eol) |
line_counter <= line_counter + 1; |
|
|
//--------------------------------------------------- |
// output |
assign vid_timing_fsm_error = (state == ERROR_STATE); |
assign vid_timing_fsm_idle = (state == IDLE_STATE); |
assign vid_active_video = (state == PIXEL_DATA); |
assign vid_hblank = (state == HORIZONTAL_BLANKING); |
assign vid_vblank = (state == VERTICAL_BLANKING); |
assign fifo_rd_en = vid_active_video; |
|
endmodule |
|
|
|
/camera_link_to_axis.sv
0,0 → 1,59
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
|
module |
camera_link_to_axis |
#( |
DATA_IN_WIDTH = 64 // same as axis_out_bus.TDATA_WIDTH |
) |
( |
axis_if.master axis_out_bus, |
input [DATA_IN_WIDTH-1:0] cl_data_in, |
input cl_frame_valid, |
input cl_line_valid, |
input cl_data_valid, |
input cl_reset, // same as axis_out_bus.aresetn |
input cl_clk // same as axis_out_bus.aclk |
); |
|
// -------------------------------------------------------------------- |
// |
reg [DATA_IN_WIDTH-1:0] cl_data_in_r0; |
reg cl_frame_valid_r0; |
reg cl_line_valid_r0; |
reg cl_data_valid_r0; |
|
always @(posedge cl_clk) |
begin |
cl_data_in_r0 <= cl_data_in; |
cl_frame_valid_r0 <= cl_frame_valid; |
cl_line_valid_r0 <= cl_line_valid; |
cl_data_valid_r0 <= cl_data_valid; |
end |
|
|
// -------------------------------------------------------------------- |
// |
reg [DATA_IN_WIDTH-1:0] cl_data_in_r1; |
reg cl_frame_valid_r1; |
reg cl_line_valid_r1; |
reg cl_data_valid_r1; |
|
always @(posedge cl_clk) |
begin |
cl_data_in_r1 <= cl_data_in_r0; |
cl_frame_valid_r1 <= cl_frame_valid_r0; |
cl_line_valid_r1 <= cl_line_valid_r0; |
cl_data_valid_r1 <= cl_data_valid_r0; |
end |
|
|
// -------------------------------------------------------------------- |
// |
|
|
endmodule |
|
|
/camera_link_to_axis_fsm.sv
0,0 → 1,83
// -------------------------------------------------------------------- |
// |
// -------------------------------------------------------------------- |
|
|
module |
camera_link_to_axis_fsm |
( |
input axis_en, |
output axis_tvalid, |
input axis_tready, |
|
input fifo_almost_full, |
input fifo_empty, |
output fifo_rd_en, |
|
output data_to_axis_fsm_error, |
|
input aclk, |
input aresetn |
); |
|
//--------------------------------------------------- |
// state machine binary definitions |
enum reg [3:0] { |
IDLE_STATE = 4'b0001, |
TVALID = 4'b0010, |
TREADY = 4'b0100, |
ERROR_STATE = 4'b1000 |
} state, next_state; |
|
|
//--------------------------------------------------- |
// state machine flop |
always_ff @(posedge aclk) |
if(~aresetn) |
state <= IDLE_STATE; |
else |
state <= next_state; |
|
|
//--------------------------------------------------- |
// state machine |
always_comb |
case(state) |
IDLE_STATE: if(axis_en & fifo_almost_full) |
if(axis_tready) |
next_state <= TREADY; |
else |
next_state <= TVALID; |
else |
next_state <= IDLE_STATE; |
|
TVALID: if(axis_tready) // wait for slave to be ready |
next_state <= TREADY; |
else |
next_state <= TVALID; |
|
TREADY: if(fifo_empty) // slave can accept data |
next_state <= IDLE_STATE; |
else if(axis_tready) |
next_state <= TREADY; |
else |
next_state <= TVALID; |
|
ERROR_STATE: next_state <= IDLE_STATE; |
|
default: next_state <= ERROR_STATE; |
|
endcase |
|
|
//--------------------------------------------------- |
// outputs |
assign axis_tvalid = (next_state == TVALID) | (next_state == TREADY); |
assign fifo_rd_en = axis_tvalid & axis_tready; |
assign data_to_axis_fsm_error = (state == ERROR_STATE); |
|
|
endmodule |
|
|
|
/data_to_axis_fsm.sv
66,7 → 66,7
// state machine |
always_comb |
case(state) |
IDLE_STATE: if(axis_en & fifo_watermark) |
IDLE_STATE: if(axis_en & fifo_watermark & ~fifo_empty) |
if(axis_tready) |
next_state <= TREADY; |
else |