//------------------------------------------------------------------------------
//
//  lynx_dvi.v : Spartan3A dvi display test top module
//
//  LICENSE : "as-is"
//  copyright (C) 2006, TakeshiNagashima caramelgate@gmail.com
//------------------------------------------------------------------------------
//  2009/mar/03 release 0.0  xilinx sp3a
//       aug/17 release 0.0a HDL xc-303/sp3an50 + CQ BLANCA
//       aug/24 release 0.1  lynx-sp3an50
//
//------------------------------------------------------------------------------

module lynx_dvi(
//--------------------------------------------------------------
//  port

	output			DVI_TX0_N,					// out   [DVI] ch0-n tmds33(CML)/lvds
	output			DVI_TX0_P,					// out   [DVI] ch0-p tmds33(CML)/lvds
	output			DVI_TX1_N,					// out   [DVI] ch1-n tmds33(CML)/lvds
	output			DVI_TX1_P,					// out   [DVI] ch1-p tmds33(CML)/lvds
	output			DVI_TX2_N,					// out   [DVI] ch2-n tmds33(CML)/lvds
	output			DVI_TX2_P,					// out   [DVI] ch2-p tmds33(CML)/lvds
	output			DVI_TXC_N,					// out   [DVI] clk-n tmds33(CML)/lvds
	output			DVI_TXC_P,					// out   [DVI] clk-p tmds33(CML)/lvds
	inout			DVI_TX_SDA,					// inout [DVI] dcc sda
	inout			DVI_TX_SCL,					// inout [DVI] dcc scl
	inout			DVI_TX_CEC,					// inout [DVI] cec
	input			DVI_TX_HPD,					// in    [DVI] detect

	output			DVI_RX0_N,					// out   [DVI] ch0-n tmds33(CML)/lvds
	output			DVI_RX0_P,					// out   [DVI] ch0-p tmds33(CML)/lvds
	output			DVI_RX1_N,					// out   [DVI] ch1-n tmds33(CML)/lvds
	output			DVI_RX1_P,					// out   [DVI] ch1-p tmds33(CML)/lvds
	output			DVI_RX2_N,					// out   [DVI] ch2-n tmds33(CML)/lvds
	output			DVI_RX2_P,					// out   [DVI] ch2-p tmds33(CML)/lvds
	output			DVI_RXC_N,					// out   [DVI] clk-n tmds33(CML)/lvds
	output			DVI_RXC_P,					// out   [DVI] clk-p tmds33(CML)/lvds
	inout			DVI_RX_SDA,					// inout [DVI] dcc sda
	inout			DVI_RX_SCL,					// inout [DVI] dcc scl
	inout			DVI_RX_CEC,					// inout [DVI] cec
	input			DVI_RX_HPD,					// in    [DVI] detect

	output			LCD_TX0_N,					// out   [LCD] ch0-n lvds
	output			LCD_TX0_P,					// out   [LCD] ch0-p lvds
	output			LCD_TX1_N,					// out   [LCD] ch1-n lvds
	output			LCD_TX1_P,					// out   [LCD] ch1-p lvds
	output			LCD_TX2_N,					// out   [LCD] ch2-n lvds
	output			LCD_TX2_P,					// out   [LCD] ch2-p lvds
	output			LCD_TX3_N,					// out   [LCD] ch3-n lvds
	output			LCD_TX3_P,					// out   [LCD] ch3-p lvds
	output			LCD_TXC_N,					// out   [LCD] clk-n lvds
	output			LCD_TXC_P,					// out   [LCD] clk-p lvds

//	input			TX_OE_N,					// in    [RGB] tx #oe

	input	[7:0]	TX_RED,						// in    [RGB] red [7:0]
	input	[7:0]	TX_GRN,						// in    [RGB] grn [7:0]
	input	[7:0]	TX_BLU,						// in    [RGB] blu [7:0]
	input			TX_HS,						// in    [RGB] #hsync
	input			TX_VS,						// in    [RGB] #vsync
//	input			TX_C0,						// in    [RGB] c0
//	input			TX_C1,						// in    [RGB] c1
//	input			TX_C2,						// in    [RGB] c2
//	input			TX_C3,						// in    [RGB] c3
	input			TX_DE,						// in    [RGB] de
	input			TX_CLK,						// in    [RGB] clock

	input			sys_clk,					// in    [SYS] clock
	input			sys_rst_n					// in    [SYS] #reset
);

//--------------------------------------------------------------
//  override parameter

//--------------------------------------------------------------
//  local parameter

