// --------------------------------------------------------------------
// Copyright (c) 2010 by Terasic Technologies Inc. 
// --------------------------------------------------------------------
//
// Permission:
//
//   Terasic grants permission to use and modify this code for use
//   in synthesis for all Terasic Development Boards and Altera Development 
//   Kits made by Terasic.  Other use of this code, including the selling 
//   ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL/Verilog or C/C++ source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Terasic provides no warranty regarding the use 
//   or functionality of this code.
//
// --------------------------------------------------------------------
//           
//                     Terasic Technologies Inc
//                     E. Rd Sec. 1. JhuBei City,
//                     HsinChu County, Taiwan
//                     302
//
//                     web: http://www.terasic.com/   
//                     email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions:	D5M_VIP
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
//   Ver  :| Author            :| Mod. Date  :| Changes Made:
//   V1.0 :| Dee Zeng          :| 2011/10/24 :| Initial Revision
// --------------------------------------------------------------------

module TR4_D5M_VIP(

							///////////BUTTON/////////////
							BUTTON,

							/////////FAN/////////
							FAN_CTRL,
							FAN_SPEED,

							/////////FLASH/////////
							FLASH_ADV_n,
							FLASH_CE_n,
							FLASH_CLK,
							FLASH_RDY_BSY_n,
							FLASH_RESET_n,
							FLASH_WP_n,

							/////////FSM/////////
							FSM_A,
							FSM_D,
							FSM_OE_n,
							FSM_WE_n,

							/////////HSMA/////////
							HSMA_CLKIN0,
							HSMA_CLKIN_n1,
							HSMA_CLKIN_n2,
							HSMA_CLKIN_p1,
							HSMA_CLKIN_p2,
							HSMA_D,
//							HSMA_GXB_RX_p,
//							HSMA_GXB_TX_p,
							HSMA_OUT0,
							HSMA_OUT_n1,
							HSMA_OUT_n2,
							HSMA_OUT_p1,
							HSMA_OUT_p2,
//							HSMA_REFCLK_p,
							HSMA_RX_n,
							HSMA_RX_p,
							HSMA_TX_n,
							HSMA_TX_p,

//							/////////HSMB/////////
//							HSMB_CLKIN0,
//							HSMB_CLKIN_n1,
//							HSMB_CLKIN_n2,
//							HSMB_CLKIN_p1,
//							HSMB_CLKIN_p2,
//							HSMB_D,
//							HSMB_OUT0,
//							HSMB_OUT_n1,
//							HSMB_OUT_n2,
//							HSMB_OUT_p1,
//							HSMB_OUT_p2,
//							HSMB_RX_n,
//							HSMB_RX_p,
//							HSMB_SCL,
//							HSMB_SDA,
//							HSMB_TX_n,
//							HSMB_TX_p,

							/////////HSMC/////////
//							HSMC_CLKIN0,
//							HSMC_CLKIN_n1,
//							HSMC_CLKIN_n2,
//							HSMC_CLKIN_p1,
//							HSMC_CLKIN_p2,
//							HSMC_CLKOUT_n1,
//							HSMC_CLKOUT_p1,
//							HSMC_D,
//							HSMC_OUT0,
//							HSMC_OUT_n2,
//							HSMC_OUT_p2,
//							HSMC_RX_n,
//							HSMC_RX_p,
//							HSMC_TX_n,
//							HSMC_TX_p,

	//////////// GPIO_1, GPIO_1 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 ,
	
	
	//////////// HSMC-B, HSMC-B connect to DVI - FullHD TX/RX //////////
	DVI_EDID_WP,
	DVI_RX_CLK,
	DVI_RX_CTL,
	DVI_RX_D,
	DVI_RX_DDCSCL,
	DVI_RX_DDCSDA,
	DVI_RX_DE,
	DVI_RX_HS,
	DVI_RX_SCDT,
	DVI_RX_VS,
	DVI_TX_CLK,
	DVI_TX_CTL,
	DVI_TX_D,
	DVI_TX_DDCSCL,
	DVI_TX_DDCSDA,
	DVI_TX_DE,
	DVI_TX_DKEN,
	DVI_TX_HS,
	DVI_TX_HTPLG,
	DVI_TX_ISEL,
	DVI_TX_MSEN,
	DVI_TX_PD_N,
	DVI_TX_SCL,
	DVI_TX_SDA,
	DVI_TX_VS,
	
							/////////HSMD/////////
							HSMD_CLKIN0,
							HSMD_CLKIN_n1,
							HSMD_CLKIN_n2,
							HSMD_CLKIN_p1,
							HSMD_CLKIN_p2,
							HSMD_CLKOUT_n1,
							HSMD_CLKOUT_p1,
							HSMD_D,
							HSMD_OUT0,
							HSMD_OUT_n2,
							HSMD_OUT_p2,
							HSMD_RX_n,
							HSMD_RX_p,
							HSMD_SCL,
							HSMD_SDA,
							HSMD_TX_n,
							HSMD_TX_p,

							/////////HSME/////////
							HSME_CLKIN0,
							HSME_CLKIN_n1,
							HSME_CLKIN_n2,
							HSME_CLKIN_p1,
							HSME_CLKIN_p2,
							HSME_CLKOUT_n1,
							HSME_CLKOUT_p1,
							HSME_D,
//							HSME_GXB_RX_p,
//							HSME_GXB_TX_p,
							HSME_OUT0,
							HSME_OUT_n2,
							HSME_OUT_p2,
//							HSME_REFCLK_p,
							HSME_RX_n,
							HSME_RX_p,
							HSME_TX_n,
							HSME_TX_p,

							/////////HSMF/////////
							HSMF_CLKIN0,
							HSMF_CLKIN_n1,
							HSMF_CLKIN_n2,
							HSMF_CLKIN_p1,
							HSMF_CLKIN_p2,
							HSMF_CLKOUT_n1,
							HSMF_CLKOUT_n2,
							HSMF_CLKOUT_p1,
							HSMF_CLKOUT_p2,
							HSMF_D,
							HSMF_OUT0,
							HSMF_RX_n,
							HSMF_RX_p,
							HSMF_TX_n,
							HSMF_TX_p,

							/////////LED/////////
							LED,

							/////////LOOP/////////
							LOOP_CLKIN0,
							LOOP_CLKOUT0,
							LOOP_CLKIN1,
							LOOP_CLKOUT1,

							/////////MAX2/////////
							MAX2_CS_n,
							MAX2_I2C_SCL,
							MAX2_I2C_SDA,

							/////////mem/////////
							mem_a,
							mem_ba,
							mem_cas_n,
							mem_cke,
							mem_ck,
							mem_ck_n,
							mem_cs_n,
							mem_dm,
							mem_dq,
							mem_dqs,
							mem_dqs_n,
							mem_event_n,
							mem_odt,
							mem_ras_n,
							mem_reset_n,
							mem_scl,
							mem_sda,
							mem_we_n,

							/////////OSC/////////
							OSC_50_BANK1,
							OSC_50_BANK3,
							OSC_50_BANK4,
							OSC_50_BANK7,
							OSC_50_BANK8,

							/////////PCIE0/////////
//							PCIE0_pREST_n,
//							PCIE0_REFCLK_p,
//							PCIE0_RX_p,
//							PCIE0_TX_p,
//							PCIE0_WAKE_n,

							/////////PCIE1/////////
//							PCIE1_pREST_n,
//							PCIE1_REFCLK_p,
//							PCIE1_RX_p,
//							PCIE1_TX_p,
//							PCIE1_WAKE_n,

							/////////PGM/////////
//							PGM_GXBCLK_p1,

							/////////mem_oct_rdn/////////
							mem_oct_rdn,

							/////////mem_oct_rup/////////
							mem_oct_rup,

							/////////SMA/////////
							SMA_CLKIN,
							SMA_CLKOUT,
							SMA_CLKOUT_n,
							SMA_CLKOUT_p,
//							SMA_GXBCLK_p,

							/////////SSRAM/////////
							SSRAM_ADSC_n,
							SSRAM_ADSP_n,
							SSRAM_ADV_n,
							SSRAM_BE_n,
							SSRAM_CE1_n,
							SSRAM_CLK,

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

							/////////TEMP/////////
							TEMP_CLK,
							TEMP_DATA,
							TEMP_INT_n,
							TEMP_OVERT_n
);

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

							///////////BUTTON/////////////

