//------------------------------------------------------------------------------
//
//  lynx_disp.v : Spartan3A 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
//       aug/24 release 0.1  lynx-sp3an50
//
//------------------------------------------------------------------------------

module lynx_disp(
//--------------------------------------------------------------
//  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

	input			DVI_RX0_N,					// in    [DVI] ch0-n tmds33(CML)/lvds
	input			DVI_RX0_P,					// in    [DVI] ch0-p tmds33(CML)/lvds
	input			DVI_RX1_N,					// in    [DVI] ch1-n tmds33(CML)/lvds
	input			DVI_RX1_P,					// in    [DVI] ch1-p tmds33(CML)/lvds
	input			DVI_RX2_N,					// in    [DVI] ch2-n tmds33(CML)/lvds
	input			DVI_RX2_P,					// in    [DVI] ch2-p tmds33(CML)/lvds
	input			DVI_RXC_N,					// in    [DVI] clk-n tmds33(CML)/lvds
	input			DVI_RXC_P,					// in    [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

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

	output	[7:0]	TX_RED,						// out   [RGB] red [7:0]
	output	[7:0]	TX_GRN,						// out   [RGB] grn [7:0]
	output	[7:0]	TX_BLU,						// out   [RGB] blu [7:0]
	output			TX_HS,						// out   [RGB] #hsync
	output			TX_VS,						// out   [RGB] #vsync
//	output			TX_C0,						// out   [RGB] c0
//	output			TX_C1,						// out   [RGB] c1
//	output			TX_C2,						// out   [RGB] c2
//	output			TX_C3,						// out   [RGB] c3
	output			TX_DE,						// out   [RGB] de
	output			TX_CLK,						// out   [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;

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

	wire	TX_OE_N;

	assign TX_OE_N=1'b0;

	assign TX_RED[7:0]=(TX_OE_N==1'b0) ? disp_red_r[7:0] : 8'hzz;
	assign TX_GRN[7:0]=(TX_OE_N==1'b0) ? disp_grn_r[7:0] : 8'hzz;
	assign TX_BLU[7:0]=(TX_OE_N==1'b0) ? disp_blu_r[7:0] : 8'hzz;
	assign TX_DE=(TX_OE_N==1'b0) ? disp_de_r : 1'bz;
	assign TX_HS=(TX_OE_N==1'b0) ? disp_hsync_n_r : 1'bz;
	assign TX_VS=(TX_OE_N==1'b0) ? disp_vsync_n_r : 1'bz;
	assign TX_C0=(TX_OE_N==1'b0) ? disp_c0_r : 1'bz;
	assign TX_C1=(TX_OE_N==1'b0) ? disp_c1_r : 1'bz;
	assign TX_C2=(TX_OE_N==1'b0) ? disp_c2_r : 1'bz;
	assign TX_C3=(TX_OE_N==1'b0) ? disp_c3_r : 1'bz;

	assign TX_CLK=(TX_OE_N==1'b0) ? TX_CLK_DDR : 1'bz;

FDDRRSE DDR_TX_CLK(.Q(TX_CLK_DDR),.C0(clk65),.C1(!clk65),.CE(1'b1),.D0(1'b1),.D1(1'b0),.R(1'b0),.S(1'b0));


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

	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

dispgen_xga dispgen(
	.D_RED(disp_red),					// out   [CRT] [7:0] red
	.D_GRN(disp_grn),					// out   [CRT] [7:0] green
	.D_BLU(disp_blu),					// out   [CRT] [7:0] blue
	.D_HSYNC_N(disp_hsync_n),			// out   [CRT] #hsync
	.D_VSYNC_N(disp_vsync_n),			// out   [CRT] #vsync
	.D_BLANK_N(disp_de),				// out   [CRT] #blank

	.D_MODE(4'b0),						// in    [SYS] [3:0] sim/#normal

	.D_RST_N(rst_n),					// in    [SYS] #reset
	.D_CLK(clk65)						// in    [SYS] dot clock
);

	assign disp_c0=1'b0;
	assign disp_c1=1'b0;
	assign disp_c2=1'b0;
	assign disp_c3=1'b0;

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

	always @(posedge clk65 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] <= disp_red[7:0];
				disp_grn_r[7:0] <= disp_grn[7:0];
				disp_blu_r[7:0] <= disp_blu[7:0];
				disp_de_r <= disp_de;
				disp_hsync_n_r <= disp_hsync_n;
				disp_vsync_n_r <= disp_vsync_n;
				disp_c0_r <= disp_c0;
				disp_c1_r <= disp_c1;
				disp_c2_r <= disp_c2;
				disp_c3_r <= disp_c3;
			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_dvi(
	.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(disp_red_r[7:0]),			// in    [TX] red [7:0]
	.TX_GRN(disp_grn_r[7:0]),			// in    [TX] grn [7:0]
	.TX_BLU(disp_blu_r[7:0]),			// in    [TX] blu [7:0]
	.TX_HS(disp_hsync_n_r),				// in    [TX] #hsync
	.TX_VS(disp_vsync_n_r),				// in    [TX] #vsync
	.TX_C0(disp_c0_r),					// in    [TX] c0
	.TX_C1(disp_c1_r),					// in    [TX] c1
	.TX_C2(disp_c2_r),					// in    [TX] c2
	.TX_C3(disp_c3_r),					// in    [TX] c3
	.TX_DE(disp_de_r),					// in    [TX] de

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

/*
`ifdef sim_x7

	assign clk65div2x7=1'b0;

`else

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

`endif

	wire	[7:0] TXW_RED;
	wire	[7:0] TXW_GRN;
	wire	[7:0] TXW_BLU;
	wire	TXW_HS;
	wire	TXW_VS;
	wire	TXW_DE;

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

dispgen_vga dispgen_vga(
	.D_RED(TXW_RED[7:0]),				// out   [CRT] [7:0] red
	.D_GRN(TXW_GRN[7:0]),				// out   [CRT] [7:0] green
	.D_BLU(TXW_BLU[7:0]),				// out   [CRT] [7:0] blue
	.D_HSYNC_N(TXW_HS),					// out   [CRT] #hsync
	.D_VSYNC_N(TXW_VS),					// out   [CRT] #vsync
	.D_BLANK_N(TXW_DE),					// out   [CRT] #blank

	.D_MODE(4'b0),						// in    [SYS] [3:0] sim/#normal

	.D_RST_N(rst_n),					// in    [SYS] #reset
	.D_CLK(clk25)						// in    [SYS] clock
);

xil_upscan upscan(
	.TXW_RED(TXW_RED[7:0]),				// in    [CRT] [7:0] red
	.TXW_GRN(TXW_GRN[7:0]),				// in    [CRT] [7:0] green
	.TXW_BLU(TXW_BLU[7:0]),				// in    [CRT] [7:0] blue
	.TXW_HS(TXW_HS),					// in    [CRT] #hsync
	.TXW_VS(TXW_VS),					// in    [CRT] #vsync
	.TXW_DE(TXW_DE),					// 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(TX_CLK_IN)					// 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(TX_CLK_IN),					// in    [TX] clock
	.CLK_div2(clk65div2),				// in    [DVI] clk /2
	.CLK_div2x7(clk65div2x7),			// in    [DVI] clk /2x7 : lvds ddr
	.RESET_N(rst_n)						// in    [TX] #reset
);
*/
endmodule
