//------------------------------------------------------------------------------
//
//  lynx_hdmi.v : Spartan3A hdmi display test top module
//
//  LICENSE : "as-is"
//  copyright (C) 2006, TakeshiNagashima caramelgate@gmail.com
//------------------------------------------------------------------------------
//  2009/sep/09 release 0.0  connection test
//
//------------------------------------------------------------------------------

module lynx_hdmi(
//--------------------------------------------------------------
//  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] RX_RED;
	wire	[7:0] RX_GRN;
	wire	[7:0] RX_BLU;
	wire	RX_HS;
	wire	RX_VS;
//	wire	RX_C0;
//	wire	RX_C1;
//	wire	RX_C2;
//	wire	RX_C3;
	wire	RX_DE;
	wire	RX_CLK;

	wire	[7:0] TX_OUT;
	wire	[3:0] TX_DDR;

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

//	assign TX_RED[7:0]=8'hzz;
//	assign TX_GRN[7:0]=8'hzz;
//	assign TX_BLU[7:0]=8'hzz;
//	assign TX_DE=1'bz;
///	assign TX_HS=1'bz;
//	assign TX_VS=1'bz;
//	assign TX_CLK=1'bz;

//	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_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_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;

	assign clk65=TX_CLK;
	assign rst_n=sys_rst_n;

//xil_dcm_sp_50x65 dcm_sp_50x65(
//	.CLKIN_IN(sys_clk), 
//	.RST_IN(!sys_rst_n), 
//	.CLKDV_OUT(clk25), 
//	.CLKFX_OUT(clk65), 
//	.CLK0_OUT(clk50), 
//	.CLK2X_OUT(clk100), 
//	.LOCKED_OUT(rst_n)
//);

`ifdef sim_x5

	assign clk65x5=1'b0;

`else

xil_dcm_x5 dcm_x5(
	.CLKIN_IN(clk65), 
	.RST_IN(!rst_n), 
	.CLKFX_OUT(clk65x5), 
	.CLKFX180_OUT(), 
	.CLK0_OUT(), 
	.LOCKED_OUT()
);

`endif

//dispgen_xga dispgen(
//	.D_RED(TX_RED[7:0]),		// out   [CRT] [7:0] red
//	.D_GRN(TX_GRN[7:0]),		// out   [CRT] [7:0] green
//	.D_BLU(TX_BLU[7:0]),		// out   [CRT] [7:0] blue
//	.D_HSYNC_N(TX_HS),			// out   [CRT] #hsync
//	.D_VSYNC_N(TX_VS),			// out   [CRT] #vsync
//	.D_BLANK_N(TX_DE),			// out   [CRT] #blank
//	.D_MODE(4'b0),				// in    [] [3:0] sim/#normal
//	.D_RST_N(rst_n),			// in    [] : #reset
//	.D_CLK(clk65)				// in    [CRT] dot clock
//);
/*
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_dvi(
	.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(TX_RED[7:0]),				// in    [TX] red [7:0]
	.TX_GRN(TX_GRN[7:0]),				// in    [TX] grn [7:0]
	.TX_BLU(TX_BLU[7:0]),				// in    [TX] blu [7:0]
	.TX_HS(TX_HS),						// in    [TX] #hsync
	.TX_VS(TX_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(TX_DE),						// in    [TX] de

	.CLK(clk65),						// in    [TX] clock
	.CLKx5(clk65x5),					// in    [DVI] clk x5 : dvi ddr
	.RESET_N(rst_n)						// in    [TX] #reset
);
*/

hdmi_encoder # (
	.SDATAINVERT("TRUE")
//	.SDATAINVERT("FALSE")
) hdmi_tx0 (
	.clkin(clk65),
	.clkx5in(clk65x5),
	.clkx5notin(!clk65x5),
	.rstin(!rst_n),
	.blue_din(TX_BLU[7:0]),
	.green_din(TX_GRN[7:0]),
	.red_din(TX_RED[7:0]),
	.hsync(TX_HS),
	.vsync(TX_VS),
	.vde(TX_DE),
	.ade(1'b0),
	.aux0_din(4'b0),
	.aux1_din(4'b0),
	.aux2_din(4'b0),
	.tmds_data(TX_OUT[7:0])
);

ODDR2 #(
	.DDR_ALIGNMENT("NONE")
) ddr_reg0 (
	.C0(clk65x5), 
	.C1(!clk65x5), 
	.D0(TX_OUT[0]), 
	.D1(TX_OUT[4]), 
	.CE(1'b1), 
	.R(1'b0), 
	.S(1'b0), 
	.Q(TX_DDR[0])
) ;

ODDR2 #(
	.DDR_ALIGNMENT("NONE")
) ddr_reg1 (
	.C0(clk65x5), 
	.C1(!clk65x5), 
	.D0(TX_OUT[1]), 
	.D1(TX_OUT[5]), 
	.CE(1'b1), 
	.R(1'b0), 
	.S(1'b0), 
	.Q(TX_DDR[1])
) ;

ODDR2 #(
	.DDR_ALIGNMENT("NONE")
) ddr_reg2 (
	.C0(clk65x5), 
	.C1(!clk65x5), 
	.D0(TX_OUT[2]), 
	.D1(TX_OUT[6]), 
	.CE(1'b1), 
	.R(1'b0), 
	.S(1'b0), 
	.Q(TX_DDR[2])
) ;

ODDR2 #(
	.DDR_ALIGNMENT("NONE")
) ddr_reg3 (
	.C0(clk65x5),       
	.C1(!clk65x5),    
	.D0(TX_OUT[3]),
	.D1(TX_OUT[7]),
	.CE(1'b1), 
	.R(1'b0), 
	.S(1'b0), 
	.Q(TX_DDR[3])
) ;

OBUFDS TMDS0 (.I(TX_DDR[0]), .O(DVI_TX0_P), .OB(DVI_TX0_N)) ;
OBUFDS TMDS1 (.I(TX_DDR[1]), .O(DVI_TX1_P), .OB(DVI_TX1_N)) ;
OBUFDS TMDS2 (.I(TX_DDR[2]), .O(DVI_TX2_P), .OB(DVI_TX2_N)) ;
OBUFDS TMDS3 (.I(TX_DDR[3]), .O(DVI_TXC_P), .OB(DVI_TXC_N)) ;// clock

endmodule
