//------------------------------------------------------------------------------
//
//  lynx_dvi_x2.v : Spartan3A dual 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
//       oct/02 release 0.2  dual dvi
//
//------------------------------------------------------------------------------

module lynx_dvi_x2(
//--------------------------------------------------------------
//  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] disp0_red_r;
	reg		[7:0] disp0_grn_r;
	reg		[7:0] disp0_blu_r;
	reg		disp0_de_r;
	reg		disp0_hsync_n_r;
	reg		disp0_vsync_n_r;
	reg		disp0_c0_r;
	reg		disp0_c1_r;
	reg		disp0_c2_r;
	reg		disp0_c3_r;

	reg		[7:0] disp1_red_r;
	reg		[7:0] disp1_grn_r;
	reg		[7:0] disp1_blu_r;
	reg		disp1_de_r;
	reg		disp1_hsync_n_r;
	reg		disp1_vsync_n_r;
	reg		disp1_c0_r;
	reg		disp1_c1_r;
	reg		disp1_c2_r;
	reg		disp1_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;

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

	wire	[7:0] RX0_RED;
	wire	[7:0] RX0_GRN;
	wire	[7:0] RX0_BLU;
	wire	RX0_HS;
	wire	RX0_VS;
	wire	RX0_DE;

	wire	[7:0] RX1_RED;
	wire	[7:0] RX1_GRN;
	wire	[7:0] RX1_BLU;
	wire	RX1_HS;
	wire	RX1_VS;
	wire	RX1_DE;

	reg		TX_HS_r;
	reg		TX_VS_r;
	reg		TX_DE_r;
	reg		[7:0] TX_RED_r;
	reg		[7:0] TX_GRN_r;
	reg		[7:0] TX_BLU_r;

	always @(posedge TX_CLK or negedge sys_rst_n)
	begin
		if (sys_rst_n==1'b0)
			begin
				TX_HS_r <= 1'b0;
				TX_VS_r <= 1'b0;
				TX_DE_r <= 1'b0;
				TX_RED_r[7:0] <= 8'b0;
				TX_GRN_r[7:0] <= 8'b0;
				TX_BLU_r[7:0] <= 8'b0;
			end
		else
			begin
				TX_HS_r <= TX_HS;
				TX_VS_r <= TX_VS;
				TX_DE_r <= TX_DE;
				TX_RED_r[7:0] <= TX_RED[7:0];
				TX_GRN_r[7:0] <= TX_GRN[7:0];
				TX_BLU_r[7:0] <= TX_BLU[7:0];
			end
	end

	// ---- dvi output ----

xil_dcm_x5 dcm_x5(
	.CLKIN_IN(TX_CLK), 
	.RST_IN(!sys_rst_n), 
	.CLKFX_OUT(clk25x5), 
	.CLKFX180_OUT(), 
	.CLK0_OUT(clk25), 
	.LOCKED_OUT(rst_n)
);

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

	assign DVI_RX_SDA=1'bz;
	assign DVI_RX_SCL=1'bz;
	assign DVI_RX_CEC=1'bz;

	always @(negedge TX_CLK or negedge rst_n)
	begin
		if (rst_n==1'b0)
			begin
				disp0_red_r[7:0] <= 8'b0;
				disp0_grn_r[7:0] <= 8'b0;
				disp0_blu_r[7:0] <= 8'b0;
				disp0_de_r <= 1'b0;
				disp0_hsync_n_r <= 1'b0;
				disp0_vsync_n_r <= 1'b0;
				disp0_c0_r <= 1'b0;
				disp0_c1_r <= 1'b0;
				disp0_c2_r <= 1'b0;
				disp0_c3_r <= 1'b0;
				disp1_red_r[7:0] <= 8'b0;
				disp1_grn_r[7:0] <= 8'b0;
				disp1_blu_r[7:0] <= 8'b0;
				disp1_de_r <= 1'b0;
				disp1_hsync_n_r <= 1'b0;
				disp1_vsync_n_r <= 1'b0;
				disp1_c0_r <= 1'b0;
				disp1_c1_r <= 1'b0;
				disp1_c2_r <= 1'b0;
				disp1_c3_r <= 1'b0;
			end
		else
			begin
				disp0_red_r[7:0] <= TX_RED_r[7:0];
				disp0_grn_r[7:0] <= TX_GRN_r[7:0];
				disp0_blu_r[7:0] <= TX_BLU_r[7:0];
				disp0_de_r <= TX_DE;
				disp0_hsync_n_r <= TX_VS_r;
				disp0_vsync_n_r <= TX_VS;
				disp0_c0_r <= 1'b0;
				disp0_c1_r <= 1'b0;
				disp0_c2_r <= 1'b0;
				disp0_c3_r <= 1'b0;
				disp1_red_r[7:0] <= TX_RED[7:0];
				disp1_grn_r[7:0] <= TX_GRN[7:0];
				disp1_blu_r[7:0] <= TX_BLU[7:0];
				disp1_de_r <= TX_DE;
				disp1_hsync_n_r <= TX_VS_r;
				disp1_vsync_n_r <= TX_VS;
				disp1_c0_r <= 1'b0;
				disp1_c1_r <= 1'b0;
				disp1_c2_r <= 1'b0;
				disp1_c3_r <= 1'b0;
			end
	end

xil_dvi #(
	.DVI_TX0(1),						// polarity 0=normal / 1=invert
	.DVI_TX1(1),						// polarity 0=normal / 1=invert
	.DVI_TX2(1),						// polarity 0=normal / 1=invert
	.DVI_TXC(1)							// polarity 0=normal / 1=invert
) xil_dvi0(
	.DVI_TX0_N(DVI_TX0_N),				// out   [TX] TX[0]-N (CML)
	.DVI_TX0_P(DVI_TX0_P),				// out   [TX] TX[0]-P (CML)
	.DVI_TX1_N(DVI_TX1_N),				// out   [TX] TX[1]-N (CML)
	.DVI_TX1_P(DVI_TX1_P),				// out   [TX] TX[1]-P (CML)
	.DVI_TX2_N(DVI_TX2_N),				// out   [TX] TX[2]-N (CML)
	.DVI_TX2_P(DVI_TX2_P),				// out   [TX] TX[2]-P (CML)
	.DVI_TXC_N(DVI_TXC_N),				// out   [TX] TX_CLK-N (CML)
	.DVI_TXC_P(DVI_TXC_P),				// out   [TX] TX_CLK-P (CML)

	.TX_RED(disp1_red_r[7:0]),			// in    [TX] red [7:0]
	.TX_GRN(disp1_grn_r[7:0]),			// in    [TX] grn [7:0]
	.TX_BLU(disp1_blu_r[7:0]),			// in    [TX] blu [7:0]
	.TX_HS(disp1_hsync_n_r),				// in    [TX] #hsync
	.TX_VS(disp1_vsync_n_r),				// in    [TX] #vsync
	.TX_C0(disp1_c0_r),					// in    [TX] c0
	.TX_C1(disp1_c1_r),					// in    [TX] c1
	.TX_C2(disp1_c2_r),					// in    [TX] c2
	.TX_C3(disp1_c3_r),					// in    [TX] c3
	.TX_DE(disp1_de_r),					// in    [TX] de

	.CLK(clk25),						// in    [DVI] clock
	.CLKx5(clk25x5),					// in    [DVI] clk x5 : dvi ddr
	.RESET_N(rst_n)						// in    [DVI] #reset
);

xil_dvi #(
	.DVI_TX0(0),						// polarity 0=normal / 1=invert
	.DVI_TX1(0),						// polarity 0=normal / 1=invert
	.DVI_TX2(0),						// polarity 0=normal / 1=invert
	.DVI_TXC(0)							// polarity 0=normal / 1=invert
) xil_dvi1(
	.DVI_TX0_N(DVI_RX0_N),				// out   [TX] TX[0]-N (CML)
	.DVI_TX0_P(DVI_RX0_P),				// out   [TX] TX[0]-P (CML)
	.DVI_TX1_N(DVI_RX1_N),				// out   [TX] TX[1]-N (CML)
	.DVI_TX1_P(DVI_RX1_P),				// out   [TX] TX[1]-P (CML)
	.DVI_TX2_N(DVI_RX2_N),				// out   [TX] TX[2]-N (CML)
	.DVI_TX2_P(DVI_RX2_P),				// out   [TX] TX[2]-P (CML)
	.DVI_TXC_N(DVI_RXC_N),				// out   [TX] TX_CLK-N (CML)
	.DVI_TXC_P(DVI_RXC_P),				// out   [TX] TX_CLK-P (CML)

	.TX_RED(disp0_red_r[7:0]),			// in    [TX] red [7:0]
	.TX_GRN(disp0_grn_r[7:0]),			// in    [TX] grn [7:0]
	.TX_BLU(disp0_blu_r[7:0]),			// in    [TX] blu [7:0]
	.TX_HS(disp1_hsync_n_r),				// in    [TX] #hsync
	.TX_VS(disp1_vsync_n_r),				// in    [TX] #vsync
	.TX_C0(disp0_c0_r),					// in    [TX] c0
	.TX_C1(disp0_c1_r),					// in    [TX] c1
	.TX_C2(disp0_c2_r),					// in    [TX] c2
	.TX_C3(disp0_c3_r),					// in    [TX] c3
	.TX_DE(disp1_de_r),					// in    [TX] de

	.CLK(clk25),						// in    [DVI] clock
	.CLKx5(clk25x5),					// in    [DVI] clk x5 : dvi ddr
	.RESET_N(rst_n)						// in    [DVI] #reset
);

	assign LCD_TX0_N=clk25;
	assign LCD_TX0_P=disp1_hsync_n_r;
	assign LCD_TX1_N=disp1_vsync_n_r;
	assign LCD_TX1_P=disp1_de_r;
	assign LCD_TX2_N=1'bz;
	assign LCD_TX2_P=1'bz;
	assign LCD_TX3_N=1'bz;
	assign LCD_TX3_P=1'bz;
	assign LCD_TXC_N=1'bz;
	assign LCD_TXC_P=1'bz;

endmodule