input							[3:0]							BUTTON;

///////// FAN /////////
output																FAN_CTRL;
input															FAN_SPEED;

///////// FLASH /////////
output																FLASH_ADV_n;
output															FLASH_CE_n;
output															FLASH_CLK;
input															FLASH_RDY_BSY_n;
output															FLASH_RESET_n;
output															FLASH_WP_n;

///////// FSM /////////
output							[25:1]							FSM_A;
inout							[31:0]							FSM_D;
output															FSM_OE_n;
output															FSM_WE_n;

///////// HSMA /////////
input																HSMA_CLKIN0;
input															HSMA_CLKIN_n1;
input															HSMA_CLKIN_n2;
input															HSMA_CLKIN_p1;
input															HSMA_CLKIN_p2;
inout							[3:0]							HSMA_D;
//input							[7:0]							HSMA_GXB_RX_p;
//output							[7:0]							HSMA_GXB_TX_p;
inout															HSMA_OUT0;
inout															HSMA_OUT_n1;
inout															HSMA_OUT_n2;
inout															HSMA_OUT_p1;
inout															HSMA_OUT_p2;
//input															HSMA_REFCLK_p;
inout							[16:0]							HSMA_RX_n;
inout							[16:0]							HSMA_RX_p;
inout							[16:0]							HSMA_TX_n;
inout							[16:0]							HSMA_TX_p;

