// Avalon ST "CONSTANT" DELAY WITHOUT WAIT (Back pressure, ready)
// Assuming NO back pressure SO ignore src_ready and fix snk ready = H
// It has a risk to lose the data in a transfer at source side
module AVSTDLYNOWAT
#(
	parameter DATAWIDTH = 32,
	parameter LATENCY = 6 //,
)
(
	input clk,
	input reset_n,

	// Input side (sink:snk) AVST port
	input snk_valid,
	output snk_ready, // fixed 1
	input [1:0] snk_error,
	input snk_sop,
	input snk_eop,
	input [DATAWIDTH-1:0] snk_data,
	
	// I/O for single src side
	output src_valid,
	input src_ready,
	output [1:0] src_error,
	output src_sop,
	output src_eop,
	output [DATAWIDTH-1:0] src_data //,
);

	// DATA buffer array
	reg [1:0] buf_error [1:LATENCY];
	reg buf_sop [1:LATENCY];
	reg buf_eop [1:LATENCY];
	reg [DATAWIDTH-1:0] buf_data [1:LATENCY];

	// VALID buffer array
	reg	valid_buf [1:LATENCY];

	// for connection in generate loop
	wire [1:0] in_error [0:LATENCY];
	wire in_sop [0:LATENCY];
	wire in_eop [0:LATENCY];
	wire [DATAWIDTH-1:0] in_data [0:LATENCY];
	wire in_valid [0:LATENCY];
	
	wire src_lost_data; // only for simulation

	genvar i;

	assign { in_valid[0], in_error[0], in_sop[0], in_eop[0], in_data[0] }
		=  { snk_valid,   snk_error,   snk_sop,   snk_eop,   snk_data } ;
	
	generate for(i = 1; i <= LATENCY; i = i + 1) begin: GEN_LOOP
		always @(posedge clk or negedge reset_n)
			if( ~reset_n )
				{ valid_buf[i], buf_error[i], buf_sop[i], buf_eop[i], buf_data[i] }
					<= {(5+DATAWIDTH){1'b0}};
			else // no condition shift
				{ valid_buf[i], buf_error[i], buf_sop[i], buf_eop[i], buf_data[i] }
					<= 
				{ in_valid[i-1], in_error[i-1], in_sop[i-1], in_eop[i-1], in_data[i-1] } ;
		assign { in_valid[i], in_error[i], in_sop[i], in_eop[i], in_data[i] }
			=  { valid_buf[i], buf_error[i], buf_sop[i], buf_eop[i], buf_data[i] } ;
	end
	endgenerate

assign	snk_ready = 1'b1; // temporalily fixed to 1

assign	src_valid = in_valid[LATENCY];
assign	src_error = in_error[LATENCY];
assign	src_sop = in_sop[LATENCY];
assign	src_eop = in_eop[LATENCY];
assign	src_data = in_data[LATENCY];

assign	src_lost_data = src_valid & (~src_ready); // detect src data lost (simulation only)
	
endmodule