//------------------------------------------------------------------------------
//
//  agx20_disp_dvi_hd.v : altera agx20 dvi output module
//
//  LICENSE : "as-is"
//  TakeshiNagashima(T.NG) caramelgete@gmail.com
//------------------------------------------------------------------------------
//  2010/jan/12 release 0.1  Interface Download Package
//  2011/jul/04 release 0.1a AGX20 Displayport Adapter Package
//
//------------------------------------------------------------------------------
//

module agx20_disp_dvi_hd(
	output	[3:0]	TX_P,			// out   [DVI] tx0,tx1,tx2,txc (lvds level)
	inout			TX_SCL,			// inout [DVI] ddc scl
	inout			TX_SDA,			// inout [DVI] ddc sda
	input			TX_HPD,			// in    [DVI] hpd input

	input			CLK1,			// in    [SYS] system clock 50MHz
	input			CLK2,			// in    [SYS] option clock input
	inout			CLK3,			// inout [SYS] clock feedbck
	inout			CLK4,			// inout [SYS] clock feedback
	input			SYSRST_N		// in    [SYS] #reset
);

	wire	CLK25;
	wire	CLK50;
	wire	CLK100;
	wire	CLK162;
	wire	CLK138;
	wire	RESET_N;

	wire	CLK3FB;
	wire	CLK4FB;

	wire	locked0;
	wire	locked1;
	wire	locked2;
	wire	locked3;
	wire	pll_locked;

	assign CLK50=CLK1;

	assign RESET_N=SYSRST_N;

	assign CLK162=1'b0;

//alt_pll_50x138 pll_50x138 (
alt_pll_50x137 pll_50x138 (
	.inclk0(CLK1),
	.c0(CLK138),
	.locked(locked0)
);

