module sdr_wrap(
  input	clk,
  input clkx2,
  input clkx2deg45,
  input	rst_n,
  input  [15:0] D_Sensor_1_In,
  input  [15:0] D_Sensor_2_In,
  input  FV,
  input  LV,
  output reg [15:0] Data_Out,
  output LV_Out,
  output FV_Out,
  output RD_FIFO_n,
  
  inout  [15:0] sdr_DQ,        // sdr data
  output [11:0] sdr_A,         // sdr address
  output [1:0]  sdr_BA,        // sdr bank address
  output sdr_CKE,       // sdr clock enable
  output sdr_CSn,       // sdr chip select
  output sdr_RASn,      // sdr row address
  output sdr_CASn,      // sdr column select
  output sdr_WEn,       // sdr write enable
  output [1:0]  sdr_DQM,// sdr write data mask
  output sdr_clk
);
	
wire [11:0] w_row_addr;
wire wr_en, rd_en, prech_en, active_en, init_done;	
reg wr_en_1, wr_en_2, wr_en_3;
wire [11:0] D_Sensor_1_Out, D_Sensor_2_Out;
reg  [11:0] q_D_Sensor_1_Out, q_D_Sensor_2_Out;
reg q_fv, q_fv_1, q_fv_2, q_lv, q_lv_1, q_lv_2, fifo_sel, fifo_sel_1, fifo_sel_2;
wire [11:0] pixel_data_0, pixel_data_1;
wire [31:0] pixel_data_in;
reg  [52:0] LV_Dlyd, FV_Dlyd;
reg  [5:0]  fifo_out_wr_en;
wire RD_FIFO_n, frame_v;
reg RD_FIFO_n_1, RD_FIFO_n_2, RD_FIFO_n_3;

always@(posedge clk or negedge rst_n) begin
   if(!rst_n) begin
		q_fv   <= 0;
		q_fv_1 <= 0;
		q_fv_2 <= 0;
		q_lv   <= 0;
		q_lv_1 <= 0;
		q_lv_2 <= 0;
		Data_Out<= 0;
		fifo_sel <= 0;
		fifo_sel_1<=0;
		fifo_sel_2<=0;
		LV_Dlyd	<= 0;
		FV_Dlyd	<= 0;
		fifo_out_wr_en <= 0;
		wr_en_1	<=0;
		wr_en_2 <=0;
		wr_en_3 <=0;
		RD_FIFO_n_1<=0;
		RD_FIFO_n_2<=0;
		RD_FIFO_n_3<=0;
		q_D_Sensor_1_Out <= 0;
		q_D_Sensor_2_Out <= 0;
   end
   else begin 
   		q_fv   <= FV;
		q_fv_1 <= q_fv;
		q_fv_2 <= q_fv_1;
		q_lv   <= LV;
		q_lv_1 <= q_lv;
		q_lv_2 <= q_lv_1;
		Data_Out[11:0] <= fifo_sel_2 ? pixel_data_1 : pixel_data_0;
		fifo_sel <= LV_Dlyd[47] ? ~fifo_sel : 0;
		fifo_sel_1<= fifo_sel;
		fifo_sel_2<= fifo_sel_1;
		LV_Dlyd[52:1] <= {LV_Dlyd[51:1],LV};
		FV_Dlyd[52:1] <= {FV_Dlyd[51:1],FV};
		fifo_out_wr_en[5:1]<= {fifo_out_wr_en[4:1],rd_en};
		wr_en_1	<= wr_en;
		wr_en_2 <= wr_en_1;
		wr_en_3 <= wr_en_2;
		RD_FIFO_n_1<=RD_FIFO_n;
		RD_FIFO_n_2<=RD_FIFO_n_1;
		RD_FIFO_n_3<=RD_FIFO_n_2;
		q_D_Sensor_1_Out <= D_Sensor_1_Out;
		q_D_Sensor_2_Out <= D_Sensor_2_Out;
		
   end
end

assign LV_Out = LV_Dlyd[51];
assign FV_Out = FV_Dlyd[51];