//--------------------------------------------------------------
//  signal

	wire	clk25;
	wire	clk25x5;
	wire	clk50;
	wire	clk65;
	wire	clk65x5;
	wire	clk65x7;
	wire	clk65div2;
	wire	clk65div2x7;
	wire	clk100;

	wire	rst_n;

	reg		[7:0] disp_red_r;
	reg		[7:0] disp_grn_r;
	reg		[7:0] disp_blu_r;
	reg		disp_de_r;
	reg		disp_hsync_n_r;
	reg		disp_vsync_n_r;
	reg		disp_c0_r;
	reg		disp_c1_r;
	reg		disp_c2_r;
	reg		disp_c3_r;

	wire	[7:0] disp_red;
	wire	[7:0] disp_grn;
	wire	[7:0] disp_blu;
	wire	disp_de;
	wire	disp_hsync_n;
	wire	disp_vsync_n;
	wire	disp_c0;
	wire	disp_c1;
	wire	disp_c2;
	wire	disp_c3;

	wire	TX_C0;
	wire	TX_C1;
	wire	TX_C2;
	wire	TX_C3;

	wire	TX_CLK_DDR;

	wire	[7:0] TX_RED_IN;
	wire	[7:0] TX_GRN_IN;
	wire	[7:0] TX_BLU_IN;
	wire	TX_HS_IN;
	wire	TX_VS_IN;
//	wire	TX_C0_IN;
//	wire	TX_C1_IN;
//	wire	TX_C2_IN;
//	wire	TX_C3_IN;
	wire	TX_DE_IN;
	wire	TX_CLK_IN;

//--------------------------------------------------------------
//  design


	assign DVI_TX0_N=1'bz;
	assign DVI_TX0_P=1'bz;
	assign DVI_TX1_N=1'bz;
	assign DVI_TX1_P=1'bz;
	assign DVI_TX2_N=1'bz;
	assign DVI_TX2_P=1'bz;
	assign DVI_TXC_N=1'bz;
	assign DVI_TXC_P=1'bz;
	assign DVI_TX_SDA=1'bz;
	assign DVI_TX_SCL=1'bz;
	assign DVI_TX_CEC=1'bz;

	assign DVI_TX_SDA=1'bz;
	assign DVI_TX_SCL=1'bz;
	assign DVI_TX_CEC=1'bz;

	assign DVI_RX0_N=1'bz;
	assign DVI_RX0_P=1'bz;
	assign DVI_RX1_N=1'bz;
	assign DVI_RX1_P=1'bz;
	assign DVI_RX2_N=1'bz;
	assign DVI_RX2_P=1'bz;
	assign DVI_RXC_N=1'bz;
	assign DVI_RXC_P=1'bz;
	assign DVI_RX_SDA=1'bz;
	assign DVI_RX_SCL=1'bz;
	assign DVI_RX_CEC=1'bz;

