// --------------------------------------------------------------------
// 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
//                     356 Fu-Shin E. Rd Sec. 1. JhuBei City,
//                     HsinChu County, Taiwan
//                     302
//
//                     web: http://www.terasic.com/
//                     email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions:	Camera link on DE3 
//                  Camera link -> HSTC - C
//                  DVI         -> HSTC - D
//                  Camera link type -> STC - CLC1500 of sensor technolgies America, inc.
// --------------------------------------------------------------------
//
// Revision History : 
// --------------------------------------------------------------------
//   Ver  :| Author            :| Mod. Date :| Changes Made:
//   V1.0 :| Peli Li           :| 2010/10/14:| Initial Revision
// --------------------------------------------------------------------
//=======================================================
//  This code is generated by Terasic System Builder
//=======================================================
module DE3_CLR(

		////////// CLOCK //////////
		OSC_BA,
		OSC_BB,
		OSC_BC,
		OSC_BD,
		OSC1_50,
		OSC2_50,
		CLK_OUT,
		EXT_CLK,

		////////// LEDR //////////
		LEDR,
		LEDG,
		LEDB,

		////////// SEG7 //////////
		HEX0,
		HEX0_DP,
		HEX1,
		HEX1_DP,

		////////// Button //////////
		Button,

		////////// SW (SLIDE SWITCH) //////////
		SW,

		////////// DIP_SW (DIP SWITCH) //////////
		DIP_SW,

		////////// MAX1619 (TEMPERATURE SENSOR) //////////
		TEMP_CLK,
		TEMP_DATA,
		TEMP_INTn,

		////////// USB //////////
		OTG_D,
		OTG_A,
		OTG_CS_n,
		OTG_WE_n,
		OTG_OE_n,
		OTG_HC_IRQ,
		OTG_DC_IRQ,
		OTG_RESET_n,
		OTG_HC_DREQ,
		OTG_HC_DACK,
		OTG_DC_DREQ,
		OTG_DC_DACK,

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

		////////// GPIO0 (J13, GPIO 0) //////////
		GPIO0_CLKINn0,
		GPIO0_CLKINp0,
		GPIO0_CLKOUTn0,
		GPIO0_CLKOUTp0,
		GPIO0_D,

		////////// GPIO1 (J14, GPIO 1) //////////
		GPIO1_CLKINn1,
		GPIO1_CLKINp1,
		GPIO1_CLKOUTn1,
		GPIO1_CLKOUTp1,
		GPIO1_D,

		////////// DDR2 (J9, DDR2 SO-DIMM) //////////
		DDR2_CKE,
		DDR2_A,
		DDR2_BA,
		DDR2_RAS_n,
		DDR2_WE_n,
		DDR2_CAS_n,
		DDR2_CS_n,
		DDR2_ODT,
		DDR2_CLK_p,
		DDR2_CLK_n,
		DDR2_DM,
		DDR2_DQS_n,
		DDR2_DQS_p,
		DDR2_DQ,
		DDR2_SDA,
		DDR2_SCL,
		DDR2_SA,

		////////// HSTCC (J5 HSTC-C TOP/J6, HSTC-C BOTTOM), connect to CLR(Camera Link Receiver Board) //////////
		CLR_RXCC,
		CLR_RXCC_EN,
		CLR_RXSERTFG_EN,
		CLR_RXSERTFG,
		CLR_RXSERTC,
		CLR_RXSERTC_EN,
		CLR_RX_BASE,
		CLR_RXCLK_BASE,
		CLR_RXCLK_FULL,
		CLR_RX2CC,
		CLR_RX2CC_EN,
		CLR_RX2SERTFG_EN,
		CLR_RX2SERTFG,
		CLR_RX2SERTC,
		CLR_RX2SERTC_EN,
//		CLR_RX_FULL,
		CLR_RXCLK_MEDIUM,
//		CLR_HSTC_SDA,
//		CLR_HSTC_SCL,
		CLR_RX_MEDIUM,

		////////// HSTCD (J7, HSTC-D TOP/J8, HSTC-D BOTTOM) //////////
		HSTCD_CLKOUT_n,
		HSTCD_CLKIN_n,
		HSTCD_CLKOUT_p,
		HSTCD_CLKIN_p,
		HSTCD_CLKOUT_2,
		HSTCD_CLKIN_2,
		HSTCD_SDA,
		HSTCD_SCL,
		HSTCD_TX_n,
		HSTCD_RX_n,
		HSTCD_TX_p,
		HSTCD_RX_p,

		////////// REGULATOR //////////
		JVC_CLK,
		JVC_CS,
		JVC_DATAOUT,
		JVC_DATAIN,
	);

