// serialize natural order parallel packet
// valid only, no ready signal (ready=1 assuming)

`timescale 1 ps / 1 ps
module compare_ffts #(
	parameter DATAWIDTH = 29 // data size (real/imag of data)
)
(
		input	clk,
		input	reset_n,

		input	org_valdata,
		input  [DATAWIDTH*2+1:0] org_avst_packs, // sop, eop, data(real, imag)
		input	dff_valdata,
		input  [DATAWIDTH*2+1:0] dff_avst_packs, // sop, eop, data(real, imag)
		
		output	compare,
		output	signed [DATAWIDTH-1:0] diff_real,
		output	signed [DATAWIDTH-1:0] diff_imag,
		output	error //,
);
localparam ADDRWIDTH = 15; // 4096 * 8 = 2 ** 15

// comparing signals (output of FIFO)
wire	org_sop, org_eop;
wire	signed [DATAWIDTH-1:0]	org_real, org_imag;
wire	dff_sop, dff_eop;
wire	signed [DATAWIDTH-1:0]	dff_real, dff_imag;

// FIFO flags
wire	full_orgbuf, empty_orgbuf, ovf_orgbuf, udf_orgbuf;
wire	full_dffbuf, empty_dffbuf, ovf_dffbuf, udf_dffbuf;

assign compare = ({empty_orgbuf, empty_dffbuf}==2'b00) ? 1'b1 : 1'b0; // NOR of empty

fifo_regout #(DATAWIDTH*2+2,ADDRWIDTH) FIFO_ORG (
		.clk(clk),
		.reset_n(reset_n),
		.we(org_valdata),
		.din(org_avst_packs),
		.re(compare),
		.dout( { org_sop, org_eop, org_real, org_imag } ),
		.flags( {full_orgbuf, empty_orgbuf, ovf_orgbuf, udf_orgbuf} ) // ,
);

fifo_regout #(DATAWIDTH*2+2,ADDRWIDTH) FIFO_DFF (
		.clk(clk),
		.reset_n(reset_n),
		.we(dff_valdata),
		.din(dff_avst_packs),
		.re(compare),
		.dout( { dff_sop, dff_eop, dff_real, dff_imag } ),
		.flags( { full_dffbuf, empty_dffbuf, ovf_dffbuf, udf_dffbuf } ) // ,
);

assign diff_real = ( compare ) ? ( dff_real - org_real ) : {DATAWIDTH{1'b0}};
assign diff_imag = ( compare ) ? ( dff_imag - org_imag ) : {DATAWIDTH{1'b0}};

assign error = ( compare ) ? ( {org_sop, org_eop}!={dff_sop, dff_eop} ) :
					(|( {ovf_orgbuf, udf_orgbuf, ovf_dffbuf, udf_dffbuf} )) ; // check if not compare (delayed)

endmodule
 