
module butterfly(clk,reset,sink_valid, ar_in, ai_in, br_in, bi_in, 
WNr_in, WNi_in, ar_out, ai_out, br_out, bi_out,source_valid);

input clk,reset,sink_valid;
input [15 : 0] ar_in,ai_in,br_in,bi_in,WNr_in,WNi_in;
output source_valid;
output[17 : 0] ar_out,ai_out,br_out,bi_out;

parameter scale=8'b0100_0000; //former scale  32  not 64
parameter idle=2'b00,work=2'b01;
reg [16 : 0] real_a,imag_a,real_b,imag_b,real_WN_in,imag_WN_in;
reg [7:0] cnt,next_cnt;
reg [1:0] current_state,next_state;

wire source_valid;
wire [16 : 0] ADDreal_out,ADDimag_out,SUBreal_out, SUBimag_out;
wire[33:0]complex_real,complex_imag;


always@(sink_valid or current_state or cnt)begin
	case(current_state)
		idle:if(sink_valid==1'b1)begin
				next_cnt=8'b0000_0001;
				next_state=work;
			 end
			 else begin
				next_cnt=8'b0000_0000;
				next_state=idle;
			 end
		work:if(cnt<scale+8'b0000_0100)begin//attention!!
				next_cnt=cnt+8'b0000_0001;
				next_state=work;
			 end
			 else begin
				next_cnt=8'b0000_0000;
				next_state=idle;
			 end
	endcase
end		
			
always@(posedge clk or negedge reset)begin
if(!reset)begin
	cnt<=0;
	current_state<=idle;
	real_a<=0;
	imag_a<=0;
	real_b<=0;
	imag_b<=0;
	real_WN_in<=0;
	imag_WN_in<=0;
	end
else begin
	cnt<=next_cnt;
	current_state<=next_state;
	if(sink_valid==1)begin
		real_a={ar_in[15],ar_in};
		imag_a={ai_in[15],ai_in};
		real_b={br_in[15],br_in};
		imag_b={bi_in[15],bi_in};
		real_WN_in={WNr_in[15],WNr_in};
		imag_WN_in={WNi_in[15],WNi_in};
		end
	end
end

ADD_17 add_real(.clock(clk), .dataa(real_a), .datab(real_b), .result(ADDreal_out));
ADD_17 add_imag(.clock(clk), .dataa(imag_a), .datab(imag_b), .result(ADDimag_out));
SUB_17 sub_real(.dataa(real_a), .datab(real_b), .result(SUBreal_out));
SUB_17 sub_imag(.dataa(imag_a), .datab(imag_b), .result(SUBimag_out));
complex_mult mult(.clock(clk), .dataa_real(real_WN_in), .dataa_imag(imag_WN_in), .datab_real(SUBreal_out), 
.datab_imag(SUBimag_out),.result_real(complex_real), .result_imag(complex_imag));

assign 	ar_out=(cnt>0)?{ADDreal_out[16],ADDreal_out}:18'b0000_0000_0000_0000_00;
assign 	ai_out=(cnt>0)?{ADDimag_out[16],ADDimag_out}:18'b0000_0000_0000_0000_00;
assign	br_out=(cnt>0)?complex_real[32:15]:18'b0000_0000_0000_0000_00;
assign	bi_out=(cnt>0)?complex_imag[32:15]:18'b0000_0000_0000_0000_00;
assign  source_valid=(cnt>4)?1'b1:1'b0;
endmodule 