alt_ddio_bidir clk3_bidir(
	.aclr(1'b0),
	.datain_h(1'b1),
	.datain_l(1'b0),
	.inclock(CLK138),
	.oe(1'b1),
	.outclock(CLK138),
	.combout(CLK3FB),
	.dataout_h(),
	.dataout_l(),
	.padio(CLK3)
);

alt_ddio_bidir clk4_bidir(
	.aclr(1'b0),
	.datain_h(1'b1),
	.datain_l(1'b0),
	.inclock(CLK162),
	.oe(1'b1),
	.outclock(CLK162),
	.combout(CLK4FB),
	.dataout_h(),
	.dataout_l(),
	.padio(CLK4)
);

	// ---- gxb dvi out ----

	wire	clk_tx;

	reg		ch_de_r;
	reg		[9:0] dvi_ch0_r;
	reg		[9:0] dvi_ch1_r;
	reg		[9:0] dvi_ch2_r;

	wire	ch_de_w;
	wire	[9:0] dvi_ch0_w;
	wire	[9:0] dvi_ch1_w;
	wire	[9:0] dvi_ch2_w;

	wire	[9:0] dvi_ch0_enc;
	wire	[9:0] dvi_ch1_enc;
	wire	[9:0] dvi_ch2_enc;
	wire	[9:0] dvi_ch3_enc;

	wire	[9:0] dvi_ch0_enc_out;
	wire	[9:0] dvi_ch1_enc_out;
	wire	[9:0] dvi_ch2_enc_out;
	wire	[9:0] dvi_ch3_enc_out;

	wire	[7:0] TX_RED;
	wire	[7:0] TX_GRN;
	wire	[7:0] TX_BLU;
	wire	TX_HS;
	wire	TX_VS;
	wire	TX_C0;
	wire	TX_C1;
	wire	TX_C2;
	wire	TX_C3;
	wire	TX_DE;

	reg		[7:0] TX_RED_r;
	reg		[7:0] TX_GRN_r;
	reg		[7:0] TX_BLU_r;
	reg		TX_HS_r;
	reg		TX_VS_r;
	reg		TX_C0_r;
	reg		TX_C1_r;
	reg		TX_C2_r;
	reg		TX_C3_r;
	reg		TX_DE_r;

	assign TX_C0=1'b0;
	assign TX_C1=1'b0;
	assign TX_C2=1'b0;
	assign TX_C3=1'b0;

dispgen_hd disp(
	.D_RED(TX_RED),						// out   [CRT] [7:0] red
	.D_GRN(TX_GRN),						// out   [CRT] [7:0] green
	.D_BLU(TX_BLU),						// 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(RESET_N),					// in    [] : #reset
	.D_CLK(clk_tx)						// in    [CRT] dot clock
);

	always @(posedge clk_tx or negedge RESET_N)
	begin
		if (RESET_N==1'b0)
			begin
				TX_RED_r <= 8'h0;
				TX_GRN_r <= 8'h0;
				TX_BLU_r <= 8'h0;
				TX_HS_r <= 1'h0;
				TX_VS_r <= 1'h0;
				TX_C0_r <= 1'h0;
				TX_C1_r <= 1'h0;
				TX_C2_r <= 1'h0;
				TX_C3_r <= 1'h0;
				TX_DE_r <= 1'h0;
				ch_de_r <= 1'b0;
				dvi_ch0_r[9:0] <= 10'b0;
				dvi_ch1_r[9:0] <= 10'b0;
				dvi_ch2_r[9:0] <= 10'b0;
			end
		else
			begin
				TX_RED_r <= TX_RED;
				TX_GRN_r <= TX_GRN;
				TX_BLU_r <= TX_BLU;
				TX_HS_r <= TX_HS;
				TX_VS_r <= TX_VS;
				TX_C0_r <= TX_C0;
				TX_C1_r <= TX_C1;
				TX_C2_r <= TX_C2;
				TX_C3_r <= TX_C3;
				TX_DE_r <= TX_DE;
				ch_de_r <= ch_de_w;
				dvi_ch0_r[9:0] <= dvi_ch0_w[9:0];
				dvi_ch1_r[9:0] <= dvi_ch1_w[9:0];
				dvi_ch2_r[9:0] <= dvi_ch2_w[9:0];
			end
	end

	assign ch_de_w=TX_DE_r;
	assign dvi_ch0_w[9:0]={TX_VS_r,TX_HS_r,TX_BLU_r[7:0]};
	assign dvi_ch1_w[9:0]={TX_C1_r,TX_C0_r,TX_GRN_r[7:0]};
	assign dvi_ch2_w[9:0]={TX_C3_r,TX_C2_r,TX_RED_r[7:0]};

dvi_data_enc enc0(
	.ch_in(dvi_ch0_r[9:0]),		// in    [ENC] [9:0]
	.ch_de(ch_de_r),			// in    [ENC] 
	.ch_out(dvi_ch0_enc[9:0]),	// out   [ENC] [9:0]

	.rst_n(RESET_N),			// in    [ENC] 
	.clk(clk_tx)				// in    [ENC] 
);

dvi_data_enc enc1(
	.ch_in(dvi_ch1_r[9:0]),		// in    [ENC] [9:0]
	.ch_de(ch_de_r),			// in    [ENC] 
	.ch_out(dvi_ch1_enc[9:0]),	// out   [ENC] [9:0]

	.rst_n(RESET_N),			// in    [ENC] 
	.clk(clk_tx)				// in    [ENC] 
);

dvi_data_enc enc2(
	.ch_in(dvi_ch2_r[9:0]),		// in    [ENC] [9:0]
	.ch_de(ch_de_r),			// in    [ENC] 
	.ch_out(dvi_ch2_enc[9:0]),	// out   [ENC] [9:0]

	.rst_n(RESET_N),			// in    [ENC] 
	.clk(clk_tx)				// in    [ENC] 
);

	assign dvi_ch3_enc[9:0]=10'b0000011111;

	wire	[3:0] tx_clkout;

	assign clk_tx=tx_clkout[0];
	assign CLK100=tx_clkout[0];

alt_alt2gxb_x4 gxb_x4 (
	.cal_blk_clk( CLK50 ) ,
	.gxb_powerdown ( 1'b0 ),
	.pll_inclk ( CLK3FB ),
	.tx_datain ( {dvi_ch3_enc[9:0],dvi_ch0_enc[9:0],dvi_ch1_enc[9:0],dvi_ch2_enc[9:0]} ),
	.tx_digitalreset ( 4'b0000 ),
	.tx_clkout ( tx_clkout[3:0] ),
	.tx_dataout ( TX_P[3:0] )
	);

	assign TX_SCL=1'bz;
	assign TX_SDA=1'bz;

endmodule