/////////// HSMB /////////
//input																HSMB_CLKIN0;
//input															HSMB_CLKIN_n1;
//input															HSMB_CLKIN_n2;
//input															HSMB_CLKIN_p1;
//input															HSMB_CLKIN_p2;
//inout							[3:0]							HSMB_D;
//inout															HSMB_OUT0;
//inout															HSMB_OUT_n1;
//inout															HSMB_OUT_n2;
//inout															HSMB_OUT_p1;
//inout															HSMB_OUT_p2;
//inout							[16:0]							HSMB_RX_n;
//inout							[16:0]							HSMB_RX_p;
//output															HSMB_SCL;
//inout															HSMB_SDA;
//inout							[16:0]							HSMB_TX_n;
//inout							[16:0]							HSMB_TX_p;

/////////// HSMC /////////
//input																HSMC_CLKIN0;
//input															HSMC_CLKIN_n1;
//input															HSMC_CLKIN_n2;
//input															HSMC_CLKIN_p1;
//input															HSMC_CLKIN_p2;
//inout															HSMC_CLKOUT_n1;
//inout															HSMC_CLKOUT_p1;
//inout							[3:0]							HSMC_D;
//inout															HSMC_OUT0;
//inout															HSMC_OUT_n2;
//inout															HSMC_OUT_p2;
//inout							[16:0]							HSMC_RX_n;
//inout							[16:0]							HSMC_RX_p;
//inout							[16:0]							HSMC_TX_n;
//inout							[16:0]							HSMC_TX_p;
//////////// GPIO_1, GPIO_1 connect to D5M - 5M Pixel Camera //////////   //JP9
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;

