//------------------------------------------------------------------------------
//
//  agx20_disp_dp2_vga.v : displaport test module
//
//  LICENSE : "as-is"
//  TakeshiNagashima(T.NG) caramelgete@gmail.com
//------------------------------------------------------------------------------
//  2009/nov/30 release 0.0  
//  2010/jan/28 release 0.1  display timinig generate test
//  2011/jul/04 release 0.1a AGX20 Displayport Adapter Package
//
//------------------------------------------------------------------------------

//`define link_270M
`define tp_ex
//`define lane4
`define lane2
//`define lane1

module agx20_disp_dp2_vga(
`ifdef simulation
	input			CLK27IN,	// in    [SIM] 27MHz
	input			CLK162IN,	// in    [SIM] 162MHz
`else
`endif

	inout	[31:0]	EXA,		// inout [SYS] testpoint
	inout	[31:0]	EXB,		// inout [SYS] testpoint
	input			KEY0,		// in    [SYS] 
	input			KEY1,		// in    [SYS] 
	input			KEY2,		// in    [SYS] 
	input			KEY3,		// in    [SYS] 
	input	[3:0]	DIPSW,		// in    [SYS] 
	output	[7:0]	LEDG,		// out   [SYS] status
	output			LED_X4,		// out   [SYS] dp linkup tr1 ready
	output			LED_X1,		// out   [SYS] dp linkup tr2 ready
	output			LED_LINK,	// out   [SYS] dp linkup done

	input	[3:0]	RX_P,		// out   [DP] recieve x4 lane
	output	[3:0]	TX_P,		// out   [DP] transmit x4 lane
	inout			TX_SCL,		// inout [DP] aux tx out
	inout			TX_SDA,		// inout [DP] aux rx in
	input			TX_HPD,		// in    [DP] hpd
	inout			TX_DIR,		// inout [DP] aux dir tx/#rx
	input			CLK1,		// in    [SYS] clock 50MHz
	input			CLK2,		// in    [SYS] option
	inout			CLK3,		// inout [SYS] pll feedback
	inout			CLK4,		// inout [SYS] pll feedback
	input			SYSRST_N	// in    [SYS] #reset
);

	parameter	K237=9'b1_111_10111;
	parameter	K277=9'b1_111_11011;
	parameter	K280=9'b1_000_11100;
	parameter	K281=9'b1_001_11100;
	parameter	K282=9'b1_010_11100;
	parameter	K283=9'b1_011_11100;
	parameter	K284=9'b1_100_11100;
	parameter	K285=9'b1_101_11100;
	parameter	K286=9'b1_110_11100;
	parameter	K287=9'b1_111_11100;
	parameter	K297=9'b1_111_11101;
	parameter	K307=9'b1_111_11110;
	parameter	D102=9'b0_010_01010;
	parameter	D116=9'b0_110_01011;

	localparam	code_bs  =K285;	// defalut symbol blank start
	localparam	code_be  =K277;	// defalut symbol blank end
	localparam	code_ss  =K282;	// defalut symbol secondary start
	localparam	code_se  =K297;	// defalut symbol secondary end
	localparam	code_fs  =K307;	// defalut symbol fill start
	localparam	code_fe  =K237;	// defalut symbol fill end
	localparam	code_sr  =K280;	// defalut symbol scramble reset
	localparam	code_cpbs=K281;	// defalut symbol content protection bs
	localparam	code_cpsr=K283;	// defalut symbol content protection sr

	localparam	code_ebs =K285;	// enhanced symbol blank start
	localparam	code_ebe =K277;	// enhanced symbol blank end
	localparam	code_ess =K282;	// enhanced symbol secondary start
	localparam	code_ese =K297;	// enhanced symbol secondary end
	localparam	code_efs =K307;	// enhanced symbol fill start
	localparam	code_efe =K237;	// enhanced symbol fill end
	localparam	code_esr =K280;	// enhanced symbol scramble reset
	localparam	code_ecp =K281;	// enhanced symbol content protection
	localparam	code_ebf =K283;	// enhanced symbol 

	wire	CLK27;
	wire	GXB162;
	wire	CLK162;
	wire	CLK135;
	wire	CLK270;
	wire	CLK50;
	wire	RST_N;

	// ---- clock gen ----

	wire	PLL27;
	wire	PLL162;

	wire	CLK3FB;
	wire	CLK4FB;

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

	assign CLK50=CLK1;

	assign RST_N=SYSRST_N;

`ifdef simulation

	assign PLL27=CLK27IN;
	assign PLL162=CLK162IN;

`else

alt_pll_50x27x162 pll_50x27x162 (
	.areset(1'b0),
	.inclk0(CLK1),
	.c0(PLL27),
	.c1(PLL162),
	.locked(locked0)
);

`endif

	assign CLK27=CLK3FB;
	assign CLK162=CLK4FB;

alt_ddio_bidir clk3_bidir(
	.aclr(1'b0),
	.datain_h(1'b1),
	.datain_l(1'b0),
	.inclock(PLL27),
	.oe(1'b1),
	.outclock(PLL27),
	.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(PLL162),
	.oe(1'b1),
	.outclock(PLL162),
	.combout(CLK4FB),
	.dataout_h(),
	.dataout_l(),
	.padio(CLK4)
);

	// ---- aux link ----

	wire	aux_data_tx;
	wire	aux_data_rx;
	wire	aux_data_oe;

	assign TX_SDA=1'bz;
	assign TX_SCL=aux_data_tx;
	assign TX_DIR=aux_data_oe;
	assign aux_data_rx=TX_SDA;

	wire	link_done;
	wire	link_err;
	wire	link_main_active;
	wire	[2:0] link_main_mode;
	wire	[7:0] link_unit;

	wire	link_aux_cmd_req;
	wire	[2:0] link_aux_cmd;
	wire	link_aux_cmd_done;
	wire	[3:0] link_aux_stat_tr1;
	wire	[3:0] link_aux_stat_tr2;
	wire	link_aux_stat_irq1;

	wire	link_aux_tx_req;
	wire	link_aux_tx_ack;
	wire	link_aux_tx_done;
	wire	[3:0] link_aux_tx_cmd;
	wire	[19:0] link_aux_tx_addr;
	wire	[7:0] link_aux_tx_len;
	wire	[7:0] link_aux_tx_data;
	wire	link_aux_tx_i2c_ao;
	wire	link_aux_tx_data_req;
	wire	[19:0] link_aux_tx_select;

	wire	[7:0] link_aux_rx_cmd;
	wire	[7:0] link_aux_rx_data;
	wire	link_aux_rx_cmd_ack;
	wire	link_aux_rx_data_ack;
	wire	link_aux_rx_sync;
	wire	link_aux_rx_stop;
	wire	link_aux_rx_done;

	assign LED_X4=(link_aux_stat_tr1[1:0]==2'b11) ? 1'b0 : 1'b1;
	assign LED_X1=(link_aux_stat_tr2[1:0]==2'b11) ? 1'b0 : 1'b1;
	assign LED_LINK=(link_done==1'b1) ? 1'b0 : 1'b1;

`ifdef lane1	// linkup x1
dp_main_linkup1 dp_main_linkup(
`else
`ifdef lane2	// linkup x2
dp_main_linkup2 dp_main_linkup(
`else			// linkup x4
dp_main_linkup dp_main_linkup(
`endif
`endif
	.TX_HPD(TX_HPD),								// in    [LINKUP] sink active

	.link_done(link_done),							// out   [LINKUP] linkup done
	.link_err(link_err),							// out   [LINKUP] linkup error
	.link_main_active(link_main_active),			// out   [LINKUP] transmitter active
	.link_main_mode(link_main_mode[2:0]),			// out   [LINKUP] transmit 00=idle/01=normal/10=tr1/11=tr2
	.link_unit(link_unit[7:0]),						// out   [LINKUP] unit size[7:0]

	.link_aux_cmd_req(link_aux_cmd_req),			// out   [LINKUP] linkup command req
	.link_aux_cmd(link_aux_cmd[2:0]),				// out   [LINKUP] linkup command[2:0]
	.link_aux_cmd_done(link_aux_cmd_done),			// out   [LINKUP] linkup command done
	.link_aux_stat_tr1(link_aux_stat_tr1[3:0]),		// out   [LINKUP] linkup tr1 status
	.link_aux_stat_tr2(link_aux_stat_tr2[3:0]),		// out   [LINKUP] linkup tr2 status
	.link_aux_stat_irq1(link_aux_stat_irq1),		// out   [LINKUP] device service irq vector bit1

	.link_aux_tx_req(link_aux_tx_req),				// out   [AUX] send request
	.link_aux_tx_ack(link_aux_tx_ack),				// in    [AUX] send acknowredge
	.link_aux_tx_done(link_aux_tx_done),			// in    [AUX] send done
	.link_aux_tx_cmd(link_aux_tx_cmd[3:0]),			// out   [AUX] send command
	.link_aux_tx_addr(link_aux_tx_addr[19:0]),		// out   [AUX] send addr
	.link_aux_tx_len(link_aux_tx_len[7:0]),			// out   [AUX] send data length
	.link_aux_tx_data(link_aux_tx_data[7:0]),		// out   [AUX] send data
	.link_aux_tx_i2c_ao(link_aux_tx_i2c_ao),		// out   [AUX] send i2c adress-only

	.link_aux_rx_cmd(link_aux_rx_cmd[7:0]),			// in    [AUX] recieve ack
	.link_aux_rx_data(link_aux_rx_data[7:0]),		// in    [AUX] recieve data
	.link_aux_rx_cmd_ack(link_aux_rx_cmd_ack),		// in    [AUX] recieve cmd acknowredge
	.link_aux_rx_data_ack(link_aux_rx_data_ack),	// in    [AUX] recieve data acknowredge
	.link_aux_rx_done(link_aux_rx_done),			// in    [AUX] recieve done

	.clk27(CLK27),									// in    [AUX] clk 27MHz
	.rst_n(RST_N)									// in    [AUX] #reset
);

dp_aux_tx aux_tx(
	.aux_tx(aux_data_tx),							// out   [AUX] dp aux_tx
	.aux_oe(aux_data_oe),							// out   [AUX] dp aux_tx oe
	.aux_req(link_aux_tx_req),						// in    [AUX] send request
	.aux_ack(link_aux_tx_ack),						// out   [AUX] send acknowredge
	.aux_done(link_aux_tx_done),					// out   [AUX] send done
	.aux_cmd(link_aux_tx_cmd[3:0]),					// in    [AUX] send command
	.aux_addr(link_aux_tx_addr[19:0]),				// in    [AUX] send addr
	.aux_len(link_aux_tx_len[7:0]),					// in    [AUX] send data length
	.aux_data(link_aux_tx_data[7:0]),				// in    [AUX] send data
	.aux_i2c_ao(link_aux_tx_i2c_ao),				// in    [AUX] send i2c adress-only
	.aux_data_req(link_aux_tx_data_req),			// out   [AUX] send data request
	.aux_select(link_aux_tx_select[19:0]),			// out   [AUX] data addr
	.clk27(CLK27),									// in    [AUX] clk 27MHz
	.rst_n(RST_N)									// in    [AUX] #reset
);

dp_aux_rx aux_rx(
	.aux_rx(aux_data_rx),							// in    [AUX] dp aux_rx
	.aux_oe(aux_data_oe),							// in    [AUX] dp aux send/#recieve
	.aux_cmd(link_aux_rx_cmd[7:0]),					// out   [AUX] recieve ack
	.aux_data(link_aux_rx_data[7:0]),				// out   [AUX] recieve data
	.aux_cmd_ack(link_aux_rx_cmd_ack),				// out   [AUX] recieve cmd acknowredge
	.aux_data_ack(link_aux_rx_data_ack),			// out   [AUX] recieve data acknowredge
	.aux_sync(link_aux_rx_sync),					// out   [AUX] recieve sync
	.aux_stop(link_aux_rx_stop),					// out   [AUX] recieve stop
	.aux_done(link_aux_rx_done),					// out   [AUX] recieve done
	.clk27(CLK27),									// in    [AUX] clk 27MHz
	.rst_n(RST_N)									// in    [AUX] #reset
);

	wire	[7:0] TX_RED;
	wire	[7:0] TX_GRN;
	wire	[7:0] TX_BLU;
	wire	TX_HS;
	wire	TX_VS;
	wire	TX_DE;
	wire	TX_CLK;

	// ---- main link : tbc ----

	wire	[23:0] dp_mvid;
	wire	[23:0] dp_nvid;
	wire	[7:0] dp_maud;
	wire	[15:0] dp_htotal;
	wire	[15:0] dp_vtotal;
	wire	[15:0] dp_hstart;
	wire	[15:0] dp_vstart;
	wire	[15:0] dp_hwidth;
	wire	[15:0] dp_vheight;
	wire	[15:0] dp_hsync;
	wire	[15:0] dp_vsync;
	wire	[7:0] dp_misc0;
	wire	[7:0] dp_misc1;

	wire	[8:0] tbc_data0;
	wire	[8:0] tbc_data1;
	wire	[8:0] tbc_data2;
	wire	[8:0] tbc_data3;

`ifdef lane1	// linkup x1
dp_main_crtc1 dp_main_crtc(
`else
`ifdef lane2	// linkup x2
dp_main_crtc2 dp_main_crtc(
`else			// linkup x4
dp_main_crtc dp_main_crtc(
`endif
`endif
	.TX_RED(TX_RED[7:0]),				// out   [CRTC] red[7:0]
	.TX_GRN(TX_GRN[7:0]),				// out   [CRTC] grn[7:0]
	.TX_BLU(TX_BLU[7:0]),				// out   [CRTC] blu[7:0]
	.TX_HS(TX_HS),						// out   [CRTC] hsync
	.TX_VS(TX_VS),						// out   [CRTC] vsync
	.TX_DE(TX_DE),						// out   [CRTC] de/#blank
	.TX_CLK(TX_CLK),					// out   [CRTC] pixel clock

	.dp_mvid(dp_mvid[23:0]),			// in    [CRTC] mvid[23:0]
	.dp_nvid(dp_nvid[23:0]),			// in    [CRTC] nvid[23:0]
	.dp_maud(dp_maud[7:0]),				// in    [CRTC] maud[7:0]
	.dp_htotal(dp_htotal[15:0]),		// in    [CRTC] htotal[15:0]
	.dp_vtotal(dp_vtotal[15:0]),		// in    [CRTC] vtotal[15:0]
	.dp_hstart(dp_hstart[15:0]),		// in    [CRTC] hstart[15:0]
	.dp_vstart(dp_vstart[15:0]),		// in    [CRTC] vstart[15:0]
	.dp_hwidth(dp_hwidth[15:0]),		// in    [CRTC] hwidth[15:0]
	.dp_vheight(dp_vheight[15:0]),		// in    [CRTC] vheight[15:0]
	.dp_hsync(dp_hsync[15:0]),			// in    [CRTC] hsync[15:0] ({hs_pol,hs_wid[14:0]})
	.dp_vsync(dp_vsync[15:0]),			// in    [CRTC] vsync[15:0] ({vs_pol,vs_wid[14:0]})
	.dp_misc0(dp_misc0[7:0]),			// in    [CRTC] misc0[7:0]
	.dp_misc1(dp_misc1[7:0]),			// in    [CRTC] misc1[7:0]
/*
	.tbc_data0(tbc_data0[8:0]),			// out   [TBC] data0[8:0]
	.tbc_data1(tbc_data1[8:0]),			// out   [TBC] data1[8:0]
	.tbc_data2(tbc_data2[8:0]),			// out   [TBC] data2[8:0]
	.tbc_data3(tbc_data3[8:0]),			// out   [TBC] data3[8:0]
*/
	.tbc_data0(),						// out   [TBC] data0[8:0]
	.tbc_data1(),						// out   [TBC] data1[8:0]
	.tbc_data2(),						// out   [TBC] data2[8:0]
	.tbc_data3(),						// out   [TBC] data3[8:0]

	.CLK(GXB162),						// in    [MAIN] system clock
	.SYSRST_N(RST_N)					// in    [MAIN] #reset
);

	wire	[7:0] D_RED;
	wire	[7:0] D_GRN;
	wire	[7:0] D_BLU;
	wire	D_HS;
	wire	D_VS;
	wire	D_DE;

dispgen dispgen(
	.D_RED(D_RED[7:0]),					// out   [CRT] [7:0] red
	.D_GRN(D_GRN[7:0]),					// out   [CRT] [7:0] green
	.D_BLU(D_BLU[7:0]),					// out   [CRT] [7:0] blue
	.D_HS(D_HS),						// out   [CRT] #hsync
	.D_VS(D_VS),						// out   [CRT] #vsync
	.D_DE(D_DE),						// out   [CRT] #blank

	.TX_HS(TX_HS),						// in    [CRT] #hsync
	.TX_VS(TX_VS),						// in    [CRT] #vsync
	.TX_DE(TX_DE),						// in    [CRT] #blank
	.TX_CLK(TX_CLK),					// in    [CRT] dot clock

	.RST_N(RST_N),						// in    [CRT] : #reset
	.CLK(GXB162)						// in    [CRT] dot clock
);

`ifdef lane1	// linkup x1
dp_main_tbc1 dp_main_tbc(
`else
`ifdef lane2	// linkup x2
dp_main_tbc2 dp_main_tbc(
`else			// linkup x4
dp_main_tbc dp_main_tbc(
`endif
`endif
	.TX_RED(D_RED[7:0]),				// in    [CRTC] red[7:0]
	.TX_GRN(D_GRN[7:0]),				// in    [CRTC] grn[7:0]
	.TX_BLU(D_BLU[7:0]),				// in    [CRTC] blu[7:0]
	.TX_HS(D_HS),						// in    [CRTC] hsync
	.TX_VS(D_VS),						// in    [CRTC] vsync
	.TX_DE(D_DE),						// in    [CRTC] de/#blank
	.TX_CLK(TX_CLK),					// in    [CRTC] pixel clock
/*
	.TX_RED(8'b0),				// in    [CRTC] red[7:0]
	.TX_GRN(8'b0),				// in    [CRTC] grn[7:0]
	.TX_BLU(8'b0),				// in    [CRTC] blu[7:0]
	.TX_HS(TX_HS),						// in    [CRTC] hsync
	.TX_VS(TX_VS),						// in    [CRTC] vsync
	.TX_DE(TX_DE),						// in    [CRTC] de/#blank
	.TX_CLK(TX_CLK),					// in    [CRTC] pixel clock
*/
	.dp_mvid(dp_mvid[23:0]),			// in    [TBC] mvid[23:0]
	.dp_nvid(dp_nvid[23:0]),			// in    [TBC] nvid[23:0]
	.dp_maud(dp_maud[7:0]),				// in    [TBC] maud[7:0]
	.dp_htotal(dp_htotal[15:0]),		// in    [TBC] htotal[15:0]
	.dp_vtotal(dp_vtotal[15:0]),		// in    [TBC] vtotal[15:0]
	.dp_hstart(dp_hstart[15:0]),		// in    [TBC] hstart[15:0]
	.dp_vstart(dp_vstart[15:0]),		// in    [TBC] vstart[15:0]
	.dp_hwidth(dp_hwidth[15:0]),		// in    [TBC] hwidth[15:0]
	.dp_vheight(dp_vheight[15:0]),		// in    [TBC] vheight[15:0]
	.dp_hsync(dp_hsync[15:0]),			// in    [TBC] hsync[15:0] ({hs_pol,hs_wid[14:0]})
	.dp_vsync(dp_vsync[15:0]),			// in    [TBC] vsync[15:0] ({vs_pol,vs_wid[14:0]})
	.dp_misc0(dp_misc0[7:0]),			// in    [TBC] misc0[7:0]
	.dp_misc1(dp_misc1[7:0]),			// in    [TBC] misc1[7:0]

	.tbc_data0(tbc_data0[8:0]),			// out   [TBC] data0[8:0]
	.tbc_data1(tbc_data1[8:0]),			// out   [TBC] data1[8:0]
	.tbc_data2(tbc_data2[8:0]),			// out   [TBC] data2[8:0]
	.tbc_data3(tbc_data3[8:0]),			// out   [TBC] data3[8:0]
/*
	.tbc_data0(),						// out   [TBC] data0[8:0]
	.tbc_data1(),						// out   [TBC] data1[8:0]
	.tbc_data2(),						// out   [TBC] data2[8:0]
	.tbc_data3(),						// out   [TBC] data3[8:0]
*/
	.CLK(GXB162),						// in    [MAIN] system clock
	.SYSRST_N(RST_N)					// in    [MAIN] #reset
);

	// ---- main link : pixel pack ----


	wire	[35:0] pack_data;
	wire	pack_rd;

	// 640x480 25.175MHz

`ifdef sim_fast

	assign dp_mvid[23:0]=24'h001554;			// strm_clk=27,ls_clk=162
	assign dp_nvid[23:0]=24'h008000;			// M:N=STRM_CLK:LS_CLK
	assign dp_maud[7:0]=8'b0;
	assign dp_htotal[15:0]=16'h0320;		// 800 : HOR TOTAL
	assign dp_vtotal[15:0]=16'h0018;		// 525 : VER TOTAL
	assign dp_hstart[15:0]=16'h0090;		// 144 : HOR SYNC + BACK PORCH
	assign dp_vstart[15:0]=16'h0006;		// 35  : VER SYNC + BACK PORCH
	assign dp_hwidth[15:0]=16'h0280;		// 640 : HOR
	assign dp_vheight[15:0]=16'h0010;		// 480 : VER
	assign dp_hsync[15:0]=16'h0060;			// high,96 : HOR SYNC
	assign dp_vsync[15:0]=16'h0002;			// high,2  : VER SYNC
	assign dp_misc0[7:0]=8'b001_0_0_00_1;	// 8bit,-,vesa,rgb,sync
	assign dp_misc1[7:0]=8'b00000_00_0;		// ,,

`else

`ifdef link_270M
	assign dp_mvid[23:0]=24'h000ccc;		// strm_clk=27,ls_clk=270
	assign dp_nvid[23:0]=24'h008000;		// M:N=STRM_CLK:LS_CLK
`else
	assign dp_mvid[23:0]=24'h001554;		// strm_clk=27,ls_clk=162
	assign dp_nvid[23:0]=24'h008000;		// M:N=STRM_CLK:LS_CLK
`endif
	assign dp_maud[7:0]=8'b0;
	assign dp_htotal[15:0]=16'h0320;		// 800 : HOR TOTAL
	assign dp_vtotal[15:0]=16'h020d;		// 525 : VER TOTAL
	assign dp_hstart[15:0]=16'h0090;		// 144 : HOR SYNC + BACK PORCH
	assign dp_vstart[15:0]=16'h0023;		// 35  : VER SYNC + BACK PORCH
	assign dp_hwidth[15:0]=16'h0280;		// 640 : HOR
	assign dp_vheight[15:0]=16'h01e0;		// 480 : VER
	assign dp_hsync[15:0]=16'h0060;			// high,96 : HOR SYNC
	assign dp_vsync[15:0]=16'h0002;			// high,2  : VER SYNC
//	assign dp_misc0[7:0]=8'b000_0_0_00_0;	// 6bit,-,vesa,rgb,async
	assign dp_misc0[7:0]=8'b001_0_0_00_0;	// 8bit,-,vesa,rgb,async
	assign dp_misc1[7:0]=8'b00000_00_0;		// ,,
`endif

	// ---- main link : scramble ----

	wire	[1:0] dp_main_mode;
	wire	dp_main_scr;

	wire	[9:0] sc_enc0_8b10b;
	wire	[9:0] sc_enc1_8b10b;
	wire	[9:0] sc_enc2_8b10b;
	wire	[9:0] sc_enc3_8b10b;

	wire	[8:0] sc_raw0;
	wire	[8:0] sc_raw1;
	wire	[8:0] sc_raw2;
	wire	[8:0] sc_raw3;

	wire	[8:0] sc_data0;
	wire	[8:0] sc_data1;
	wire	[8:0] sc_data2;
	wire	[8:0] sc_data3;
	wire	[1:0] sc_disp0;
	wire	[1:0] sc_disp1;
	wire	[1:0] sc_disp2;
	wire	[1:0] sc_disp3;

	assign dp_main_mode[1:0]=link_main_mode[1:0];
	assign dp_main_scr=link_main_mode[2];

dp_main_scramble dp_main_scramble(
	.dp_main_mode(dp_main_mode[1:0]),	// in    [SCR] link 00=idle/01=disp/10=tr1/11=tr2
	.dp_main_scr(dp_main_scr),			// in    [SCR] data scramble on=1/off=0

	.pack_data0(tbc_data0[8:0]),		// in    [PACK] data0
	.pack_data1(tbc_data1[8:0]),		// in    [PACK] data1
	.pack_data2(tbc_data2[8:0]),		// in    [PACK] data2
	.pack_data3(tbc_data3[8:0]),		// in    [PACK] data3

	.sc_enc0(sc_enc0_8b10b[9:0]),		// out   [SCR] encoded data0[8:0]
	.sc_enc1(sc_enc1_8b10b[9:0]),		// out   [SCR] encoded data1[8:0]
	.sc_enc2(sc_enc2_8b10b[9:0]),		// out   [SCR] encoded data2[8:0]
	.sc_enc3(sc_enc3_8b10b[9:0]),		// out   [SCR] encoded data3[8:0]

	.sc_data0(sc_data0[8:0]),			// out   [SCR] transfer data0[8:0]
	.sc_data1(sc_data1[8:0]),			// out   [SCR] transfer data1[8:0]
	.sc_data2(sc_data2[8:0]),			// out   [SCR] transfer data2[8:0]
	.sc_data3(sc_data3[8:0]),			// out   [SCR] transfer data3[8:0]
	.sc_disp0(sc_disp0[1:0]),			// out   [SCR] transfer disp0[1:0]
	.sc_disp1(sc_disp1[1:0]),			// out   [SCR] transfer disp1[1:0]
	.sc_disp2(sc_disp2[1:0]),			// out   [SCR] transfer disp2[1:0]
	.sc_disp3(sc_disp3[1:0]),			// out   [SCR] transfer disp3[1:0]

	.sc_raw0(sc_raw0[8:0]),				// out   [SCR] raw data0[8:0]
	.sc_raw1(sc_raw1[8:0]),				// out   [SCR] raw data1[8:0]
	.sc_raw2(sc_raw2[8:0]),				// out   [SCR] raw data2[8:0]
	.sc_raw3(sc_raw3[8:0]),				// out   [SCR] raw data3[8:0]

	.CLK(GXB162),						// in    [MAIN] system clock
	.SYSRST_N(RST_N)					// in    [MAIN] #reset
);


`ifdef sim_no_phy

	assign GXB162=CLK162;

	assign TX_P[0]=1'b0;
	assign TX_P[1]=1'b0;
	assign TX_P[2]=1'b0;
	assign TX_P[3]=1'b0;

`else

	wire	cal_blk_clk;
	wire	gxb_enable;
	wire	gxb_powerdown;
	wire	pll_inclk;
	wire	[3:0] tx_coreclk;
	wire	[3:0] tx_ctrlenable;
	wire	[31:0] tx_datain;
	wire	[9:0] tx_encin;
	wire	[3:0] tx_digitalreset;
	wire	[3:0] tx_dispval;
	wire	[3:0] tx_forcedisp;
//	wire	pll_locked;
	wire	[3:0] tx_clkout;
	wire	[3:0] tx_dataout;

	assign cal_blk_clk=CLK50;
	assign gxb_enable=1'b1;
	assign gxb_powerdown=1'b0;
	assign pll_inclk=CLK162;
	assign tx_coreclk[3:0]=tx_clkout[3:0];
	assign tx_digitalreset[0]=1'b0;

	assign tx_encin[9:0]=sc_enc0_8b10b[9:0];

	assign tx_ctrlenable[0]=sc_data0[8];
	assign tx_ctrlenable[1]=sc_data1[8];
	assign tx_ctrlenable[2]=sc_data2[8];
	assign tx_ctrlenable[3]=sc_data3[8];
	assign tx_datain[7:0]=sc_data0[7:0];
	assign tx_datain[15:8]=sc_data1[7:0];
	assign tx_datain[23:16]=sc_data2[7:0];
	assign tx_datain[31:24]=sc_data3[7:0];
	assign tx_dispval[0]=sc_disp0[0];
	assign tx_dispval[1]=sc_disp1[0];
	assign tx_dispval[2]=sc_disp2[0];
	assign tx_dispval[3]=sc_disp3[0];
	assign tx_forcedisp[0]=sc_disp0[1];
	assign tx_forcedisp[1]=sc_disp1[1];
	assign tx_forcedisp[2]=sc_disp2[1];
	assign tx_forcedisp[3]=sc_disp3[1];

	assign GXB162=tx_clkout[0];

`ifdef lane4

alt_alt2gxb_tx4 alt2gxb_tx (
	.cal_blk_clk(cal_blk_clk),
	.gxb_enable(gxb_enable),
	.gxb_powerdown(gxb_powerdown),
	.pll_inclk(pll_inclk),
	.tx_ctrlenable(tx_ctrlenable[3:0]),
	.tx_datain(tx_datain[31:0]),
	.tx_digitalreset(tx_digitalreset[3:0]),
	.tx_dispval(tx_dispval[3:0]),
	.tx_forcedisp(tx_forcedisp[3:0]),
	.pll_locked(pll_locked),
	.tx_clkout(tx_clkout[3:0]),
	.tx_dataout(TX_P[3:0])
);

`else

alt_alt2gxb_tx2 alt2gxb_tx (
	.cal_blk_clk(cal_blk_clk),
	.gxb_enable(gxb_enable),
	.gxb_powerdown(gxb_powerdown),
	.pll_inclk(pll_inclk),
	.tx_ctrlenable(tx_ctrlenable[1:0]),
	.tx_datain(tx_datain[15:0]),
	.tx_digitalreset(tx_digitalreset[1:0]),
	.tx_dispval(tx_dispval[1:0]),
	.tx_forcedisp(tx_forcedisp[1:0]),
	.pll_locked(pll_locked),
	.tx_clkout(tx_clkout[1:0]),
	.tx_dataout(TX_P[1:0])
);

	assign TX_P[2]=1'bz;
	assign TX_P[3]=1'bz;

`endif

`endif

	// ---- condition display ----

`ifdef sim_fast

	assign LEDG[7:0]=8'b0;

`else

	reg		[31:0] GXB162_r;

	always @(posedge GXB162 or negedge RST_N)
	begin
		if (RST_N==1'b0)
			begin
				GXB162_r <= 32'b0;
			end
		else
			begin
				GXB162_r <= GXB162_r+32'b01;
			end
	end
/*
	assign LEDG[7]=GXB162_r[24];

	assign LEDG[0]=locked0;
	assign LEDG[1]=pll_locked;
	assign LEDG[2]=link_main_active;
	assign LEDG[3]=link_main_mode[0];
	assign LEDG[4]=link_main_mode[1];
	assign LEDG[5]=RST_N;
	assign LEDG[6]=SYSRST_N;
*/

	assign LEDG[0]=SYSRST_N;
	assign LEDG[1]=(link_main_mode[1:0]==2'b00) ? 1'b1 : 1'b0;
	assign LEDG[2]=(link_main_mode[1:0]==2'b10) ? 1'b1 : 1'b0;
	assign LEDG[3]=(link_main_mode[1:0]==2'b11) ? 1'b1 : 1'b0;
	assign LEDG[4]=(link_main_mode[1:0]==2'b01) ? 1'b1 : 1'b0;
	assign LEDG[5]=link_main_active;
	assign LEDG[6]=(link_aux_stat_tr2[1:0]==2'b11) ? 1'b1 : 1'b0;
	assign LEDG[7]=link_done;

`endif

	wire	[7:0] sc_stat;

	wire	[7:0] aux_txcmd;
	wire	[7:0] aux_txdata;
	wire	aux_txcmd_ack;
	wire	aux_txdata_ack;
	wire	aux_txsync;
	wire	aux_txstop;
	wire	aux_txdone;

dp_aux_rx aux_sink_rx(
	.aux_rx(aux_data_rx),				// in    [AUX] dp aux_rx
	.aux_oe(1'b0),						// in    [AUX] dp aux send/#recieve
	.aux_cmd(aux_txcmd[7:0]),			// out   [AUX] recieve ack
	.aux_data(aux_txdata[7:0]),			// out   [AUX] recieve data
	.aux_cmd_ack(aux_txcmd_ack),		// out   [AUX] recieve cmd acknowredge
	.aux_data_ack(aux_txdata_ack),		// out   [AUX] recieve data acknowredge
	.aux_sync(aux_txsync),				// out   [AUX] recieve sync
	.aux_stop(aux_txstop),				// out   [AUX] recieve stop
	.aux_done(aux_txdone),				// out   [AUX] recieve done
	.clk27(CLK27),						// in    [AUX] clk 27MHz
	.rst_n(RST_N)						// in    [AUX] #reset
);

	reg		[7:0] aux_txdata_r;

	always @(posedge CLK27 or negedge RST_N)
	begin
		if (RST_N==1'b0)
			begin
				aux_txdata_r[7:0] <= 8'b0;
			end
		else
			begin
				aux_txdata_r[7:0] <= 
					(aux_txcmd_ack==1'b1) ? aux_txcmd[7:0] :
					({aux_txcmd_ack,aux_txdata_ack}==2'b01) ? aux_txdata[7:0] :
					aux_txdata_r[7:0];
			end
	end


	wire	[15:0] sc_op_bs_out_w;
	wire	[15:0] sc_op_be_out_w;
	wire	[15:0] sc_op_sr_out_w;
	wire	[15:0] sc_op_ss_out_w;
	wire	[15:0] sc_op_fs_out_w;
	wire	[15:0] sc_op_fe_out_w;
	wire	sc_vs_out_w;
	wire	sc_de_out_w;
	wire	[15:0] sc_de_count_w;

	reg		[15:0] sc_op_bs_out_r;
	reg		[15:0] sc_op_be_out_r;
	reg		[15:0] sc_op_sr_out_r;
	reg		[15:0] sc_op_ss_out_r;
	reg		[15:0] sc_op_fs_out_r;
	reg		[15:0] sc_op_fe_out_r;
	reg		sc_vs_out_r;
	reg		sc_de_out_r;
	reg		[15:0] sc_de_count_r;

	wire	sc_op_bs;
	wire	sc_op_be;
	wire	sc_op_sr;
	wire	sc_op_ss;
	wire	sc_op_fs;
	wire	sc_op_fe;

	assign sc_op_bs=(sc_raw0[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_be=(sc_raw0[8:0]==code_be[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_sr=(sc_raw0[8:0]==code_sr[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_ss=(sc_raw0[8:0]==code_ss[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_fs=(sc_raw0[8:0]==code_fs[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_fe=(sc_raw0[8:0]==code_fe[8:0]) ? 1'b1 : 1'b0;

	always @(posedge GXB162 or negedge RST_N)
	begin
		if (RST_N==1'b0)
			begin
				sc_op_bs_out_r[15:0] <= 16'b0;
				sc_op_be_out_r[15:0] <= 16'b0;
				sc_op_sr_out_r[15:0] <= 16'b0;
				sc_op_ss_out_r[15:0] <= 16'b0;
				sc_op_fs_out_r[15:0] <= 16'b0;
				sc_op_fe_out_r[15:0] <= 16'b0;
				sc_vs_out_r <= 1'b0;
				sc_de_out_r <= 1'b0;
				sc_de_count_r[15:0] <= 16'b0;
			end
		else
			begin
				sc_op_bs_out_r[15:0] <= sc_op_bs_out_w[15:0];
				sc_op_be_out_r[15:0] <= sc_op_be_out_w[15:0];
				sc_op_sr_out_r[15:0] <= sc_op_sr_out_w[15:0];
				sc_op_ss_out_r[15:0] <= sc_op_ss_out_w[15:0];
				sc_op_fs_out_r[15:0] <= sc_op_fs_out_w[15:0];
				sc_op_fe_out_r[15:0] <= sc_op_fe_out_w[15:0];
				sc_vs_out_r <= sc_vs_out_w;
				sc_de_out_r <= sc_de_out_w;
				sc_de_count_r[15:0] <= sc_de_count_w[15:0];
			end
	end

	assign sc_op_bs_out_w[15:0]=(sc_op_bs==1'b1) ? 16'hffff : {sc_op_bs_out_r[14:0],1'b0};
	assign sc_op_be_out_w[15:0]=(sc_op_be==1'b1) ? 16'hffff : {sc_op_be_out_r[14:0],1'b0};
	assign sc_op_sr_out_w[15:0]=(sc_op_sr==1'b1) ? 16'hffff : {sc_op_sr_out_r[14:0],1'b0};
	assign sc_op_ss_out_w[15:0]=(sc_op_ss==1'b1) ? 16'hffff : {sc_op_ss_out_r[14:0],1'b0};
	assign sc_op_fs_out_w[15:0]=(sc_op_fs==1'b1) ? 16'hffff : {sc_op_fs_out_r[14:0],1'b0};
	assign sc_op_fe_out_w[15:0]=(sc_op_fe==1'b1) ? 16'hffff : {sc_op_fe_out_r[14:0],1'b0};
	assign sc_vs_out_w=
			(sc_op_be_out_r[0]==1'b1) ? 1'b0 :
			(sc_op_be_out_r[0]==1'b0) & (sc_op_bs_out_r[0]==1'b1) ? sc_raw0[0] :
			(sc_op_be_out_r[0]==1'b0) & (sc_op_bs_out_r[0]==1'b0) ? sc_vs_out_r :
			1'b0;

	assign sc_de_out_w=
			(sc_op_be==1'b1) ? 1'b1 :
			(sc_op_be==1'b0) &  ((sc_op_bs==1'b1) | (sc_op_sr==1'b1)) ? 1'b0 :
			(sc_op_be==1'b0) & !((sc_op_bs==1'b1) | (sc_op_sr==1'b1)) & (sc_op_fs==1'b1) ? 1'b0 :
			(sc_op_be==1'b0) & !((sc_op_bs==1'b1) | (sc_op_sr==1'b1)) & (sc_op_fs==1'b0) & (sc_op_fe==1'b1) ? 1'b1 :
			(sc_op_be==1'b0) & !((sc_op_bs==1'b1) | (sc_op_sr==1'b1)) & (sc_op_fs==1'b0) & (sc_op_fe==1'b0) ? sc_de_out_r :
			1'b0;
	assign sc_de_count_w[15:0]=
			(sc_op_be==1'b1) ? 16'b0 :
			(sc_op_be==1'b0) & (sc_de_out_r==1'b1) & (sc_raw0[8]==1'b0) ? sc_de_count_r[15:0]+16'b01 :
			(sc_op_be==1'b0) & (sc_de_out_r==1'b1) & (sc_raw0[8]==1'b1) ? sc_de_count_r[15:0] :
			(sc_op_be==1'b0) & (sc_de_out_r==1'b0) ? sc_de_count_r[15:0] :
			16'b0;

	assign sc_stat[0]=sc_op_be_out_r[3];
	assign sc_stat[1]=sc_op_bs_out_r[3] | sc_op_sr_out_r[3];
	assign sc_stat[2]=sc_op_sr_out_r[3];
	assign sc_stat[3]=sc_op_fs_out_r[3] | sc_op_fe_out_r[3];
	assign sc_stat[4]=sc_vs_out_r;
	assign sc_stat[5]=1'b0;
	assign sc_stat[6]=1'b0;
	assign sc_stat[7]=1'b0;

`ifdef tp_ex

/*
	assign EXA[8:0]=sc_data0[8:0];
	assign EXA[10:9]=sc_disp0[1:0];
	assign EXA[19:11]=sc_data1[8:0];
	assign EXA[21:20]=sc_disp1[1:0];
	assign EXB[8:0]=sc_data2[8:0];
	assign EXB[10:9]=sc_disp2[1:0];
	assign EXB[19:11]=sc_data3[8:0];
	assign EXB[21:20]=sc_disp3[1:0];
*/

/*
//	assign EXA[0]=aux_data_rx;
//	assign EXA[1]=aux_data_tx;
//	assign EXA[2]=aux_txcmd_ack;
//	assign EXA[3]=aux_txdata_ack;
//	assign EXA[4:2]=sc_stat[2:0];
//	assign EXA[4]=link_aux_stat_tr1;
//	assign EXA[5]=link_aux_stat_tr2;
//	assign EXA[6]=link_aux_stat_irq1;

	assign EXA[0]=aux_data_rx;
	assign EXA[1]=link_err;
	assign EXA[2]=link_done;

//	assign EXA[3]=link_aux_tx_req;
//	assign EXA[4]=(link_aux_tx_addr[19:0]==20'h0202) ? 1'b1 : 1'b0;
//	assign EXA[5]=(link_aux_tx_addr[19:0]==20'h0203) ? 1'b1 : 1'b0;
//	assign EXA[6]=(link_aux_tx_addr[19:0]==20'h0204) ? 1'b1 : 1'b0;
//	assign EXA[7]=(link_aux_tx_addr[19:0]==20'h0205) ? 1'b1 : 1'b0;

	assign EXA[3]=sc_stat[0];
	assign EXA[4]=sc_stat[1];
	assign EXA[5]=sc_stat[2];
	assign EXA[6]=sc_stat[3];
	assign EXA[7]=sc_stat[4];
	assign EXA[8]=aux_txdata_r[7];
	assign EXA[9]=aux_txdata_r[6];
	assign EXA[10]=aux_txdata_r[5];
	assign EXA[11]=aux_txdata_r[4];
	assign EXA[12]=aux_txdata_r[3];
	assign EXA[13]=aux_txdata_r[2];
	assign EXA[14]=aux_txdata_r[1];
	assign EXA[15]=aux_txdata_r[0];

	assign EXA[19:16]=4'bzzzz;
	assign EXA[23:20]=4'bzzzz;
	assign EXA[24]=1'bz;
	assign EXA[25]=TX_BLU[7];
	assign EXA[26]=TX_GRN[7];
	assign EXA[27]=TX_RED[7];
	assign EXA[28]=TX_HS;
	assign EXA[29]=TX_VS;
	assign EXA[30]=TX_DE;
	assign EXA[31]=TX_CLK;
*/

/*
	assign EXB[15:8]=4'bzzzz;
	assign EXB[7]=1'bz;
	assign EXB[6]=TX_BLU[7];
	assign EXB[5]=TX_GRN[7];
	assign EXB[4]=TX_RED[7];
	assign EXB[3]=TX_HS;
	assign EXB[2]=TX_VS;
	assign EXB[1]=TX_DE;
	assign EXB[0]=TX_CLK;
*/

	assign EXA[0]=aux_data_rx;
	assign EXA[1]=aux_data_tx;
	assign EXA[2]=aux_txcmd_ack;
	assign EXA[3]=aux_txdata_ack;
	assign EXA[4]=link_aux_stat_tr1[0];
	assign EXA[5]=link_aux_stat_tr2[0];
	assign EXA[6]=link_aux_stat_irq1;
	assign EXA[7]=link_done;
	assign EXA[8]=link_err;
	assign EXA[9]=link_main_active;
//	assign EXA[10]=link_main_mode[0];
//	assign EXA[11]=link_main_mode[1];
//	assign EXA[12]=link_main_mode[2];
//	assign EXA[13]=1'b0;
//	assign EXA[14]=1'b0;
//	assign EXA[15]=SYSRST_N;
	assign EXA[10]=link_aux_tx_req;
	assign EXA[11]=(link_aux_tx_addr[19:0]==20'h0102) ? 1'b1 : 1'b0;
	assign EXA[12]=(link_aux_tx_addr[19:0]==20'h0202) ? 1'b1 : 1'b0;
	assign EXA[13]=(link_aux_tx_addr[19:0]==20'h0203) ? 1'b1 : 1'b0;
	assign EXA[14]=(link_aux_tx_addr[19:0]==20'h0204) ? 1'b1 : 1'b0;
	assign EXA[15]=(link_aux_tx_addr[19:0]==20'h0205) ? 1'b1 : 1'b0;


`else

	assign EXA[31:0]=32'hzzzzzzzz;
	assign EXB[31:0]=32'hzzzzzzzz;

`endif

endmodule
