URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
[/] [qaz_libs/] [trunk/] [video/] [src/] [fifo_to_avf.sv] - Rev 49
Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2019 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
module
fifo_to_avf #(AW, AH, D, B=2, T=1, N=B*T)
(
input [(N*8)-1:0] tdata,
input wr_en,
output wr_full,
output sof,
output sol,
output eol,
output eof,
output reg [$clog2(AW)-1:0] n,
output reg [$clog2(AH)-1:0] m,
wire error,
axis_if axis_out,
input aclk,
input aresetn
);
// --------------------------------------------------------------------
// synthesis translate_off
initial
assert(AW % T == 0) else $fatal;
// synthesis translate_on
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// / \
// | A_00 A_01 .... A_0n |
// | A_10 A_11 .... A_1n |
// | .... .... .... .... |
// | A_m0 A_m1 .... A_mn |
// \ /
// --------------------------------------------------------------------
localparam U = 3;
localparam W = (N*8) + U + 1; // tdata + tuser + tlast
// --------------------------------------------------------------------
// tuser[0] = SOF; tuser[1] = SOL; tlast = EOL; tuser[2] = EOF;
wire tlast = eol;
wire [U-1:0] tuser = {eof, sol, sof};
wire [W-1:0] wr_data = {tlast, tuser, tdata};
wire rd_empty;
wire [W-1:0] rd_data;
wire rd_en;
wire [$clog2(D):0] count;
sync_fifo #(W, D) fifo_i(.clk(aclk), .reset(~aresetn), .*);
// --------------------------------------------------------------------
wire almost_eol = (n == AW - (2*T));
always_ff @(posedge aclk)
if(~aresetn | (wr_en & eol))
n <= 0;
else if(wr_en)
n <= n + T;
// --------------------------------------------------------------------
wire last_pixel = (m == AH - 1);
always_ff @(posedge aclk)
if(~aresetn | (wr_en & eof))
m <= 0;
else if(wr_en & eol)
m <= m + 1;
// --------------------------------------------------------------------
enum reg [2:0]
{
SOF = 3'b001,
LINE = 3'b010,
EOL = 3'b100
} prior_state, state, next_state;
// --------------------------------------------------------------------
always_ff @(posedge aclk)
if(~aresetn)
state <= SOF;
else
state <= next_state;
// --------------------------------------------------------------------
always_ff @(posedge aclk)
if(wr_en)
prior_state <= state;
// --------------------------------------------------------------------
always_comb
case(state)
SOF: if(wr_en)
next_state <= LINE;
else
next_state <= SOF;
LINE: if(wr_en & almost_eol)
next_state <= EOL;
else
next_state <= LINE;
EOL: if(wr_en)
if(last_pixel) // EOF
next_state <= SOF;
else
next_state <= LINE;
else
next_state <= EOL;
default: next_state <= SOF;
endcase
// --------------------------------------------------------------------
assign error = (wr_en & wr_full);
assign sof = (state == SOF);
assign sol = (state == SOF) | ((state == LINE) & (prior_state == EOL));
assign eof = (state == EOL) & last_pixel;
assign eol = (state == EOL);
// --------------------------------------------------------------------
assign rd_en = axis_out.tvalid & axis_out.tready;
assign axis_out.tvalid = ~rd_empty;
assign {axis_out.tlast, axis_out.tuser[U-1:0], axis_out.tdata} = rd_data;
// --------------------------------------------------------------------
endmodule