/* D5M Adjust

	- Exposure Adjust:
		after SW[0] is setup, press KEY1 to active exposure time.
			increase if SW[0] = DOWN
			descree  if SW[0] = UP

	- Zoom Mode Adjust:
		after SW[1] is setup, press KEY1 to active zoom seutp.
			normal   if SW[1] = DOWN
			zoom-in  if SW[1] = UP
		



*/


//=======================================================
//  This code is generated by Terasic System Builder
//=======================================================

module C5G_D5M(

	//////////// CLOCK //////////
	CLOCK_125_p,
	CLOCK_50_B3B,
	CLOCK_50_B5B,
	CLOCK_50_B6A,
	CLOCK_50_B7A,
	CLOCK_50_B8A,

	//////////// LED //////////
	LEDG,
	LEDR,

	//////////// KEY //////////
	CPU_RESET_n,
	KEY,

	//////////// SW //////////
	SW,

	//////////// SEG7 //////////
	HEX0,
	HEX1,

	//////////// HDMI-TX //////////
	HDMI_TX_CLK,
	HDMI_TX_D,
	HDMI_TX_DE,
	HDMI_TX_HS,
	HDMI_TX_INT,
	HDMI_TX_VS,

	//////////// ADC SPI //////////
	ADC_CONVST,
	ADC_SCK,
	ADC_SDI,
	ADC_SDO,

	//////////// Audio //////////
	AUD_ADCDAT,
	AUD_ADCLRCK,
	AUD_BCLK,
	AUD_DACDAT,
	AUD_DACLRCK,
	AUD_XCK,

	//////////// I2C for Audio/HDMI-TX/Si5338/HSMC //////////
	I2C_SCL,
	I2C_SDA,

	//////////// SDCARD //////////
	SD_CLK,
	SD_CMD,
	SD_DAT,

	//////////// Uart to USB //////////
	UART_RX,
	UART_TX,

	//////////// SRAM //////////
	SRAM_A,
	SRAM_CE_n,
	SRAM_D,
	SRAM_LB_n,
	SRAM_OE_n,
	SRAM_UB_n,
	SRAM_WE_n,

	//////////// LPDDR2 //////////
	DDR2LP_CA,
	DDR2LP_CK_n,
	DDR2LP_CK_p,
	DDR2LP_CKE,
	DDR2LP_CS_n,
	DDR2LP_DM,
	DDR2LP_DQ,
	DDR2LP_DQS_n,
	DDR2LP_DQS_p,
	DDR2LP_OCT_RZQ,

	//////////// GPIO, GPIO connect to D5M - 5M Pixel Camera //////////
	D5M_D,
	D5M_FVAL,
	D5M_LVAL,
	D5M_PIXCLK,
	D5M_RESET_N,
	D5M_SCLK,
	D5M_SDATA,
	D5M_STROBE,
	D5M_TRIGGER,
	D5M_XCLKIN 
);

//=======================================================
//  PARAMETER declarations
//=======================================================


//=======================================================
//  PORT declarations
//=======================================================

//////////// CLOCK //////////
input 		          		CLOCK_125_p;
input 		          		CLOCK_50_B3B;
input 		          		CLOCK_50_B5B;
input 		          		CLOCK_50_B6A;
input 		          		CLOCK_50_B7A;
input 		          		CLOCK_50_B8A;

//////////// LED //////////
output		     [7:0]		LEDG;
output		     [9:0]		LEDR;

//////////// KEY //////////
input 		          		CPU_RESET_n;
input 		     [3:0]		KEY;

//////////// SW //////////
input 		     [9:0]		SW;

//////////// SEG7 //////////
output		     [6:0]		HEX0;
output		     [6:0]		HEX1;

//////////// HDMI-TX //////////
output		          		HDMI_TX_CLK;
output		    [23:0]		HDMI_TX_D;
output		          		HDMI_TX_DE;
output		          		HDMI_TX_HS;
input 		          		HDMI_TX_INT;
output		          		HDMI_TX_VS;

