//   ==================================================================
//   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
//   ------------------------------------------------------------------
//   Copyright (c) 2012 by Lattice Semiconductor Corporation
//   ------------------------------------------------------------------
//
//   Permission:
//
//      Lattice Semiconductor grants permission to use this code
//      with Lattice Semiconductor Products and Devices only.   
//      Other use of this code, including the sell or duplication 
//      of any portion, or the use with any other products or  
//      services is strictly prohibited.
//
//   Disclaimer:
//
//      Lattice Semiconductor provides no warranty regarding the use or
//      functionality of this code. It is the user's responsibility to
//      verify their design for consistency and functionality through
//      the use of formal verification methods.
//
//   --------------------------------------------------------------------
//
//                  Lattice Semiconductor Corporation
//                  5555 NE Moore Court
//                  Hillsboro, OR 97214
//                  U.S.A
//
//                  TEL: 1-800-Lattice (USA and Canada)
//                         503-286-8001 (other locations)
//
//                  web: http://www.latticesemi.com/
//                  email: techsupport@latticesemi.com
//
//   --------------------------------------------------------------------
//
//      Project:           XO2 HiSPi to Parallel Bridge Design
//      File:              DSIB_ref_top.v
//      Date:              Mon, 3 Dec 2012 14:02 PDT
//      Version:           1
//      Targeted Family:   XO2
//
//   =======================================================================

module DSIB_ref_top #(
parameter pmi_family    = "XO2"           , //"ECP3" or "XP2 or XO2"
parameter gearing       = "x4"            , //"x2" or "x4"
parameter c_HDR_MODE    = "false"	      , //"true" or "false"; For AR0331 choose "false" for both linear and HDR modes
parameter c_HISPI_MODE  = "Packetized-SP" , //"Packetized-SP" or "Streaming-SP" or "Streaming-S" or "ActiveStart-SP8"
parameter c_WORD_WIDTH  = 12              , //8/10/12/14/16
parameter c_LANE_WIDTH  = 2               , //LANE NUMBER 1/2/3/4	
parameter c_BRIDGES		= 1				  ,	//Number of HISPi to parallel bridges 1/2/ 3= two bridges plus top/bottom (half) 3D support
parameter c_3D			= "none"			//"none" or "topbottom"
)(
   input clk_i,
   input reset_n,
   input       hispi_clk,
   input [3:0] hispi_data,
   input       hispi_clk_s2,
   input [3:0] hispi_data_s2,
   output      hispi_resetn,
   
   output         	 hispi_sens_clk  ,
   output reg        hispi_sens_fv   ,
   output reg        hispi_sens_lv   ,   
   output reg [15:0] hispi_sens_data ,

   input         sda_sensor_s1,
   input         scl_sensor_s1,
   output         sda_sensor_s2,
   output         scl_sensor_s2,

   // Sensor Inputs
	//output [1:0]	saddr,
	output				trigger,
	//output				output_en_n,
	//output				standby,
	output      	XO2_clk,
	output			LED_S1,
	output			LED_S2,
	
	input sensor_switch,
	
	// SDR
	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
);

//Sensor Inputs
//assign saddr				= 2'b00;//0
assign trigger			= pin_rstn;//sensor_switch;//1
//assign output_en_n	= 1'b0;//0
//assign standby			= 1'b0;//0 
assign hispi_resetn	= reset_n; //pin_rstn; 
assign XO2_clk	=	clk_i;
assign LED_S1	= fv;
assign LED_S2	= fv_2;
assign sda_sensor_s2 = sda_sensor_s1;
assign scl_sensor_s2 = scl_sensor_s1;

reg [27:0] rst_cnt;
reg       pin_rstn;
reg		  q_sensor_switch;
reg [1:0] switch_cnt;

wire [15:0] para_data, para_data_2, para_data_sdr;
wire fv, lv, fv_2, lv_2, w_fv_sdr, w_lv_sdr;
wire hispi_sens_clk_tmp;
wire [23:0] data_syncd;   
always @(posedge clk_i or negedge reset_n)
begin
	if (~reset_n) begin
		rst_cnt				<= 0;
		pin_rstn 			<= 0;
		q_sensor_switch		<= 0;
		switch_cnt			<= 0;
	end	
	else begin
		q_sensor_switch		<= sensor_switch;
		switch_cnt			<= (q_sensor_switch && !sensor_switch) ? ((switch_cnt<(c_BRIDGES-1) && c_3D=="none")||(switch_cnt<c_BRIDGES && c_3D=="topbottom")) ? switch_cnt+1 : 0 : switch_cnt;
   		if (!rst_cnt[27])
      		rst_cnt <= rst_cnt + 1;
      	else
      		rst_cnt	<= rst_cnt;
		if (rst_cnt[27])
			pin_rstn <= 1'b1;
		else
			pin_rstn <= pin_rstn;
    end     
