// If valid data comes intermittently, keep them until "BURSTSIZE" packets stocked,
// then output "BURSTSIZE" packets consectively

module pack_tank
#(
	parameter DATAWIDTH = 32,
	parameter BURSTSIZE = 1
)
(
	input clk,
	input reset_n,

	// Input side (sink:snk) AVST port
	input snk_valid,
	output snk_ready,
	input [DATAWIDTH+3:0] snk_pack, // snk_error, snk_sop, snk_eop, snk_data,
	
	// I/O for single src side (on half rate clock)
	output src_valid,
	input src_ready,
	output [DATAWIDTH+3:0] src_pack //, src_error, src_sop, src_eop, src_data

);
 // packing port signals

	wire [1:0] snk_error;
	wire snk_sop;
	wire snk_eop;
	wire [DATAWIDTH-1:0] snk_data;
	
	wire [1:0] src_error;
	wire src_sop;
	wire src_eop;
	wire [DATAWIDTH-1:0] src_data; //,

// control logic signals ( and FIFO status)
	
	wire snk_tfr, src_tfr;
	wire full, empty, ovf, udf ;
	wire we_snk, re_src;
	
// packet countung and flow control
	reg [10:0] stock_packs;	// stocked packets count in FIFO
	reg [3:0] paying_packs;	// current paying out packes allowed by "BURSTSIZE" (this counter must content the size)

assign snk_tfr = snk_valid & snk_ready;
assign src_tfr = src_valid & src_ready;
	
// I/O wire fragment
assign { snk_error, snk_sop, snk_eop, snk_data } = snk_pack;
// assign src_pack = { src_error, src_sop, src_eop, src_data };
assign { src_error, src_sop, src_eop, src_data } = src_pack; // driven by easy_fifo

fifo_regout #(DATAWIDTH + 4, 14) BURST_TANK
(
		.clk(clk),	
		.reset_n(reset_n),
		.we(we_snk),
		.din(snk_pack),
		.re(re_src),
		.dout(src_pack),
		.flags( {full, empty, ovf, udf} ) // ,
);

// Write enable control : if FIFO is not full, it can accept a transfer
assign snk_ready = ~full;
assign we_snk = snk_tfr;

// packet save, stock and paying counting and flow control
always @(posedge clk or negedge reset_n)
	if( ~reset_n ) stock_packs <= 11'd0;
	else
		stock_packs <= stock_packs
			+ ( ( snk_tfr & snk_eop ) ? 11'd1 : 11'd0 )   // saving a packet input
			- ( ( src_tfr & src_eop ) ? 11'd1 : 11'd0 ) ; // paying a packet output	
// end of always

always @(posedge clk or negedge reset_n)
	if( ~reset_n ) paying_packs <= 11'd0;
	else if( paying_packs==11'd0 ) 
		paying_packs <= ( stock_packs >= BURSTSIZE ) ? BURSTSIZE : 11'd0 ;
	else if( (paying_packs==11'd1)&&( stock_packs > BURSTSIZE ) )
		paying_packs <= ( src_tfr & src_eop ) ? BURSTSIZE : 11'd1 ;
	else // paying_packs > 1 or stock_packs <= BURSTSIZE
		paying_packs <= ( src_tfr & src_eop ) ? ( paying_packs - 11'd1) : paying_packs ;
// end of always

// read "paying" enable control
assign src_valid = (paying_packs!=0) ? 1'b1 : 1'b0 ;
assign re_src = src_tfr;

endmodule