FIFO_IN U4(.Reset(~rst_n || ~frame_v), 
 	 	 	  .Clock(clk), 
 	 	 	  .Din({D_Sensor_2_In[11:0], D_Sensor_1_In[11:0]}), 
 	 	 	  .Write_enable(LV), 
 	 	 	  .Read_enable(~RD_FIFO_n), 
 	 	 	  .Dout({D_Sensor_2_Out,D_Sensor_1_Out}), 
 	 	 	  .Full(), 
 	 	 	  .Empty() 
 	 	 	 ) ;
/*FIFO_IN U3(						//write fifo 1
	.Data({D_Sensor_2_In[11:0], D_Sensor_1_In[11:0]}), 
	.WrClock(clk), 
	.RdClock(clk), 
	.WrEn(LV), 
	.RdEn(~RD_FIFO_n), 
    .Reset(~rst_n || ~frame_v), 
    .RPReset(~rst_n || ~frame_v), 
    .Q({D_Sensor_2_Out,D_Sensor_1_Out}), 
    .Empty( ), 
    .Full( ), 
    .AlmostEmpty( ), 
    .AlmostFull( )
    );
FIFO_IN U4(						//write fifo 2
	.Data(D_Sensor_2_In[11:0]), 
	.WrClock(clk), 
	.RdClock(clk), 
	.WrEn(LV), 
	.RdEn(~RD_FIFO_n), 
    .Reset(~rst_n || ~frame_v), 
    .RPReset(~rst_n || ~frame_v), 
    .Q(D_Sensor_2_Out), 
    .Empty( ), 
    .Full( ), 
    .AlmostEmpty( ), 
    .AlmostFull( )
    );*/

FIFO_OUT U5(					//read fifo
	.Data({pixel_data_in[27:16], pixel_data_in[11:0]}), 
	.WrClock(clk), 
	.RdClock(clk), 
	.WrEn(fifo_out_wr_en[5]), 
	.RdEn(fifo_sel/*LV_Dlyd[47]*/), 
    .Reset(~rst_n || ~frame_v), 
    .RPReset(~rst_n || ~frame_v), 
    .Q({pixel_data_1, pixel_data_0}), 
    .Empty( ), 
    .Full( ), 
    .AlmostEmpty( ), 
    .AlmostFull( )
    );

	
IS42VM16400K_Cmd U0(
	.clk(clk),
	.rst_n(rst_n),
	.FV(FV),//q_fv_2),
	.LV(LV),//q_lv_2),
	.WR_EN(wr_en),
	.RD_EN(rd_en),
	.Prech_EN(prech_en),
	.Active_EN(active_en),
	.Row_Addr(w_row_addr),
	.init_done(init_done),
	.RD_FIFO_n(RD_FIFO_n),
	.Frame_V(frame_v)
);
	
	
IS42VM16400K_Cntlr U1(
  .clk			(clk)			,									//74.25Mhz
  .clkx2(clkx2),			//148.5
  .clkx2deg45(clkx2deg45),
  .rst_n		(rst_n)			,
  
  .D_Sensor_1({4'h0,q_D_Sensor_1_Out}),
  .D_Sensor_2({4'h0,q_D_Sensor_2_Out}),
  .D_Sensor_Out(pixel_data_in),
  .WR_EN				(wr_en),
  .RD_EN				(rd_en),
  .Prech_EN				(prech_en),
  .Active_EN			(active_en),
  .Row_Addr				(w_row_addr),
  .init_done		(init_done),
    
  .sdr_DQ   (sdr_DQ	 )	,     // sdr data
  .sdr_A    (sdr_A   )	,     // sdr address
  .sdr_BA   (sdr_BA  )	,     // sdr bank address
  .sdr_CKE  (sdr_CKE )	,     // sdr clock enable
  .sdr_CSn  (sdr_CSn )	,     // sdr chip select
  .sdr_RASn (sdr_RASn)	,     // sdr row address
  .sdr_CASn (sdr_CASn)	,     // sdr column select
  .sdr_WEn  (sdr_WEn )	,     // sdr write enable
  .sdr_DQM	(sdr_DQM)   ,			// sdr write data mask
  .sdr_CLK	(sdr_clk)				//148.5Mhz
);

endmodule