end  

hispi_wrap	#(
.pmi_family     (pmi_family         ), //"ECP3" or "XP2 or XO2"
.gearing        (gearing            ), //"x2" or "x4"
.c_HDR_MODE     (c_HDR_MODE        	), //"true" or "false"
.c_HISPI_MODE   (c_HISPI_MODE   	), //"Packetized-SP" or "Streaming-SP" or "Streaming-S" or "ActiveStart-SP8"
.c_WORD_WIDTH   (c_WORD_WIDTH       ), //8/10/12/14/16
.c_LANE_WIDTH   (c_LANE_WIDTH       ),  //LANE NUMBER 1/2/3/4
.c_BRIDGES		(c_BRIDGES			)
)
I_hispi_wrap(
	.rstn             (/*sensor_switch*/pin_rstn         ),  //   
//hispi input port   
	.sclk_1	          (hispi_clk     ),
	.sdata_1          (hispi_data    ),
	.sclk_2	          (hispi_clk_s2  ),
	.sdata_2          (hispi_data_s2 ),

//output ports
	.pclk           (para_clk       ),
	.pixel_clk_x2	(clk_x2),
	.pixel_clk_x2_45deg(clkx2deg45),
	.f_valid        (fv		    	),
	.f_valid_2      (fv_2	    	),	
	.l_valid        (lv				),	
	.l_valid_2      (lv_2			),	
	.dout           (para_data[15:0]),
	.dout_2         (para_data_2[15:0])
	);
	
//add output registers to improving timing
//add by xuan, 2011_1_30
ODDRXE I_clk_out (
   .D0    (1'b1       ), 
   .D1    (1'b0       ), 
   .SCLK  (hispi_sens_clk_tmp),
   .RST   (1'b0       ),
   .Q     (hispi_sens_clk)
   );   
   
assign hispi_sens_clk_tmp = para_clk;    

always @(posedge hispi_sens_clk_tmp or negedge pin_rstn)  //      
   if (!pin_rstn) begin                                
      hispi_sens_fv <= 0;
      hispi_sens_lv <= 0;
      hispi_sens_data <= 0;
   end
   else if (switch_cnt==0) begin
      hispi_sens_fv <= fv;  
      hispi_sens_lv <= lv;  
      hispi_sens_data <= para_data;
   end
   else if (switch_cnt==1) begin
      hispi_sens_fv <= fv_2;        
      hispi_sens_lv <= lv_2;        
      hispi_sens_data <= para_data_2;   
   end   
   else if (switch_cnt==2) begin      
      hispi_sens_fv <= w_fv_sdr;  
      hispi_sens_lv <= w_lv_sdr;  
      hispi_sens_data <= para_data_sdr;
   end 

generate
	if(c_3D=="topbottom") begin
		frame_sync U1(
			.clk(para_clk),
			.rst_n(pin_rstn),
			.FV1(fv_2),
			.LV1(lv_2),
			.DIN1(para_data_2),
			.DIN2(para_data),
			.FV2(fv),
			.LV2(lv),
			.FV(fv_out),
			.LV(lv_out),
			.DOUT(data_syncd)
  		);    
		sdr_wrap U2(
 			.clk(para_clk),			//74.25Mhz
  			.clkx2(clk_x2),			//148.5
  			.clkx2deg45(clkx2deg45),	//148.5+45degree phase shift
  			.rst_n(pin_rstn),
  			.D_Sensor_1_In({4'b0000, data_syncd[11:0]}),//test_cnt),//para_data),
  			.D_Sensor_2_In({4'b0000, data_syncd[23:12]}),//test_cnt),//para_data),//
  			.FV(fv_out),
  			.LV(lv_out),
  			.Data_Out(para_data_sdr),
  			.LV_Out(w_lv_sdr),
  			.FV_Out(w_fv_sdr),
  
  			.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)
		);
	end
endgenerate


endmodule