//////////// ADC SPI //////////
output		          		ADC_CONVST;
output		          		ADC_SCK;
output		          		ADC_SDI;
input 		          		ADC_SDO;

//////////// Audio //////////
input 		          		AUD_ADCDAT;
inout 		          		AUD_ADCLRCK;
inout 		          		AUD_BCLK;
output		          		AUD_DACDAT;
inout 		          		AUD_DACLRCK;
output		          		AUD_XCK;

//////////// I2C for Audio/HDMI-TX/Si5338/HSMC //////////
output		          		I2C_SCL;
inout 		          		I2C_SDA;

//////////// SDCARD //////////
output		          		SD_CLK;
inout 		          		SD_CMD;
inout 		     [3:0]		SD_DAT;

//////////// Uart to USB //////////
input 		          		UART_RX;
output		          		UART_TX;

//////////// SRAM //////////
output		    [17:0]		SRAM_A;
output		          		SRAM_CE_n;
inout 		    [15:0]		SRAM_D;
output		          		SRAM_LB_n;
output		          		SRAM_OE_n;
output		          		SRAM_UB_n;
output		          		SRAM_WE_n;

//////////// LPDDR2 //////////
output		     [9:0]		DDR2LP_CA;
output		          		DDR2LP_CK_n;
output		          		DDR2LP_CK_p;
output		     [1:0]		DDR2LP_CKE;
output		     [1:0]		DDR2LP_CS_n;
output		     [3:0]		DDR2LP_DM;
inout 		    [31:0]		DDR2LP_DQ;
inout 		     [3:0]		DDR2LP_DQS_n;
inout 		     [3:0]		DDR2LP_DQS_p;
input 		          		DDR2LP_OCT_RZQ;

//////////// GPIO, GPIO connect to D5M - 5M Pixel Camera //////////
input 		    [11:0]		D5M_D;
input 		          		D5M_FVAL;
input 		          		D5M_LVAL;
input 		          		D5M_PIXCLK;
output		          		D5M_RESET_N;
output		          		D5M_SCLK;
inout 		          		D5M_SDATA;
input 		          		D5M_STROBE;
output		          		D5M_TRIGGER;
output		          		D5M_XCLKIN;


//=======================================================
//  REG/WIRE declarations
//=======================================================

wire reset_n;


wire DLY_RST_1;
wire DLY_RST_3;


wire [23:0]	disp_data;
wire			disp_clk;
wire			disp_hs;
wire			disp_vs;
wire			disp_de;

wire lpddr2_local_init_done;
wire lpddr2_local_cal_success;
wire lpddr2_local_cal_fail;

//=======================================================
//  Structural coding
//=======================================================


assign reset_n = 1'b1;