//=======================================================
//  PARAMETER declarations
//=======================================================
parameter  IMAGE_WITH   =  32'h00000400;
parameter IMAGE_HEIGHT  =  32'h00000300;
//note: if you want to change the image resolution,you should change the belows:
//1.the ccd_capture output image resolution
//2.RAW2RGB module (line buffer taps distance)
//3.DDR2 frame buffer size
//4.DVI output resolution
//=======================================================
//  PORT declarations
//=======================================================
////////// CLOCK //////////
input                     		OSC_BA;
input                     		OSC_BB;
input                     		OSC_BC;
input                     		OSC_BD;
input                     		OSC1_50;
input                     		OSC2_50;
output                    		CLK_OUT;
input                     		EXT_CLK;

////////// LEDR //////////
output    	[7:0]           	LEDR;
output    	[7:0]           	LEDG;
output    	[7:0]           	LEDB;

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

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

////////// SW (SLIDE SWITCH) //////////
input     	[3:0]           	SW;

////////// DIP_SW (DIP SWITCH) //////////
input     	[7:0]           	DIP_SW;

////////// MAX1619 (TEMPERATURE SENSOR) //////////
output                    		TEMP_CLK;
inout                     		TEMP_DATA;
input                     		TEMP_INTn;

////////// USB //////////
inout     	[31:0]          	OTG_D;
output    	[17:1]          	OTG_A;
output                    		OTG_CS_n;
output                    		OTG_WE_n;
output                    		OTG_OE_n;
input                     		OTG_HC_IRQ;
input                     		OTG_DC_IRQ;
output                    		OTG_RESET_n;
input                     		OTG_HC_DREQ;
output                    		OTG_HC_DACK;
input                     		OTG_DC_DREQ;
output                    		OTG_DC_DACK;

////////// SDCARD //////////
inout                     		SD_CMD;
output                    		SD_CLK;
inout                     		SD_DAT;
input                     		SD_WPn;

////////// GPIO0 (J13, GPIO 0) //////////
inout                     		GPIO0_CLKINn0;
inout     	[31:0]          	GPIO0_D;
inout                     		GPIO0_CLKINp0;
inout                     		GPIO0_CLKOUTn0;
inout                     		GPIO0_CLKOUTp0;

////////// GPIO1 (J14, GPIO 1) //////////
inout                     		GPIO1_CLKINn1;
inout     	[31:0]          	GPIO1_D;
inout                     		GPIO1_CLKINp1;
inout                     		GPIO1_CLKOUTn1;
inout                     		GPIO1_CLKOUTp1;

////////// DDR2 (J9, DDR2 SO-DIMM) //////////
inout     	[63:0]          	DDR2_DQ;
output    	[7:0]           	DDR2_DM;
inout     	[7:0]           	DDR2_DQS_n;
inout     	[7:0]           	DDR2_DQS_p;
inout     	[1:0]           	DDR2_CLK_p;
inout     	[1:0]           	DDR2_CLK_n;
output    	[1:0]           	DDR2_CKE;
output    	[15:0]          	DDR2_A;
output    	[2:0]           	DDR2_BA;
output                    		DDR2_RAS_n;
output                    		DDR2_WE_n;
output    	[1:0]           	DDR2_CS_n;
output                    		DDR2_CAS_n;
output    	[1:0]           	DDR2_ODT;
inout                     		DDR2_SDA;
output                    		DDR2_SCL;
output    	[1:0]           	DDR2_SA;

////////// HSTCC (J5 HSTC-C TOP/J6, HSTC-C BOTTOM), connect to CLR(Camera Link Receiver Board) //////////
input     	[27:0]          	CLR_RX_BASE;
output    	[4:1]           	CLR_RXCC;
output                    		CLR_RXCC_EN;
output                    		CLR_RXSERTFG_EN;
input                     		CLR_RXSERTFG;
output                    		CLR_RXSERTC;
output                    		CLR_RXSERTC_EN;
input                     		CLR_RXCLK_BASE;
input                     		CLR_RXCLK_FULL;
//input     	[27:0]          	CLR_RX_FULL;
output    	[4:1]           	CLR_RX2CC;
output                    		CLR_RX2CC_EN;
output                    		CLR_RX2SERTFG_EN;
input                     		CLR_RX2SERTFG;
output                    		CLR_RX2SERTC;
output                    		CLR_RX2SERTC_EN;
input                     		CLR_RXCLK_MEDIUM;
//inout                     		CLR_HSTC_SDA;
//output                    		CLR_HSTC_SCL;
input     	[27:0]          	CLR_RX_MEDIUM;

