//------------------------------------------------------------------------------
//
//  alt_dvi.v : altera cyclone3 dvi output module
//
//  LICENSE : "as-is"
//  TakeshiNagashima(T.NG) caramelgete@gmail.com
//------------------------------------------------------------------------------
//  2009/jul/04 release 0.0  
//
//------------------------------------------------------------------------------

module alt_dvi(
	output			DVI_TX0,			// out   [DVI] lvds tx0-p : dvi tx0 out
	output			DVI_TX1,			// out   [DVI] lvds tx1-p : dvi tx1 out
	output			DVI_TX2,			// out   [DVI] lvds tx2-p : dvi tx2 out
	output			DVI_TXC,			// out   [DVI] lvds tx3-p : dvi clk out
	input	[7:0]	TX_RED,				// in    [DVI] [7:0] red
	input	[7:0]	TX_GRN,				// in    [DVI] [7:0] green
	input	[7:0]	TX_BLU,				// in    [DVI] [7:0] red
	input			TX_HS,				// in    [DVI] hsync
	input			TX_VS,				// in    [DVI] vsync
	input			TX_C0,				// in    [DVI] c0
	input			TX_C1,				// in    [DVI] c1
	input			TX_C2,				// in    [DVI] c2
	input			TX_C3,				// in    [DVI] c3
	input			TX_DE,				// in    [DVI] de/#blank
	input			CLK,				// in    [DVI] clk
	input			CLKx5,				// in    [DVI] clk x5 : dvi ddr
	input			RESET_N				// in    [DVI] #reset
);

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

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

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

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

	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_ch0_enc_out;
	wire	[9:0] dvi_ch1_enc_out;
	wire	[9:0] dvi_ch2_enc_out;

	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;

	always @(posedge CLK 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)					// 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)					// 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)					// in    [ENC] 
);

	assign dvi_ch0_enc_out[9:5]={dvi_ch0_enc[0],dvi_ch0_enc[1],dvi_ch0_enc[2],dvi_ch0_enc[3],dvi_ch0_enc[4]};
	assign dvi_ch0_enc_out[4:0]={dvi_ch0_enc[5],dvi_ch0_enc[6],dvi_ch0_enc[7],dvi_ch0_enc[8],dvi_ch0_enc[9]};
	assign dvi_ch1_enc_out[9:5]={dvi_ch1_enc[0],dvi_ch1_enc[1],dvi_ch1_enc[2],dvi_ch1_enc[3],dvi_ch1_enc[4]};
	assign dvi_ch1_enc_out[4:0]={dvi_ch1_enc[5],dvi_ch1_enc[6],dvi_ch1_enc[7],dvi_ch1_enc[8],dvi_ch1_enc[9]};
	assign dvi_ch2_enc_out[9:5]={dvi_ch2_enc[0],dvi_ch2_enc[1],dvi_ch2_enc[2],dvi_ch2_enc[3],dvi_ch2_enc[4]};
	assign dvi_ch2_enc_out[4:0]={dvi_ch2_enc[5],dvi_ch2_enc[6],dvi_ch2_enc[7],dvi_ch2_enc[8],dvi_ch2_enc[9]};

alt_dvi_out_x4_raw dvi_out_x4_raw(
	.tx_in({10'b1111100000,dvi_ch2_enc_out[9:0],dvi_ch1_enc_out[9:0],dvi_ch0_enc_out[9:0]}),
	.tx_inclock(CLKx5),
	.tx_syncclock(CLK),
	.tx_out({DVI_TXC,DVI_TX2,DVI_TX1,DVI_TX0})
);

endmodule
