// --------------------------------------------------------------------
// Copyright (c) 2011 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 demo on DE2-115 with VGA display
//                  Camera link -> HSMC 
//                  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
//=======================================================
`include "VGA_Param.h" 
module DE2_115_CLR(

	//////////// CLOCK //////////
	CLOCK_50,
	CLOCK2_50,
	CLOCK3_50,

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

	//////////// KEY //////////
	KEY,

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

	//////////// SEG7 //////////
	HEX0,
	HEX1,
	HEX2,
	HEX3,
	HEX4,
	HEX5,
	HEX6,
	HEX7,

	//////////// RS232 //////////
	UART_CTS,
	UART_RTS,
	UART_RXD,
	UART_TXD,

	//////////// VGA //////////
	VGA_B,
	VGA_BLANK_N,
	VGA_CLK,
	VGA_G,
	VGA_HS,
	VGA_R,
	VGA_SYNC_N,
	VGA_VS,

	//////////// I2C for HSMC  //////////
	I2C_SCLK,
	I2C_SDAT,

	//////////// SDRAM //////////
	DRAM_ADDR,
	DRAM_BA,
	DRAM_CAS_N,
	DRAM_CKE,
	DRAM_CLK,
	DRAM_CS_N,
	DRAM_DQ,
	DRAM_DQM,
	DRAM_RAS_N,
	DRAM_WE_N,

	//////////// GPIO, GPIO connect to GPIO Default //////////
	GPIO,

	//////////// HSMC, HSMC connect to Camera Link Receiver //////////
	CLRRX_BASE,
	CLRRX_FULL10_HSMC,
	CLRRX_FULL11_HSMC,
	CLRRX_FULL12_HSMC,
	CLRRX_FULL13_HSMC,
	CLRRX_FULL14_HSMC,
	CLRRX_FULL27_HSMC,
	CLRRX_FULL9_HSMC,
	CLRRX_MEDIUM,
	CLRRX2CC,
	CLRRX2CC_EN,
	CLRRX2SERTC,
	CLRRX2SERTC_EN,
	CLRRX2SERTFG,
	CLRRX2SERTFG_EN,
	CLRRXCC,
	CLRRXCC_EN,
	CLRRXCLK_BASE,
	CLRRXCLK_FULL,
	CLRRXCLK_MEDIUM,
	CLRRXSERTC,
	CLRRXSERTC_EN,
	CLRRXSERTFG,
	CLRRXSERTFG_EN 
);

//=======================================================
//  PARAMETER declarations
//=======================================================
parameter  IMAGE_WITH    =  32'h00000280;  //640
parameter  IMAGE_HEIGHT  =  32'h000001E0;  //480
//=======================================================
//  PORT declarations
//=======================================================

//////////// CLOCK //////////
input		          		   CLOCK_50;
input		          		   CLOCK2_50;
input		          		   CLOCK3_50;

//////////// LED //////////
output		     [8:0]		LEDG;
output		    [17:0]		LEDR;

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

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

//////////// SEG7 //////////
output		     [6:0]		HEX0;
output		     [6:0]		HEX1;
output		     [6:0]		HEX2;
output		     [6:0]		HEX3;
output		     [6:0]		HEX4;
output		     [6:0]		HEX5;
output		     [6:0]		HEX6;
output		     [6:0]		HEX7;

//////////// RS232 //////////
output		          		UART_CTS;
input		          		   UART_RTS;
input		          		   UART_RXD;
output		          		UART_TXD;

//////////// VGA //////////
output		     [7:0]		VGA_B;
output		          		VGA_BLANK_N;
output		          		VGA_CLK;
output		     [7:0]		VGA_G;
output		          		VGA_HS;
output		     [7:0]		VGA_R;
output		          		VGA_SYNC_N;
output		          		VGA_VS;

//////////// I2C for HSMC  //////////
output		          		I2C_SCLK;
inout		          		   I2C_SDAT;

//////////// SDRAM //////////
output		    [12:0]		DRAM_ADDR;
output		     [1:0]		DRAM_BA;
output		          		DRAM_CAS_N;
output		          		DRAM_CKE;
output		          		DRAM_CLK;
output		          		DRAM_CS_N;
inout		       [31:0]		DRAM_DQ;
output		     [3:0]		DRAM_DQM;
output		          		DRAM_RAS_N;
output		          		DRAM_WE_N;

//////////// GPIO, GPIO connect to GPIO Default //////////
inout		       [35:0]		GPIO;

//////////// HSMC, HSMC connect to Camera Link Receiver //////////
input		       [27:0]		CLRRX_BASE;
input		            		CLRRX_FULL10_HSMC;
input		          	   	CLRRX_FULL11_HSMC;
input		          		   CLRRX_FULL12_HSMC;
input		          	   	CLRRX_FULL13_HSMC;
input		          	   	CLRRX_FULL14_HSMC;
input		          		   CLRRX_FULL27_HSMC;
input		          		   CLRRX_FULL9_HSMC;
input		      [27:0]		CLRRX_MEDIUM;
output		    [4:1]		CLRRX2CC;
output		          		CLRRX2CC_EN;
output		          		CLRRX2SERTC;
output		          		CLRRX2SERTC_EN;
input		          	   	CLRRX2SERTFG;
output		          		CLRRX2SERTFG_EN;
output		    [4:1]		CLRRXCC;
output		          		CLRRXCC_EN;
input		          	   	CLRRXCLK_BASE;
input		          		   CLRRXCLK_FULL;
input		          		   CLRRXCLK_MEDIUM;
output		          		CLRRXSERTC;
output		          		CLRRXSERTC_EN;
input		          		   CLRRXSERTFG;
output		          		CLRRXSERTFG_EN;

//=======================================================
//  REG/WIRE declarations
//=======================================================
wire				   			CLR_BASE_CLK;
wire		       [9:0]		CLR_BASE_D;
wire							   CLR_BASE_FVAL;
wire							   CLR_BASE_LVAL;
wire						      start;
wire						      rst_n;
wire	         [15:0]	   X_Cont;
wire	         [15:0]	   Y_Cont;
wire		       [9:0]		cap_data;
wire				   			cap_dval;
wire                       dval;
wire                       oWRITE_w1;
wire			               sdram_ctrl_clk;
wire	         [15:0]	   Read_DATA1;
wire	         [15:0]	   Read_DATA2;
wire		       [9:0]		red;
wire		       [9:0]		green;
wire		       [9:0]		blue;
wire                       Read;
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]
wire                       VGA_CTRL_CLK;
//=======================================================
//  Structural coding
//=======================================================
//camera link base1 and base2 selection via SW[0]
assign	CLR_BASE_CLK	=	SW[0] ? CLRRXCLK_BASE : CLRRXCLK_MEDIUM;  //clk
assign	CLR_BASE_D[0]	=	SW[0] ? CLRRX_BASE[0] : CLRRX_MEDIUM[0];  //0
assign	CLR_BASE_D[1]	=	SW[0] ? CLRRX_BASE[1] : CLRRX_MEDIUM[1];  //1 
assign	CLR_BASE_D[2]	=	SW[0] ? CLRRX_BASE[2] : CLRRX_MEDIUM[2];  //2
assign	CLR_BASE_D[3]	=	SW[0] ? CLRRX_BASE[3] : CLRRX_MEDIUM[3];  //3
assign	CLR_BASE_D[4]	=	SW[0] ? CLRRX_BASE[4] : CLRRX_MEDIUM[4];  //4
assign	CLR_BASE_D[5]	=	SW[0] ? CLRRX_BASE[6] : CLRRX_MEDIUM[6];  //6
assign	CLR_BASE_D[6]	=	SW[0] ? CLRRX_BASE[27]: CLRRX_MEDIUM[27]; //27
assign	CLR_BASE_D[7]	=	SW[0] ? CLRRX_BASE[5] : CLRRX_MEDIUM[5];  //5
assign	CLR_BASE_D[8]	=	SW[0] ? CLRRX_BASE[7] : CLRRX_MEDIUM[7];  //7
assign	CLR_BASE_D[9]	=	SW[0] ? CLRRX_BASE[8] : CLRRX_MEDIUM[8];  //8
assign	CLR_BASE_FVAL	=	SW[0] ? CLRRX_BASE[25]: CLRRX_MEDIUM[25]; //25
assign	CLR_BASE_LVAL	=	SW[0] ? CLRRX_BASE[24]: CLRRX_MEDIUM[24]; //24

//reset module
Reset_Delay	Reset_Delay_cmp
		(
			.iCLK(CLOCK2_50),
//			.iCLK(CLR_BASE_CLK),
			.iRST(KEY[0]),
			.oRST_0(),
			.oRST_1(rst_n),
			.oRST_2(start)
		);
//camera link video capture
CCD_Capture  CCD_Capture_cmp
		(
			.iRST_n(rst_n),				
			.iGO(start),					
			.iWidth(IMAGE_WITH),			   
			.iHeight(IMAGE_HEIGHT),			

			.iCLK(CLR_BASE_CLK),			
			.iDATA(CLR_BASE_D),			
			.iFVAL(CLR_BASE_FVAL),		
			.iLVAL(CLR_BASE_LVAL),		
			.oX_CONT(X_Cont),				
			.oY_CONT(Y_Cont),				
			.oDATA(cap_data),				
			.oDVAL(cap_dval),				
			.oFINISH(),				
			.oLED()

		);
assign LEDR[15:0]  =  X_Cont;  
//bayer filter output change to 10-bit RGB
RAW2RGB  RAW2RGB_cmp
		(
			.iX_Cont(X_Cont),				
			.iY_Cont(Y_Cont),				
			.iDATA(cap_data),				
			.iDVAL(cap_dval),				
			.iCLK(CLR_BASE_CLK),			
			.iRST(rst_n),				
			.oRed(red),						
			.oGreen(green),				
			.oBlue(blue),					
			.oDVAL(dval)					
		);


//SDRam Read and Write as Frame Buffer
Sdram_Control	u7	(	//	HOST Side						
						   .RESET_N(KEY[0]),
							.CLK(sdram_ctrl_clk),

							//	FIFO Write Side 1
							.WR1_DATA({1'b0,green[9:5],blue[9:0]}),
							.WR1(dval),
							.WR1_ADDR(0),
`ifdef VGA_640x480p60
						   .WR1_MAX_ADDR(640*480/2),
						   .WR1_LENGTH(8'h50),
`else
							.WR1_MAX_ADDR(800*600/2),
							.WR1_LENGTH(8'h80),
`endif							
							.WR1_LOAD(!rst_n),
							.WR1_CLK(CLR_BASE_CLK),

							//	FIFO Write Side 2
							.WR2_DATA({1'b0,green[4:0],red[9:0]}),
							.WR2(dval),
							.WR2_ADDR(23'h100000),
`ifdef VGA_640x480p60
						   .WR2_MAX_ADDR(23'h100000+640*480/2),
							.WR2_LENGTH(8'h50),
`else							
							.WR2_MAX_ADDR(23'h100000+800*600/2),
							.WR2_LENGTH(8'h80),
`endif	
							.WR2_LOAD(!rst_n),
							.WR2_CLK(CLR_BASE_CLK),

							//	FIFO Read Side 1
						   .RD1_DATA(Read_DATA1),
				        	.RD1(Read),
				        	.RD1_ADDR(0),
`ifdef VGA_640x480p60
						   .RD1_MAX_ADDR(640*480/2),
							.RD1_LENGTH(8'h50),
`else
							.RD1_MAX_ADDR(800*600/2),
							.RD1_LENGTH(8'h80),
`endif
							.RD1_LOAD(!rst_n),
							.RD1_CLK(~VGA_CTRL_CLK),
							
							//	FIFO Read Side 2
						   .RD2_DATA(Read_DATA2),
							.RD2(Read),
							.RD2_ADDR(23'h100000),
`ifdef VGA_640x480p60
						   .RD2_MAX_ADDR(23'h100000+640*480/2),
							.RD2_LENGTH(8'h50),
`else
							.RD2_MAX_ADDR(23'h100000+800*600/2),
							.RD2_LENGTH(8'h80),
`endif
				        	.RD2_LOAD(!rst_n),
							.RD2_CLK(~VGA_CTRL_CLK),
							
							//	SDRAM Side
						   .SA(DRAM_ADDR),
							.BA(DRAM_BA),
							.CS_N(DRAM_CS_N),
							.CKE(DRAM_CKE),
							.RAS_N(DRAM_RAS_N),
							.CAS_N(DRAM_CAS_N),
							.WE_N(DRAM_WE_N),
							.DQ(DRAM_DQ),
							.DQM(DRAM_DQM)
						);

//VGA DISPLAY
VGA_Controller		u1	(	//	Host Side
							.oRequest(Read),
							.iRed(Read_DATA2[9:0]),
							.iGreen({Read_DATA1[14:10],Read_DATA2[14:10]}),
							.iBlue(Read_DATA1[9:0]),
							//	VGA Side
							.oVGA_R(oVGA_R),
							.oVGA_G(oVGA_G),
							.oVGA_B(oVGA_B),
							.oVGA_H_SYNC(VGA_HS),
							.oVGA_V_SYNC(VGA_VS),
							.oVGA_SYNC(VGA_SYNC_N),
							.oVGA_BLANK(VGA_BLANK_N),
							//	Control Signal
							.iCLK(VGA_CTRL_CLK),
							.iRST_N(rst_n),
							.iZOOM_MODE_SW(SW[16])
						);
//VGA RGB 
//fetch the high 8 bits
assign  VGA_R  =  oVGA_R[9:2];
assign  VGA_G  =  oVGA_G[9:2];
assign  VGA_B  =  oVGA_B[9:2];
//clock
sdram_pll 			u6	(
							.inclk0(CLOCK2_50),
							.c0(sdram_ctrl_clk),
							.c1(DRAM_CLK),
//							.c2(D5M_XCLKIN), //25M
`ifdef VGA_640x480p60
							.c3(VGA_CLK)     //25M 
`else
						   .c4(VGA_CLK)     //40M 	
`endif
						);

assign VGA_CTRL_CLK = ~VGA_CLK;

endmodule