////////// HSTCD (J7, HSTC-D TOP/J8, HSTC-D BOTTOM) //////////
inout     	[1:0]           	HSTCD_CLKOUT_n;
inout     	[1:0]           	HSTCD_CLKIN_n;
inout     	[1:0]           	HSTCD_CLKOUT_p;
inout     	[1:0]           	HSTCD_CLKIN_p;
inout     	[29:0]          	HSTCD_TX_n;
inout     	[29:0]          	HSTCD_RX_n;
inout     	[29:0]          	HSTCD_TX_p;
inout     	[29:0]          	HSTCD_RX_p;
inout                     		HSTCD_CLKOUT_2;
inout                     		HSTCD_CLKIN_2;
inout                     		HSTCD_SDA;
output                    		HSTCD_SCL;

////////// REGULATOR //////////
output                    		JVC_CLK;
output                    		JVC_CS;
output                    		JVC_DATAOUT;
input                     		JVC_DATAIN;

//=======================================================
//  REG/WIRE declarations
//=======================================================
// CAMERA LINK
wire						      	CLR_CLK_120;
wire						       	CLR_RXCLK_BASE;
wire	      [9:0]				   CLR_BASE_D;
wire					      		CLR_BASE_FVAL;
wire			            		CLR_BASE_DVAL;
wire	      [15:0]	         Read_DATA1;
wire	      [15:0]	         Read_DATA2;

wire	      [15:0]	         X_Cont;
wire	      [15:0]	         Y_Cont;
wire		    [9:0]			 	cap_data;
wire						      	cap_dval;
wire                          oWRITE_w1;
wire		    [9:0]				red;
wire		    [9:0]				green;
wire	       [9:0]				blue;
wire                          dval;
wire					         	start;
wire					         	rst_n;

wire                          ip_init_done;

//dvi
wire        [23:0]            DVI_TX_D;  