//////////// HSMC-B, HSMC-B connect to DVI - FullHD TX/RX //////////
output		          	DVI_EDID_WP;
input		          		DVI_RX_CLK;
input		     [3:1]		DVI_RX_CTL;
input		    [23:0]		DVI_RX_D;
inout		          		DVI_RX_DDCSCL;
inout		          		DVI_RX_DDCSDA;
input		          		DVI_RX_DE;
input		          		DVI_RX_HS;
input		          		DVI_RX_SCDT;
input		         	 	DVI_RX_VS;
output		          	DVI_TX_CLK;
output		  [3:1]		DVI_TX_CTL;
output		 [23:0]		DVI_TX_D;
inout		          		DVI_TX_DDCSCL;
inout		         	 	DVI_TX_DDCSDA;
output		          	DVI_TX_DE;
output		          	DVI_TX_DKEN;
output		          	DVI_TX_HS;
output		          	DVI_TX_HTPLG;
output		          	DVI_TX_ISEL;
output		          	DVI_TX_MSEN;
output		          	DVI_TX_PD_N;
output		          	DVI_TX_SCL;
inout		          		DVI_TX_SDA;
output		          	DVI_TX_VS;



///////// HSMD /////////
input																HSMD_CLKIN0;
input															HSMD_CLKIN_n1;
input															HSMD_CLKIN_n2;
input															HSMD_CLKIN_p1;
input															HSMD_CLKIN_p2;
inout															HSMD_CLKOUT_n1;
inout															HSMD_CLKOUT_p1;
inout							[3:0]							HSMD_D;
inout															HSMD_OUT0;
inout															HSMD_OUT_n2;
inout															HSMD_OUT_p2;
inout							[16:0]							HSMD_RX_n;
inout							[16:0]							HSMD_RX_p;
output															HSMD_SCL;
inout															HSMD_SDA;
inout							[16:0]							HSMD_TX_n;
inout							[16:0]							HSMD_TX_p;

///////// HSME /////////
input																HSME_CLKIN0;
input															HSME_CLKIN_n1;
input															HSME_CLKIN_n2;
input															HSME_CLKIN_p1;
input															HSME_CLKIN_p2;
inout															HSME_CLKOUT_n1;
inout															HSME_CLKOUT_p1;
inout							[3:0]							HSME_D;
//input							[7:0]							HSME_GXB_RX_p;
//output							[7:0]							HSME_GXB_TX_p;
inout															HSME_OUT0;
inout															HSME_OUT_n2;
inout															HSME_OUT_p2;
//input															HSME_REFCLK_p;
inout							[16:0]							HSME_RX_n;
inout							[16:0]							HSME_RX_p;
inout							[16:0]							HSME_TX_n;
inout							[16:0]							HSME_TX_p;

///////// HSMF /////////
input																HSMF_CLKIN0;
input															HSMF_CLKIN_n1;
input															HSMF_CLKIN_n2;
input															HSMF_CLKIN_p1;
input															HSMF_CLKIN_p2;
inout															HSMF_CLKOUT_n1;
inout															HSMF_CLKOUT_n2;
inout															HSMF_CLKOUT_p1;
inout															HSMF_CLKOUT_p2;
inout							[3:0]							HSMF_D;
inout															HSMF_OUT0;
inout							[16:0]							HSMF_RX_n;
inout							[16:0]							HSMF_RX_p;
inout							[16:0]							HSMF_TX_n;
inout							[16:0]							HSMF_TX_p;

///////// LED /////////
output							[3:0]							LED;

///////// LOOP /////////
input																LOOP_CLKIN0;
output															LOOP_CLKOUT0;
input															LOOP_CLKIN1;
output															LOOP_CLKOUT1;

///////// MAX2 /////////
output																MAX2_CS_n;
output															MAX2_I2C_SCL;
inout															MAX2_I2C_SDA;