//reset signals
Reset_Delay			Reset_Delay_inst(
							.iCLK(CLOCK_50_B7A),
							.iRST(KEY[0]),
							.oRST_0(),
							.oRST_1(DLY_RST_1),
							.oRST_2(),
							.oRST_3(DLY_RST_3), //auto-start start point
							.oRST_4()  //auto-start end point
						);




    D5M_QSYS u0 (
        .external_clk50_clk                        (CLOCK_50_B7A),                        //                 external_clk50.clk
        .external_reset_reset_n                    (reset_n),                    //                 external_reset.reset_n
        .terasic_camera_0_conduit_end_D            (D5M_D),            //   terasic_camera_0_conduit_end.D
        .terasic_camera_0_conduit_end_FVAL         (D5M_FVAL),         //                               .FVAL
        .terasic_camera_0_conduit_end_LVAL         (D5M_LVAL),         //                               .LVAL
        .terasic_camera_0_conduit_end_PIXCLK       (D5M_PIXCLK),       //                               .PIXCLK
		  
		  // display output
        .alt_vip_itc_0_clocked_video_vid_clk       (disp_clk),       //    alt_vip_itc_0_clocked_video.vid_clk
        .alt_vip_itc_0_clocked_video_vid_data      (disp_data),      //                               .vid_data
        .alt_vip_itc_0_clocked_video_underflow     (),     //                               .underflow
        .alt_vip_itc_0_clocked_video_vid_datavalid (disp_de), //                               .vid_datavalid
        .alt_vip_itc_0_clocked_video_vid_v_sync    (disp_vs),    //                               .vid_v_sync
        .alt_vip_itc_0_clocked_video_vid_h_sync    (disp_hs),    //                               .vid_h_sync
        .alt_vip_itc_0_clocked_video_vid_f         (),         //                               .vid_f
        .alt_vip_itc_0_clocked_video_vid_h         (),         //                               .vid_h
        .alt_vip_itc_0_clocked_video_vid_v         (),         //                               .vid_v
		  
			// lpddr2
        .memory_mem_ca                             (DDR2LP_CA),                             //                         memory.mem_ca
        .memory_mem_ck                             (DDR2LP_CK_p),                             //                               .mem_ck
        .memory_mem_ck_n                           (DDR2LP_CK_n),                           //                               .mem_ck_n
        .memory_mem_cke                            (DDR2LP_CKE),                            //                               .mem_cke
        .memory_mem_cs_n                           (DDR2LP_CS_n),                           //                               .mem_cs_n
        .memory_mem_dm                             (DDR2LP_DM),                             //                               .mem_dm
        .memory_mem_dq                             (DDR2LP_DQ),                             //                               .mem_dq
        .memory_mem_dqs                            (DDR2LP_DQS_p),                            //                               .mem_dqs
        .memory_mem_dqs_n                          (DDR2LP_DQS_n),                          //                               .mem_dqs_n
        .oct_rzqin                                 (DDR2LP_OCT_RZQ),                                 //                            oct.rzqin
        .mem_if_lpddr2_emif_pll_ref_clk_clk        (CLOCK_125_p),        // mem_if_lpddr2_emif_pll_ref_clk.clk
		  
  
        .mem_if_lpddr2_emif_status_local_init_done   (lpddr2_local_init_done),   //      mem_if_lpddr2_emif_status.local_init_done
        .mem_if_lpddr2_emif_status_local_cal_success (lpddr2_local_cal_success), //                               .local_cal_success
        .mem_if_lpddr2_emif_status_local_cal_fail    (lpddr2_local_cal_fail),     //                               .local_cal_fail
  
		  
		  // hdmi i2c
        .i2c_scl_external_connection_export        (I2C_SCL),        //    i2c_scl_external_connection.export
        .i2c_sda_external_connection_export        (I2C_SDA),         //    i2c_sda_external_connection.export

		  // hdmi interrupt
        .hdmi_tx_int_n_external_connection_export  (~HDMI_TX_INT)   // hdmi_tx_int_n_external_connection.export
    );

/////////////////////////////
// LPDDR2 status
assign LEDG[0] = lpddr2_local_init_done;  // led is high active
assign LEDG[1] = lpddr2_local_cal_fail;
assign LEDG[2] = lpddr2_local_cal_success;
	 
/////////////////////////////
// HDMI TX
assign HDMI_TX_CLK	= disp_clk;
assign HDMI_TX_D		= disp_data;
assign HDMI_TX_DE		= disp_de;
assign HDMI_TX_HS		= disp_hs;
assign HDMI_TX_VS		= disp_vs;


pll0 pll0_sys(
		.refclk(CLOCK_50_B7A),   
		.rst(~reset_n),      
		.outclk_0(D5M_XCLKIN), 
		.outclk_1(disp_clk),
		.locked()    
	);

///////////////////////////////////////////////
//D5M I2C control
I2C_CCD_Config 		i2c_config_inst	(	//	Host Side
							.iCLK(CLOCK_50_B5B),
							.iRST_N(DLY_RST_3),
							.iZOOM_MODE_SW(SW[1]),
							.iEXPOSURE_ADJ(KEY[1]),
							.iEXPOSURE_DEC_p(SW[0]),							
							//	I2C Side
							.I2C_SCLK(D5M_SCLK),
							.I2C_SDAT(D5M_SDATA)
						);

						
//D5M
assign	D5M_TRIGGER	=	1'b1;  // RIGGER
assign	D5M_RESET_N	=	DLY_RST_1;						

endmodule