//=======================================================
//  IO Group Voltage Configuration (Do not modify it)
//=======================================================
IOV_A3V3_B1V8_C3V3_D3V3 IOV_Instance(
	.iCLK(OSC2_50),
	.iRST_n(1'b1),
	.iENABLE(1'b0),
	.oREADY(),
	.oERR(),
	.oERRCODE(),
	.oJVC_CLK(JVC_CLK),
	.oJVC_CS(JVC_CS),
	.oJVC_DATAOUT(JVC_DATAOUT),
	.iJVC_DATAIN(JVC_DATAIN)
);

//=======================================================
//  Structural coding
//=======================================================
Reset_Delay	Reset_Delay_cmp
		(
			.iCLK(OSC2_50),
//			.iCLK(CLR_RXCLK_BASE),
			.iRST(Button[0]),
			.oRST_0(),
			.oRST_1(rst_n),
			.oRST_2(start)
		);
//Camera Link HSTC-C
//CLR_RXCLK_BASE --->pixclk
assign CLR_BASE_D[0]	= CLR_RX_BASE[0];
assign CLR_BASE_D[1]	= CLR_RX_BASE[1];
assign CLR_BASE_D[2]	= CLR_RX_BASE[2];
assign CLR_BASE_D[3]	= CLR_RX_BASE[3];
assign CLR_BASE_D[4]	= CLR_RX_BASE[4];
assign CLR_BASE_D[5]	= CLR_RX_BASE[6];
assign CLR_BASE_D[6]	= CLR_RX_BASE[27];
assign CLR_BASE_D[7]	= CLR_RX_BASE[5];
assign CLR_BASE_D[8]	= CLR_RX_BASE[7];
assign CLR_BASE_D[9]	= CLR_RX_BASE[8];
assign CLR_BASE_FVAL	= CLR_RX_BASE[25];
assign CLR_BASE_DVAL	= CLR_RX_BASE[24];

//DVI connection HSTC D 
assign HSTCD_RX_n[1] = DVI_TX_ISEL; 
assign HSTCD_RX_n[0] = DVI_TX_SCL; 
assign HSTCD_RX_p[2] = DVI_TX_HTPLG; 
assign HSTCD_RX_p[0] = DVI_TX_SDA;   
assign HSTCD_RX_n[2] = DVI_TX_PD_N;  

assign HSTCD_TX_p[0] = DVI_TX_DE ;   
assign HSTCD_RX_n[5] = DVI_TX_HS ;   
assign HSTCD_RX_p[4] = DVI_TX_VS ;   
assign HSTCD_CLKOUT_p[0] = DVI_TX_CLK ;         

assign HSTCD_TX_n[1] = DVI_TX_D[0];
assign HSTCD_TX_p[1] = DVI_TX_D[1];
assign HSTCD_TX_n[2] = DVI_TX_D[2];
assign HSTCD_TX_p[2] = DVI_TX_D[3];
assign HSTCD_TX_n[3] = DVI_TX_D[4];
assign HSTCD_TX_p[3] = DVI_TX_D[5];

assign HSTCD_TX_n[4] = DVI_TX_D[6];
assign HSTCD_TX_p[4] = DVI_TX_D[7];
assign HSTCD_TX_n[5] = DVI_TX_D[8];
assign HSTCD_TX_p[5] = DVI_TX_D[9];
assign HSTCD_TX_n[6] = DVI_TX_D[10];
assign HSTCD_TX_p[6] = DVI_TX_D[11];

assign HSTCD_TX_p[8] = DVI_TX_D[12];
assign HSTCD_TX_n[8] = DVI_TX_D[13];
assign HSTCD_TX_p[7] = DVI_TX_D[14];
assign HSTCD_TX_n[7] = DVI_TX_D[15];
assign HSTCD_CLKOUT_p[1] = DVI_TX_D[16];
assign HSTCD_RX_n[9] = DVI_TX_D[17];

assign HSTCD_RX_p[8] = DVI_TX_D[18];
assign HSTCD_RX_n[8] = DVI_TX_D[19];
assign HSTCD_RX_p[7] = DVI_TX_D[20];
assign HSTCD_RX_n[7] = DVI_TX_D[21];
assign HSTCD_RX_p[6] = DVI_TX_D[22];
assign HSTCD_RX_n[6] = DVI_TX_D[23];

//camer link capture	 
//image resolution 1024*768	
CCD_Capture  CCD_Capture_cmp
		(
			.iRST_n(rst_n),				
			.iGO(start),					
			.iWidth(IMAGE_WITH),			
			.iHeight(IMAGE_HEIGHT),		

			.iCLK(CLR_RXCLK_BASE),			
			.iDATA(CLR_BASE_D),			
			.iFVAL(CLR_BASE_FVAL),		
			.iLVAL(CLR_BASE_DVAL),		
			.oX_CONT(X_Cont),				
			.oY_CONT(Y_Cont),				
			.oDATA(cap_data),				
			.oDVAL(cap_dval),				
			.oFINISH(LEDR[0]),				
			.oFIFO_DVAL(oWRITE_w1),		
			.oLED(LEDR[1]),
			.oWidth(oWidth),
			.oHeight(oHeight),
			.oStatus(oStatus)
		);

RAW2RGB  RAW2RGB_cmp
		(
			.iX_Cont(X_Cont),				
			.iY_Cont(Y_Cont),				
			.iDATA(cap_data),				
			.iDVAL(cap_dval),				
			.iCLK(CLR_RXCLK_BASE),			
			.iRST(rst_n),				
			.oRed(red),						
			.oGreen(green),				
			.oBlue(blue),					
			.oDVAL(dval)					
		);
		
assign LEDB = Y_Cont[15:8];
assign LEDG = X_Cont[15:8];

//DDR2 Read and Write as Frame Buffer
DE3_SOPC            u7    (
                         // 1) global signals:
						   .clk_50(OSC2_50),
						   .reset_n(rst_n),

						 // the_Read_Port0   
						   .iCLK_F_to_the_Read_Port0(vpg_pclk),
						   .iIP_INIT_DONE_to_the_Read_Port0(ip_init_done),
						   .iREAD_ACK_F_to_the_Read_Port0(vpg_de),
						   .iRST_n_F_to_the_Read_Port0(read_rstn),
						   .oEMPTY_F_from_the_Read_Port0(),
						   .oPORT_READY_F_from_the_Read_Port0(),
						   .oREAD_DATA_F_from_the_Read_Port0({Read_DATA1,Read_DATA2}),

						 // the_Write_Port0     
						   .iCLK_F_to_the_Write_Port0(CLR_RXCLK_BASE),
						   .iFLUSH_REQ_F_to_the_Write_Port0(),
						   .iIP_INIT_DONE_to_the_Write_Port0(ip_init_done),
						   .iRST_n_F_to_the_Write_Port0(rst_n),
						   .iWRITE_DATA_F_to_the_Write_Port0({1'b0,green[9:5],blue[9:0],1'b0,green[4:0],red[9:0]}), //{1'b0,5'b00000,10'b1111111111,1'b0,5'b00000,10'b0000000000}{1'b0,green[9:5],blue[9:0],1'b0,green[4:0],red[9:0]}
						   .iWRITE_F_to_the_Write_Port0(dval),
						   .oBURST_COUNT_from_the_Write_Port0(),
						   .oFLUSH_BUSY_F_from_the_Write_Port0(),
						   .oFULL_F_from_the_Write_Port0(wrt_full_port0),
						  
						  // the_ddr2   
						   .global_reset_n_to_the_ddr2(rst_n),
						   .local_init_done_from_the_ddr2(ip_init_done),
						   .mem_addr_from_the_ddr2(DDR2_A),
						   .mem_ba_from_the_ddr2(DDR2_BA),
						   .mem_cas_n_from_the_ddr2(DDR2_CAS_n),
						   .mem_cke_from_the_ddr2(DDR2_CKE),
						   .mem_clk_n_to_and_from_the_ddr2(DDR2_CLK_n),
						   .mem_clk_to_and_from_the_ddr2(DDR2_CLK_p),
						   .mem_cs_n_from_the_ddr2(DDR2_CS_n),
						   .mem_dm_from_the_ddr2(DDR2_DM),
						   .mem_dq_to_and_from_the_ddr2(DDR2_DQ),
						   .mem_dqs_to_and_from_the_ddr2(DDR2_DQS_p),
						   .mem_dqsn_to_and_from_the_ddr2(DDR2_DQS_n),
						   .mem_odt_from_the_ddr2(DDR2_ODT),
						   .mem_ras_n_from_the_ddr2(DDR2_RAS_n),
						   .mem_we_n_from_the_ddr2(DDR2_WE_n),
                        
                         );
//prevent from read at starting because of none data in the ddr2
reg	[15:0]write_cnt;
always@(posedge CLR_RXCLK_BASE)
	if (~Button[0])
		write_cnt <= 0;
	else if ( (dval) & (write_cnt != 65536) )
		write_cnt <= write_cnt + 1;
			                  
reg	read_rstn;
	always@(posedge CLR_RXCLK_BASE)
		begin
			if (~Button[0])
				read_rstn <= 0;
			else if (write_cnt == 256)
				read_rstn <= 1;
		end

//system clocks generate
sys_pll sys_pll_inst(
	.areset(1'b0),
	.inclk0(OSC2_50),
	.c0(pll_100M),
	.c1(pll_100K),
	.c2(CLR_CLK_120),//25M 
	.locked(reset_n_dvi)
	);
//---------------------------------------------------//
//				DVI Mode Change Button Monitor 			 //
//---------------------------------------------------//
wire		[3:0]	vpg_mode;	
//`ifdef SXGA_1280x1024p60
	assign vpg_mode = `MODE_1024x768;
//`else
//assign vpg_mode = `VGA_640x480p60;
//`endif
//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;
//----------------------------------------------//
// 			 Video Pattern Generator	  	   	//
//----------------------------------------------//
wire [3:0]	vpg_disp_mode;
wire [1:0]	vpg_disp_color;
wire vpg_pclk;
wire vpg_de;
wire vpg_hs;
wire vpg_vs;
wire [23:0]	vpg_data;
vpg	vpg_inst(
	.clk_100(pll_100M),
	.reset_n(read_rstn & reset_n_dvi),//
	.mode(vpg_mode),
	.mode_change(1'b0),
	.disp_color(`COLOR_RGB444),       
	.vpg_pclk(vpg_pclk),
	.vpg_de(vpg_de),
	.vpg_hs(vpg_hs),
	.vpg_vs(vpg_vs),
	.vpg_r(vpg_data[23:16]), //
	.vpg_g(vpg_data[15:8]), //
	.vpg_b(vpg_data[7:0]) //
);
//DVI Signal
assign DVI_TX_DE = vpg_de;
assign DVI_TX_HS = vpg_hs;
assign DVI_TX_VS = vpg_vs;
assign DVI_TX_CLK = vpg_pclk;
//DVI data source selection via SW[0]
assign DVI_TX_D = SW[0] ? {Read_DATA2[9:2],Read_DATA1[14:10],Read_DATA2[14:12],Read_DATA1[9:2]} : vpg_data;


endmodule