///////// mem /////////
output							[15:0]							mem_a;
output							[2:0]							mem_ba;
output															mem_cas_n;
output							[1:0]							mem_cke;
output							[0:0]							mem_ck; //[1:0] for 2 rank
output							[0:0]							mem_ck_n;//[1:0] for 2 rank
output							[1:0]							mem_cs_n;
output							[7:0]							mem_dm;
inout							[63:0]							mem_dq;
inout							[7:0]							mem_dqs;
inout							[7:0]							mem_dqs_n;
input															mem_event_n;
output							[1:0]							mem_odt;
output															mem_ras_n;
output															mem_reset_n;
output															mem_scl;
inout															mem_sda;
output															mem_we_n;

///////// OSC /////////
input																OSC_50_BANK1;
input															OSC_50_BANK3;
input															OSC_50_BANK4;
input															OSC_50_BANK7;
input															OSC_50_BANK8;

///////// PCIE0 /////////
//input																PCIE0_pREST_n;
//input															PCIE0_REFCLK_p;
//input							[3:0]							PCIE0_RX_p;
//output							[3:0]							PCIE0_TX_p;
//output															PCIE0_WAKE_n;

///////// PCIE1 /////////
//input																PCIE1_pREST_n;
//input															PCIE1_REFCLK_p;
//input							[3:0]							PCIE1_RX_p;
//output							[3:0]							PCIE1_TX_p;
//output															PCIE1_WAKE_n;

///////// PGM /////////
//input																PGM_GXBCLK_p1;

///////// mem_oct_rdn /////////
input																mem_oct_rdn;

///////// mem_oct_rup /////////
input																mem_oct_rup;

///////// SMA /////////
input																SMA_CLKIN;
output															SMA_CLKOUT;
output															SMA_CLKOUT_n;
output															SMA_CLKOUT_p;
//input															SMA_GXBCLK_p;

///////// SSRAM /////////
output																SSRAM_ADSC_n;
output															SSRAM_ADSP_n;
output															SSRAM_ADV_n;
output							[3:0]							SSRAM_BE_n;
output															SSRAM_CE1_n;
output															SSRAM_CLK;

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

///////// TEMP /////////
output																TEMP_CLK;
inout															TEMP_DATA;
input															TEMP_INT_n;
input															TEMP_OVERT_n;



//=======================================================
//  REG/WIRE declarations
//=======================================================
//	D5M
wire	[15:0]	Read_DATA1;
wire	[15:0]	Read_DATA2;
wire			VGA_CTRL_CLK;
wire	[11:0]	mCCD_DATA;
wire			mCCD_DVAL;
wire			mCCD_DVAL_d;
wire	[15:0]	X_Cont;
wire	[15:0]	Y_Cont;
wire	[9:0]	X_ADDR;
wire	[31:0]	Frame_Cont;
wire			DLY_RST_0;
wire			DLY_RST_1;
wire			DLY_RST_2;
wire			DLY_RST_3;
wire			DLY_RST_4;
wire			Read;
reg		[11:0]	rCCD_DATA;
reg				rCCD_LVAL;
reg				rCCD_FVAL;
wire	[11:0]	sCCD_R;
wire	[11:0]	sCCD_G;
wire	[11:0]	sCCD_B;
wire			sCCD_DVAL;
wire	[9:0]	oVGA_R;   				//	VGA Red[9:0]
wire	[9:0]	oVGA_G;	 				//	VGA Green[9:0]
wire	[9:0]	oVGA_B;   				//	VGA Blue[9:0]
reg		[1:0]	rClk;


//ddr2
wire	ip_init_done;
wire reset_n;
assign reset_n = BUTTON[0];

//=======================================================
//  Structural coding
//=======================================================
//D5M
assign	D5M_TRIGGER	=	1'b1;  // tRIGGER
assign	D5M_RESET_N	=	DLY_RST_1;
//Fan
assign  FAN_CTRL    =   1'b1;
//DVI
assign DVI_TX_ISEL 	=   1'b0; 	// disable i2c
assign DVI_TX_SCL 	=   1'b1; 	// BSEL=0, 12-bit, dual-edge input
assign DVI_TX_HTPLG =   1'b1; 	// Note. *** EDGE=1, primary latch to occur on the rising edge of the input clock IDCK+
assign DVI_TX_SDA 	=   1'b1;  	// DSEL=X (VREF=3.3V)
assign DVI_TX_PD_N  =   1'b1;