//xil_dcm_sp_25x65 dcm_sp_25x65(
xil_dcm_sp_25x66 dcm_sp_25x65(
//xil_dcm_sp_25x67 dcm_sp_25x65(
	.CLKIN_IN(TX_CLK), 
	.RST_IN(!sys_rst_n), 
	.CLKDV_OUT(), 
	.CLKFX_OUT(clk65), 
	.CLK0_OUT(clk25), 
	.CLK2X_OUT(clk50), 
	.LOCKED_OUT(rst_n)
);

	reg		clk65div2_r;

	assign clk65div2=clk65div2_r;

	always @(posedge clk65 or negedge rst_n)
	begin
		if (rst_n==1'b0)
			begin
				clk65div2_r <= 1'b0;
			end
		else
			begin
				clk65div2_r <= !clk65div2_r;
			end
	end

xil_dcm_x7d2 dcm_x7d2(
	.CLKIN_IN(clk65), 
	.RST_IN(!rst_n), 
	.CLKFX_OUT(clk65div2x7), 
	.CLKFX180_OUT(), 
	.CLK0_OUT(), 
	.LOCKED_OUT()
);

	always @(negedge clk25 or negedge rst_n)
	begin
		if (rst_n==1'b0)
			begin
				disp_red_r[7:0] <= 8'b0;
				disp_grn_r[7:0] <= 8'b0;
				disp_blu_r[7:0] <= 8'b0;
				disp_de_r <= 1'b0;
				disp_hsync_n_r <= 1'b0;
				disp_vsync_n_r <= 1'b0;
				disp_c0_r <= 1'b0;
				disp_c1_r <= 1'b0;
				disp_c2_r <= 1'b0;
				disp_c3_r <= 1'b0;
			end
		else
			begin
				disp_red_r[7:0] <= TX_RED[7:0];
				disp_grn_r[7:0] <= TX_GRN[7:0];
				disp_blu_r[7:0] <= TX_BLU[7:0];
				disp_de_r <= TX_DE;
				disp_hsync_n_r <= TX_HS;
				disp_vsync_n_r <= TX_VS;
				disp_c0_r <= 1'b0;
				disp_c1_r <= 1'b0;
				disp_c2_r <= 1'b0;
				disp_c3_r <= 1'b0;
			end
	end

	assign TX_RED_IN[7:0]=disp_red_r[7:0];
	assign TX_GRN_IN[7:0]=disp_grn_r[7:0];
	assign TX_BLU_IN[7:0]=disp_blu_r[7:0];
	assign TX_DE_IN=disp_de_r;
	assign TX_HS_IN=disp_hsync_n_r;
	assign TX_VS_IN=disp_vsync_n_r;

	wire	[7:0] TXR_RED;
	wire	[7:0] TXR_GRN;
	wire	[7:0] TXR_BLU;
	wire	TXR_HS;
	wire	TXR_VS;
	wire	TXR_DE;

xil_upscan upscan(
	.TXW_RED(TX_RED_IN[7:0]),			// in    [CRT] [7:0] red
	.TXW_GRN(TX_GRN_IN[7:0]),			// in    [CRT] [7:0] green
	.TXW_BLU(TX_BLU_IN[7:0]),			// in    [CRT] [7:0] blue
	.TXW_HS(TX_HS_IN),					// in    [CRT] #hsync
	.TXW_VS(TX_VS_IN),					// in    [CRT] #vsync
	.TXW_DE(TX_DE_IN),					// in    [CRT] #blank/de
	.TXW_CLK(clk25),					// in    [CRT] clock

	.TXR_RED(TXR_RED[7:0]),				// out   [CRT] [7:0] red
	.TXR_GRN(TXR_GRN[7:0]),				// out   [CRT] [7:0] green
	.TXR_BLU(TXR_BLU[7:0]),				// out   [CRT] [7:0] blue
	.TXR_HS(TXR_HS),					// out   [CRT] #hsync
	.TXR_VS(TXR_VS),					// out   [CRT] #vsync
	.TXR_DE(TXR_DE),					// out   [CRT] #blank/de

	.TXR_RST_N(rst_n),					// in    [SYS] #reset
	.TXR_CLK(clk65)						// in    [SYS] clock
);


xil_lvds666 lvds666(
	.LCD_TX0_N(LCD_TX0_N),				// out   [LCD] ch0-n lvds
	.LCD_TX0_P(LCD_TX0_P),				// out   [LCD] ch0-p lvds
	.LCD_TX1_N(LCD_TX1_N),				// out   [LCD] ch1-n lvds
	.LCD_TX1_P(LCD_TX1_P),				// out   [LCD] ch1-p lvds
	.LCD_TX2_N(LCD_TX2_N),				// out   [LCD] ch2-n lvds
	.LCD_TX2_P(LCD_TX2_P),				// out   [LCD] ch2-p lvds
	.LCD_TX3_N(LCD_TX3_N),				// out   [LCD] ch3-n lvds
	.LCD_TX3_P(LCD_TX3_P),				// out   [LCD] ch3-p lvds
	.LCD_TXC_N(LCD_TXC_N),				// out   [LCD] clk-n lvds
	.LCD_TXC_P(LCD_TXC_P),				// out   [LCD] clk-p lvds

	.TX_RED(TXR_RED[7:0]),				// in    [TX] red [7:0]
	.TX_GRN(TXR_GRN[7:0]),				// in    [TX] grn [7:0]
	.TX_BLU(TXR_BLU[7:0]),				// in    [TX] blu [7:0]
	.TX_HS(TXR_HS),						// in    [TX] #hsync
	.TX_VS(TXR_VS),						// in    [TX] #vsync
	.TX_C0(1'b0),						// in    [TX] c0
	.TX_C1(1'b0),						// in    [TX] c1
	.TX_C2(1'b0),						// in    [TX] c2
	.TX_C3(1'b0),						// in    [TX] c3
	.TX_DE(TXR_DE),						// in    [TX] de

	.CLK(clk65),						// in    [TX] clock
	.CLK_div2(clk65div2),				// in    [TX] clk /2
	.CLK_div2x7(clk65div2x7),			// in    [TX] clk /2x7 : lvds ddr
	.RESET_N(rst_n)						// in    [TX] #reset
);

endmodule
