module butterfly_2048x2(
   input clk, 
   input reset_n,
   
   input  snk_valid,
   // output snk_ready, // combinational from source (NO WAIT version fix ready=1)
   
   // 	input [12 : 0] // fftpts_in, current version is only for 2048 x2
   // 	input	[0 : 0] // inverse, current version is only for forward mode

	input	snk_sop,
	input	snk_eop, // current version is ony through

	input	[27 : 0] snk_real_ev,
	input	[27 : 0] snk_imag_ev,
	input	[27 : 0] snk_real_od,
	input	[27 : 0] snk_imag_od,

	// input	[1 : 0] snk_error, // current version ignores error

	output	src_valid,
	// input	src_ready, // NO WAIT version fix ready=1
    // output [12 : 0] fftpts_out,
	// output [1 : 0] source_error, // current version ignores error
	output src_sop,
	output src_eop,
	output	[28 : 0] src_real_lo,
	output	[28 : 0] src_imag_lo,
	output	[28 : 0] src_real_hi,
	output	[28 : 0] src_imag_hi //,

	);

// twiddle rom data
wire [35:0] twdl_data;

// input for twiddle complex multipler "rotator" : "rtin"
wire	[27:0] rtin_real, rtin_imag;
// output for twiddle complex multipler : "rtout"
wire	[46:0] rtout_real, rtout_imag;
// output from rounded output : "rdout"
wire	[27:0] rdout_real, rdout_imag;
// output from pipeline register stage after round
wire	[27:0] rdreg_real, rdreg_imag;
// input for last butterfly (only add/sub) "lbin"
// wire	lbin_valid;
wire	lbin_ev_valid;
wire	[27:0] lbin_real_ev, lbin_imag_ev; // , lbin_real_od, lbin_imag_od; // (<- rdout)
// output from last butterfly lower and higher part "lbout"
wire	[28:0] lbout_real_lo, lbout_imag_lo, lbout_real_hi, lbout_imag_hi;

AVSTDLYNOWAT #(56,10) DFFT_EVDLY ( // 1 clock increase from previous version (ROM 4, MULT 5, ROUND 1)
	.clk(clk),
	.reset_n(reset_n),

	// Input side (sink:snk) AVST port
	.snk_valid(snk_valid),
	.snk_ready(), // cominational
	.snk_error(2'b00),
	.snk_sop(snk_sop),
	.snk_eop(snk_eop),
	.snk_data({snk_real_ev, snk_imag_ev}),
	
	// I/O for single src side 
	.src_valid(lbin_ev_valid),
	.src_ready(1'b1),
	.src_error(),
	.src_sop(src_sop),
	.src_eop(src_eop),
	.src_data({lbin_real_ev, lbin_imag_ev}) //, DATAWIDTH doubled
);

AVSTDLYNOWAT #(56,4) DFFT_ODDLY (
	.clk(clk),
	.reset_n(reset_n),

	// Input side (sink:snk) AVST port
	.snk_valid(snk_valid),
	.snk_ready(), // not used (same as even side)
	.snk_error(2'b00),
	.snk_sop(snk_sop),
	.snk_eop(1'b0),
	.snk_data({snk_real_od, snk_imag_od}),
	
	// I/O for single src side (on half rate clock)
	.src_valid(),
	.src_ready(1'b1),
	.src_error(),
	.src_sop(),
	.src_eop(),
	.src_data({rtin_real, rtin_imag}) //, DATAWIDTH doubled
);

readtwdl test_rom(
		.clk          (clk),              //    clk.clk
		.reset_n      (reset_n),          //    rst.reset_n

	.sclr(snk_sop),
	.read(snk_valid),
	.data(twdl_data) //, 
);

MULTWD U_ROTATOR(
		.dataa_real(rtin_real),  //  complex_input.dataa_real
		.dataa_imag(rtin_imag),  //               .dataa_imag
		.datab_real(twdl_data[35:18]),  //               .datab_real
		.datab_imag(twdl_data[17:0 ]),  //               .datab_imag
		.clock(clk),       //               .clk
		.aclr(~reset_n),        //               .aclr
		// .ena(1'b1),         //               .ena
		.result_real(rtout_real), // complex_output.result_real
		.result_imag(rtout_imag)  //               .result_imag
	);
	
roundtrunc U_RNDTRN_RE(
	.din(rtout_real),
	.overflow(),
	.dout(rdout_real) //,
);

roundtrunc U_RNDTRN_IM(
	.din(rtout_imag),
	.overflow(),
	.dout(rdout_imag) //,
);

DELAY #(56,1) PPREG_RDOUT (
	.clk(clk),
	.reset_n(reset_n),

	.din({rdout_real, rdout_imag}),
	.dout({rdreg_real, rdreg_imag}) //,
);

last_butterfly U_LBUT( // combinational (latency=0)
		.din_real_ev(lbin_real_ev),
		.din_imag_ev(lbin_imag_ev),
		.din_real_od(rdreg_real), // (rdout_real),
		.din_imag_od(rdreg_imag), // (rdout_imag),

		.dout_real_lo(lbout_real_lo),
		.dout_imag_lo(lbout_imag_lo),
		.dout_real_hi(lbout_real_hi),
		.dout_imag_hi(lbout_imag_hi) // ,
);

assign	src_valid = lbin_ev_valid;

assign 	{ src_real_lo, src_imag_lo, src_real_hi, src_imag_hi } = 
		{ lbout_real_lo, lbout_imag_lo, lbout_real_hi, lbout_imag_hi };

endmodule