//D5M DVI clocks generate
PLL0 sys_pll_inst(
	.inclk0(OSC_50_BANK3),
	.c0 ( D5M_XCLKIN ),
	.c1 ( DVI_TX_CLK )
	);
//reset signals
Reset_Delay			u2	(	.iCLK(OSC_50_BANK3),
							.iRST(BUTTON[0]),
							.oRST_0(DLY_RST_0),
							.oRST_1(DLY_RST_1),
							.oRST_2(DLY_RST_2),
							.oRST_3(DLY_RST_3), //auto-start start point
							.oRST_4(DLY_RST_4)  //auto-start end point
						);

//DDR3 Read and Write as Frame Buffer

    TR4_QSYS u0 (
            .external_clk50_clk                                 (OSC_50_BANK8),                               
            .external_reset_reset_n                             (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
			  
		  .alt_vip_itc_0_clocked_video_vid_clk           (~DVI_TX_CLK),           //  alt_vip_itc_0_clocked_video.vid_clk
        .alt_vip_itc_0_clocked_video_vid_data          (DVI_TX_D),          //                             .vid_data
        .alt_vip_itc_0_clocked_video_underflow         (),         //                             .underflow
        .alt_vip_itc_0_clocked_video_vid_datavalid     (DVI_TX_DE),     //                             .vid_datavalid
        .alt_vip_itc_0_clocked_video_vid_v_sync        (DVI_TX_VS),        //                             .vid_v_sync
        .alt_vip_itc_0_clocked_video_vid_h_sync        (DVI_TX_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
		  
        .memory_mem_cs_n                                    (mem_cs_n),      
        .memory_mem_odt                                     (mem_odt), 
        .memory_mem_cas_n                                   (mem_cas_n), 
        .memory_mem_dm                                      (mem_dm),  
        .memory_mem_dqs                                     (mem_dqs), 
        .memory_mem_we_n                                    (mem_we_n),
        .memory_mem_ck                                      (mem_ck),   
        .memory_mem_ras_n                                   (mem_ras_n), 
        .memory_mem_dq                                      (mem_dq), 
        .memory_mem_ck_n                                    (mem_ck_n), 
        .memory_mem_cke                                     (mem_cke), 
        .memory_mem_dqs_n                                   (mem_dqs_n),  
        .memory_mem_reset_n                                 (mem_reset_n), 
        .memory_mem_a                                       (mem_a),    
        .memory_mem_ba                                      (mem_ba),   
        .oct_rup                                            (mem_oct_rup),      
        .oct_rdn                                            (mem_oct_rdn),      

        .uniphy_ddr3_local_powerdown_local_powerdn_ack      (),    
        .uniphy_ddr3_local_powerdown_local_powerdn_req      (),    
        .uniphy_ddr3_status_local_cal_success               (),       
        .uniphy_ddr3_status_local_cal_fail                  (),     
        .uniphy_ddr3_status_local_init_done                 (ip_init_done)     
		  
    );
	 
	assign LED[3] = ~ip_init_done; 
   assign LED[2:0] = 3'd7;
	
//D5M I2C control
I2C_CCD_Config 		i2c_config_inst	(	//	Host Side
							.iCLK(OSC_50_BANK3),
							.iRST_N(DLY_RST_3),
							.iZOOM_MODE_SW(SW[1]),
							.iEXPOSURE_ADJ(BUTTON[1]),
							.iEXPOSURE_DEC_p(SW[0]),							
							//	I2C Side
							.I2C_SCLK(D5M_SCLK),
							.I2C_SDAT(D5M_SDATA)
						);




endmodule
