//------------------------------------------------------------------------------
//
//  dp_main_scramble.v : displaport main-link scramble module
//
//  LICENSE : "as-is"
//  TakeshiNagashima(T.NG) caramelgete@gmail.com
//------------------------------------------------------------------------------
//  2009/dec/17 release 0.0  
//  2010/jan/28 release 0.1  display timinig generate test
//
//------------------------------------------------------------------------------

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

	input	[8:0]	pack_data0,		// in    [PACK] data0[8:0]
	input	[8:0]	pack_data1,		// in    [PACK] data1[8:0]
	input	[8:0]	pack_data2,		// in    [PACK] data2[8:0]
	input	[8:0]	pack_data3,		// in    [PACK] data3[8:0]

	output	[9:0]	sc_enc0,		// out   [SCR] enc8b10b(data0)
	output	[9:0]	sc_enc1,		// out   [SCR] enc8b10b(data1)
	output	[9:0]	sc_enc2,		// out   [SCR] enc8b10b(data2)
	output	[9:0]	sc_enc3,		// out   [SCR] enc8b10b(data3)

	output	[8:0]	sc_data0,		// out   [SCR] transfer data0[8:0]
	output	[8:0]	sc_data1,		// out   [SCR] transfer data1[8:0]
	output	[8:0]	sc_data2,		// out   [SCR] transfer data2[8:0]
	output	[8:0]	sc_data3,		// out   [SCR] transfer data3[8:0]
	output	[1:0]	sc_disp0,		// out   [SCR] transfer force0,disp0
	output	[1:0]	sc_disp1,		// out   [SCR] transfer force1,disp1
	output	[1:0]	sc_disp2,		// out   [SCR] transfer force2,disp2
	output	[1:0]	sc_disp3,		// out   [SCR] transfer force3,disp3

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

	input			CLK,			// in    [MAIN] system clock
	input			SYSRST_N		// in    [MAIN] #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 

	localparam	dp_main_mode_idle=2'b00;	// 8k-bs/512-sr
	localparam	dp_main_mode_op  =2'b01;	// display on
	localparam	dp_main_mode_tr1 =2'b10;	// training 1 : clock recovery
	localparam	dp_main_mode_tr2 =2'b11;	// training 2 : channel eq

	wire	dp_main_dis;
	wire	dp_main_tr1;
	wire	dp_main_tr2;
	wire	dp_main_ilde;
	wire	dp_main_op;

	wire	sc_lfsr_reset0;
	wire	[7:0] sc_lfsr_out;

	wire	[10:0] sc_data0_dly;
	wire	[10:0] sc_data1_dly;
	wire	[10:0] sc_data2_dly;
	wire	[10:0] sc_data3_dly;

	wire	[9:0] sc_data0_out_w;
	wire	[9:0] sc_data1_out_w;
	wire	[9:0] sc_data2_out_w;
	wire	[9:0] sc_data3_out_w;
	wire	[10:0] sc_data0_out0_w;
	wire	sc_data0_out0_sr_w;
	wire	[10:0] sc_data1_out0_w;
	wire	[10:0] sc_data2_out0_w;
	wire	[10:0] sc_data3_out0_w;
	wire	[10:0] sc_data0_out1_w;
	wire	[10:0] sc_data1_out1_w;
	wire	[10:0] sc_data2_out1_w;
	wire	[10:0] sc_data3_out1_w;
	wire	[10:0] sc_data0_out2_w;
	wire	[10:0] sc_data1_out2_w;
	wire	[10:0] sc_data2_out2_w;
	wire	[10:0] sc_data3_out2_w;
	wire	[10:0] sc_data1_dl1_w;
	wire	[10:0] sc_data2_dl1_w;
	wire	[10:0] sc_data3_dl1_w;
	wire	[10:0] sc_data2_dl2_w;
	wire	[10:0] sc_data3_dl2_w;
	wire	[10:0] sc_data3_dl3_w;
	wire	[3:0] sc_disp_out_w;
	wire	[10:0] sc_tr_data_out_w;
	wire	[3:0] sc_tr_count_w;
	wire	[10:0] sc_no_data_out_w;
	wire	[8:0] pack_data0_in_w;
	wire	[8:0] pack_data1_in_w;
	wire	[8:0] pack_data2_in_w;
	wire	[8:0] pack_data3_in_w;
	wire	pack_data0_in_bs_w;
	wire	pack_data1_in_bs_w;
	wire	pack_data2_in_bs_w;
	wire	pack_data3_in_bs_w;
	wire	[10:0] sc_op_data0_out_w;
	wire	[10:0] sc_op_data1_out_w;
	wire	[10:0] sc_op_data2_out_w;
	wire	[10:0] sc_op_data3_out_w;
	wire	[11:0] sc_op_count_w;
	wire	[11:0] sc_op_size_w;
	wire	[12:0] sc_no_count_w;
	wire	[8:0] sc_no_count_8k_w;
	wire	sc_no_8k_w;
	wire	sc_no_8k512_w;
	wire	[8:0] sc_op_count_512_w;
	wire	sc_op_512_w;

	reg		[9:0] sc_data0_out_r;
	reg		[9:0] sc_data1_out_r;
	reg		[9:0] sc_data2_out_r;
	reg		[9:0] sc_data3_out_r;
	reg		[10:0] sc_data0_out0_r;
	reg		sc_data0_out0_sr_r;
	reg		[10:0] sc_data1_out0_r;
	reg		[10:0] sc_data2_out0_r;
	reg		[10:0] sc_data3_out0_r;
	reg		[10:0] sc_data0_out1_r;
	reg		[10:0] sc_data1_out1_r;
	reg		[10:0] sc_data2_out1_r;
	reg		[10:0] sc_data3_out1_r;
	reg		[10:0] sc_data0_out2_r;
	reg		[10:0] sc_data1_out2_r;
	reg		[10:0] sc_data2_out2_r;
	reg		[10:0] sc_data3_out2_r;
	reg		[10:0] sc_data1_dl1_r;
	reg		[10:0] sc_data2_dl1_r;
	reg		[10:0] sc_data3_dl1_r;
	reg		[10:0] sc_data2_dl2_r;
	reg		[10:0] sc_data3_dl2_r;
	reg		[10:0] sc_data3_dl3_r;
	reg		[10:0] sc_tr_data_out_r;
	reg		[3:0] sc_tr_count_r;
	reg		[10:0] sc_no_data_out_r;
	reg		[8:0] pack_data0_in_r;
	reg		[8:0] pack_data1_in_r;
	reg		[8:0] pack_data2_in_r;
	reg		[8:0] pack_data3_in_r;
	reg		pack_data0_in_bs_r;
	reg		pack_data1_in_bs_r;
	reg		pack_data2_in_bs_r;
	reg		pack_data3_in_bs_r;
	reg		[10:0] sc_op_data0_out_r;
	reg		[10:0] sc_op_data1_out_r;
	reg		[10:0] sc_op_data2_out_r;
	reg		[10:0] sc_op_data3_out_r;
	reg		[11:0] sc_op_count_r;
	reg		[11:0] sc_op_size_r;
	reg		[12:0] sc_no_count_r;
	reg		[8:0] sc_no_count_8k_r;
	reg		sc_no_8k_r;
	reg		sc_no_8k512_r;
	reg		[8:0] sc_op_count_512_r;
	reg		sc_op_512_r;

	wire	[9:0] sc_enc0_out;
	wire	[9:0] sc_enc1_out;
	wire	[9:0] sc_enc2_out;
	wire	[9:0] sc_enc3_out;

	assign sc_data0_dly[10:0]=sc_data0_out2_r[10:0];
	assign sc_data1_dly[10:0]=sc_data1_dl1_r[10:0];
	assign sc_data2_dly[10:0]=sc_data2_dl2_r[10:0];
	assign sc_data3_dly[10:0]=sc_data3_dl3_r[10:0];

	assign sc_enc0[9:0]=sc_data0_out_r[9:0];
	assign sc_enc1[9:0]=sc_data1_out_r[9:0];
	assign sc_enc2[9:0]=sc_data2_out_r[9:0];
	assign sc_enc3[9:0]=sc_data3_out_r[9:0];

	assign sc_data0[8:0]=sc_data0_dly[8:0];
	assign sc_disp0[1:0]=sc_data0_dly[10:9];
	assign sc_data1[8:0]=sc_data1_dly[8:0];
	assign sc_disp1[1:0]=sc_data1_dly[10:9];
	assign sc_data2[8:0]=sc_data2_dly[8:0];
	assign sc_disp2[1:0]=sc_data2_dly[10:9];
	assign sc_data3[8:0]=sc_data3_dly[8:0];
	assign sc_disp3[1:0]=sc_data3_dly[10:9];

	assign sc_raw0[8:0]=sc_data0_out1_r[8:0];
	assign sc_raw1[8:0]=sc_data1_out1_r[8:0];
	assign sc_raw2[8:0]=sc_data2_out1_r[8:0];
	assign sc_raw3[8:0]=sc_data3_out1_r[8:0];

	always @(posedge CLK or negedge SYSRST_N)
	begin
		if (SYSRST_N==1'b0)
			begin
				sc_data0_out_r[9:0] <= 10'b0101010101;
				sc_data1_out_r[9:0] <= 10'b0101010101;
				sc_data2_out_r[9:0] <= 10'b0101010101;
				sc_data3_out_r[9:0] <= 10'b0101010101;
				sc_data0_out0_r[10:0] <= {2'b0,K285[8:0]};
				sc_data0_out0_sr_r <= 1'b0;
				sc_data1_out0_r[10:0] <= {2'b0,K285[8:0]};
				sc_data2_out0_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_out0_r[10:0] <= {2'b0,K285[8:0]};
				sc_data0_out1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data1_out1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data2_out1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_out1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data0_out2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data1_out2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data2_out2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_out2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data1_dl1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data2_dl1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_dl1_r[10:0] <= {2'b0,K285[8:0]};
				sc_data2_dl2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_dl2_r[10:0] <= {2'b0,K285[8:0]};
				sc_data3_dl3_r[10:0] <= {2'b0,K285[8:0]};
				sc_tr_data_out_r[10:0] <= 11'b0;
				sc_tr_count_r[3:0] <= 4'b0;
				sc_no_data_out_r[10:0] <= 11'b0;
				pack_data0_in_r[8:0] <= 9'b0;
				pack_data1_in_r[8:0] <= 9'b0;
				pack_data2_in_r[8:0] <= 9'b0;
				pack_data3_in_r[8:0] <= 9'b0;
				pack_data0_in_bs_r <= 1'b0;
				pack_data1_in_bs_r <= 1'b0;
				pack_data2_in_bs_r <= 1'b0;
				pack_data3_in_bs_r <= 1'b0;
				sc_op_data0_out_r[10:0] <= 11'b0;
				sc_op_data1_out_r[10:0] <= 11'b0;
				sc_op_data2_out_r[10:0] <= 11'b0;
				sc_op_data3_out_r[10:0] <= 11'b0;
				sc_op_count_r[11:0] <= 12'b0;
				sc_op_size_r[11:0] <= 12'b0;
				sc_no_count_r[12:0] <= 13'b0;
				sc_no_count_8k_r[8:0] <= 9'b0;
				sc_no_8k_r <= 1'b0;
				sc_no_8k512_r <= 1'b0;
				sc_op_count_512_r[8:0] <= 9'b0;
				sc_op_512_r <= 1'b0;
			end
		else
			begin
				sc_data0_out_r[9:0] <= sc_data0_out_w[9:0];
				sc_data1_out_r[9:0] <= sc_data1_out_w[9:0];
				sc_data2_out_r[9:0] <= sc_data2_out_w[9:0];
				sc_data3_out_r[9:0] <= sc_data3_out_w[9:0];
				sc_data0_out0_r[10:0] <= sc_data0_out0_w[10:0];
				sc_data0_out0_sr_r <= sc_data0_out0_sr_w;
				sc_data1_out0_r[10:0] <= sc_data1_out0_w[10:0];
				sc_data2_out0_r[10:0] <= sc_data2_out0_w[10:0];
				sc_data3_out0_r[10:0] <= sc_data3_out0_w[10:0];
				sc_data0_out1_r[10:0] <= sc_data0_out1_w[10:0];
				sc_data1_out1_r[10:0] <= sc_data1_out1_w[10:0];
				sc_data2_out1_r[10:0] <= sc_data2_out1_w[10:0];
				sc_data3_out1_r[10:0] <= sc_data3_out1_w[10:0];
				sc_data0_out2_r[10:0] <= sc_data0_out2_w[10:0];
				sc_data1_out2_r[10:0] <= sc_data1_out2_w[10:0];
				sc_data2_out2_r[10:0] <= sc_data2_out2_w[10:0];
				sc_data3_out2_r[10:0] <= sc_data3_out2_w[10:0];
				sc_data1_dl1_r[10:0] <= sc_data1_dl1_w[10:0];
				sc_data2_dl1_r[10:0] <= sc_data2_dl1_w[10:0];
				sc_data3_dl1_r[10:0] <= sc_data3_dl1_w[10:0];
				sc_data2_dl2_r[10:0] <= sc_data2_dl2_w[10:0];
				sc_data3_dl2_r[10:0] <= sc_data3_dl2_w[10:0];
				sc_data3_dl3_r[10:0] <= sc_data3_dl3_w[10:0];
				sc_tr_data_out_r[10:0] <= sc_tr_data_out_w[10:0];
				sc_tr_count_r[3:0] <= sc_tr_count_w[3:0];
				sc_no_data_out_r[10:0] <= sc_no_data_out_w[10:0];
				pack_data0_in_r[8:0] <= pack_data0_in_w[8:0];
				pack_data1_in_r[8:0] <= pack_data1_in_w[8:0];
				pack_data2_in_r[8:0] <= pack_data2_in_w[8:0];
				pack_data3_in_r[8:0] <= pack_data3_in_w[8:0];
				pack_data0_in_bs_r <= pack_data0_in_bs_w;
				pack_data1_in_bs_r <= pack_data1_in_bs_w;
				pack_data2_in_bs_r <= pack_data2_in_bs_w;
				pack_data3_in_bs_r <= pack_data3_in_bs_w;
				sc_op_data0_out_r[10:0] <= sc_op_data0_out_w[10:0];
				sc_op_data1_out_r[10:0] <= sc_op_data1_out_w[10:0];
				sc_op_data2_out_r[10:0] <= sc_op_data2_out_w[10:0];
				sc_op_data3_out_r[10:0] <= sc_op_data3_out_w[10:0];
				sc_op_count_r[11:0] <= sc_op_count_w[11:0];
				sc_op_size_r[11:0] <= sc_op_size_w[11:0];
				sc_no_count_r[12:0] <= sc_no_count_w[12:0];
				sc_no_count_8k_r[8:0] <= sc_no_count_8k_w[8:0];
				sc_no_8k_r <= sc_no_8k_w;
				sc_no_8k512_r <= sc_no_8k512_w;
				sc_op_count_512_r[8:0] <= sc_op_count_512_w[8:0];
				sc_op_512_r <= sc_op_512_w;
			end
	end

	assign sc_data0_out_w[9:0]=sc_enc0_out[9:0];
	assign sc_data1_out_w[9:0]=sc_enc1_out[9:0];
	assign sc_data2_out_w[9:0]=sc_enc2_out[9:0];
	assign sc_data3_out_w[9:0]=sc_enc3_out[9:0];

	assign sc_data0_out0_w[10:0]=
			(dp_main_mode[1:0]==2'b00) ? sc_no_data_out_r[10:0] :	// nodisp
			(dp_main_mode[1:0]==2'b10) ? sc_tr_data_out_r[10:0] :	// tr1
			(dp_main_mode[1:0]==2'b11) ? sc_tr_data_out_r[10:0] :	// tr2
			(dp_main_mode[1:0]==2'b01) ? sc_op_data0_out_r[10:0] :	// display
			22'b0;

	assign sc_data0_out0_sr_w=(sc_op_data0_out_r[8:0]==code_sr[8:0]) ? 1'b1 : 1'b0;

	assign sc_data1_out0_w[10:0]=
			(dp_main_mode[1:0]==2'b00) ? sc_no_data_out_r[10:0] :	// nodisp
			(dp_main_mode[1:0]==2'b10) ? sc_tr_data_out_r[10:0] :	// tr1
			(dp_main_mode[1:0]==2'b11) ? sc_tr_data_out_r[10:0] :	// tr2
			(dp_main_mode[1:0]==2'b01) ? sc_op_data1_out_r[10:0] :	// display
			22'b0;

	assign sc_data2_out0_w[10:0]=
			(dp_main_mode[1:0]==2'b00) ? sc_no_data_out_r[10:0] :	// nodisp
			(dp_main_mode[1:0]==2'b10) ? sc_tr_data_out_r[10:0] :	// tr1
			(dp_main_mode[1:0]==2'b11) ? sc_tr_data_out_r[10:0] :	// tr2
			(dp_main_mode[1:0]==2'b01) ? sc_op_data2_out_r[10:0] :	// display
			22'b0;

	assign sc_data3_out0_w[10:0]=
			(dp_main_mode[1:0]==2'b00) ? sc_no_data_out_r[10:0] :	// nodisp
			(dp_main_mode[1:0]==2'b10) ? sc_tr_data_out_r[10:0] :	// tr1
			(dp_main_mode[1:0]==2'b11) ? sc_tr_data_out_r[10:0] :	// tr2
			(dp_main_mode[1:0]==2'b01) ? sc_op_data3_out_r[10:0] :	// display
			22'b0;

	assign sc_lfsr_reset0=(sc_data0_out0_sr_r==1'b1) ? 1'b1 : 1'b0;

	assign sc_data0_out1_w[10:0]=sc_data0_out0_r[10:0];
	assign sc_data1_out1_w[10:0]=sc_data1_out0_r[10:0];
	assign sc_data2_out1_w[10:0]=sc_data2_out0_r[10:0];
	assign sc_data3_out1_w[10:0]=sc_data3_out0_r[10:0];

	assign sc_data0_out2_w[7:0]=(sc_data0_out1_r[8]==1'b1) ? sc_data0_out1_r[7:0] : sc_data0_out1_r[7:0] ^ sc_lfsr_out[7:0];
	assign sc_data0_out2_w[10:8]=sc_data0_out1_r[10:8];

	assign sc_data1_out2_w[7:0]=(sc_data1_out1_r[8]==1'b1) ? sc_data1_out1_r[7:0] : sc_data1_out1_r[7:0] ^ sc_lfsr_out[7:0];
	assign sc_data1_out2_w[10:8]=sc_data1_out1_r[10:8];

	assign sc_data2_out2_w[7:0]=(sc_data2_out1_r[8]==1'b1) ? sc_data2_out1_r[7:0] : sc_data2_out1_r[7:0] ^ sc_lfsr_out[7:0];
	assign sc_data2_out2_w[10:8]=sc_data2_out1_r[10:8];

	assign sc_data3_out2_w[7:0]=(sc_data3_out1_r[8]==1'b1) ? sc_data3_out1_r[7:0] : sc_data3_out1_r[7:0] ^ sc_lfsr_out[7:0];
	assign sc_data3_out2_w[10:8]=sc_data3_out1_r[10:8];

	assign sc_data1_dl1_w[10:0]=sc_data1_out2_r[10:0];
	assign sc_data2_dl1_w[10:0]=sc_data2_out2_r[10:0];
	assign sc_data3_dl1_w[10:0]=sc_data3_out2_r[10:0];
	assign sc_data2_dl2_w[10:0]=sc_data2_dl1_r[10:0];
	assign sc_data3_dl2_w[10:0]=sc_data3_dl1_r[10:0];
	assign sc_data3_dl3_w[10:0]=sc_data3_dl2_r[10:0];

	assign sc_tr_data_out_w[10:0]=
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00000) ? {2'b00,D102[8:0]} :	// tr0 disp1,data1,disp0,data0
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00001) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00010) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00011) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00100) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00101) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00110) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b00111) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01000) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01001) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01010) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01011) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01100) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01101) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01110) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b01111) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10000) ? {2'b10,K285[8:0]} :	// tr1
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10001) ? {2'b00,D116[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10010) ? {2'b11,K285[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10011) ? {2'b00,D116[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10100) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10101) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10110) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b10111) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11000) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11001) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11010) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11011) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11100) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11101) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11110) ? {2'b00,D102[8:0]} :
			({dp_main_mode[0],sc_tr_count_r[3:0]}==5'b11111) ? {2'b00,D102[8:0]} :
			22'b0;

	assign sc_tr_count_w[3:0]=(sc_tr_count_r[3:0]==4'b1001) ? 4'b0 : sc_tr_count_r[3:0]+4'b01;

	assign sc_no_data_out_w[10:0]=
			({sc_no_8k_r,sc_no_8k512_r}==2'b00) ? 11'b0 :
			({sc_no_8k_r,sc_no_8k512_r}==2'b10) ? {2'b00,code_bs[8:0]} :	// 8k
			({sc_no_8k_r,sc_no_8k512_r}==2'b01) ? 11'b0 :
			({sc_no_8k_r,sc_no_8k512_r}==2'b11) ? {2'b00,code_sr[8:0]} :	// 8k * 512
			18'b0;

	assign pack_data0_in_w[8:0]=pack_data0[8:0];
	assign pack_data1_in_w[8:0]=pack_data1[8:0];
	assign pack_data2_in_w[8:0]=pack_data2[8:0];
	assign pack_data3_in_w[8:0]=pack_data3[8:0];
	assign pack_data0_in_bs_w=(pack_data0[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;
	assign pack_data1_in_bs_w=(pack_data1[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;
	assign pack_data2_in_bs_w=(pack_data2[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;
	assign pack_data3_in_bs_w=(pack_data3[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;

	assign sc_op_data0_out_w[10:0]=(pack_data0_in_bs_r==1'b1) & (sc_op_512_r==1'b1) ? {2'b00,code_sr[8:0]} : {2'b00,pack_data0_in_r[8:0]};
	assign sc_op_data1_out_w[10:0]=(pack_data0_in_bs_r==1'b1) & (sc_op_512_r==1'b1) ? {2'b00,code_sr[8:0]} : {2'b00,pack_data1_in_r[8:0]};
	assign sc_op_data2_out_w[10:0]=(pack_data0_in_bs_r==1'b1) & (sc_op_512_r==1'b1) ? {2'b00,code_sr[8:0]} : {2'b00,pack_data2_in_r[8:0]};
	assign sc_op_data3_out_w[10:0]=(pack_data0_in_bs_r==1'b1) & (sc_op_512_r==1'b1) ? {2'b00,code_sr[8:0]} : {2'b00,pack_data3_in_r[8:0]};

	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_data0_out0_r[8:0]==code_bs[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_be=(sc_data0_out0_r[8:0]==code_be[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_sr=(sc_data0_out0_r[8:0]==code_sr[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_ss=(sc_data0_out0_r[8:0]==code_ss[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_fs=(sc_data0_out0_r[8:0]==code_fs[8:0]) ? 1'b1 : 1'b0;
	assign sc_op_fe=(sc_data0_out0_r[8:0]==code_fe[8:0]) ? 1'b1 : 1'b0;

	assign sc_op_count_w[11:0]=(sc_op_be==1'b1) ? 12'b0 : sc_op_count_r[11:0]+12'h001;
	assign sc_op_size_w[11:0]=(sc_op_bs==1'b1) ? sc_op_count_r[11:0] : sc_op_size_r[11:0];

`ifdef sim_fast

	// 8192 -> 256 , 512 -> 16

	assign sc_no_count_w[12:7]=6'h000;
	assign sc_no_count_w[6:0]=sc_no_count_r[6:0]+7'h001;
	assign sc_no_count_8k_w[8:4]=5'b0;
	assign sc_no_count_8k_w[3:0]=(sc_no_8k_r==1'b1) ? sc_no_count_8k_r[3:0]+4'h01 : sc_no_count_8k_r[3:0];
	assign sc_no_8k_w=(sc_no_count_r[6:0]==7'h7e) ? 1'b1 : 1'b0;
	assign sc_no_8k512_w=(sc_no_count_8k_r[3:0]==4'hf) ? 1'b1 : 1'b0;
	assign sc_op_count_512_w[8:4]=5'b0;
	assign sc_op_count_512_w[3:0]=(pack_data0_in_bs_r==1'b1) ? sc_op_count_512_r[3:0]+4'h01 : sc_op_count_512_r[3:0];
	assign sc_op_512_w=(sc_op_count_512_r[3:0]==4'hf) ? 1'b1 : 1'b0;

`else
	assign sc_no_count_w[12:0]=sc_no_count_r[12:0]+13'h001;
	assign sc_no_count_8k_w[8:0]=(sc_no_8k_r==1'b1) ? sc_no_count_8k_r[8:0]+9'h01 : sc_no_count_8k_r[8:0];
	assign sc_no_8k_w=(sc_no_count_r[12:0]==13'h1ffe) ? 1'b1 : 1'b0;
	assign sc_no_8k512_w=(sc_no_count_8k_r[8:0]==9'h1ff) ? 1'b1 : 1'b0;
	assign sc_op_count_512_w[8:0]=(pack_data0_in_bs_r==1'b1) ? sc_op_count_512_r[8:0]+9'h01 : sc_op_count_512_r[8:0];
	assign sc_op_512_w=(sc_op_count_512_r[8:0]==9'h1ff) ? 1'b1 : 1'b0;

`endif

	// ---- scramble data generate ----

	wire	dp_main_scr_w;
	reg		dp_main_scr_r;

	wire	[15:0] scr_lfsr_w;
	wire	[7:0] scr_lfsr_out_w;

	reg		[15:0] scr_lfsr_r;
	reg		[7:0] scr_lfsr_out_r;

	assign sc_lfsr_out[7:0]=(dp_main_scr_r==1'b0) ? 8'h0 : scr_lfsr_out_r[7:0];

	always @(posedge CLK or negedge SYSRST_N)
	begin
		if (SYSRST_N==1'b0)
			begin
				dp_main_scr_r <= 1'b0;
				scr_lfsr_r[15:0] <= 16'hffff;
				scr_lfsr_out_r[7:0] <= 8'hff;
			end
		else
			begin
				dp_main_scr_r <= dp_main_scr_w;
				scr_lfsr_r[15:0] <= scr_lfsr_w[15:0];
				scr_lfsr_out_r[7:0] <= scr_lfsr_out_w[7:0];
			end
	end

	assign dp_main_scr_w=dp_main_scr;

	wire	[15:0] scr_lfsr00;
	wire	[15:0] scr_lfsr01;
	wire	[15:0] scr_lfsr02;
	wire	[15:0] scr_lfsr03;
	wire	[15:0] scr_lfsr04;
	wire	[15:0] scr_lfsr05;
	wire	[15:0] scr_lfsr06;
	wire	[15:0] scr_lfsr07;

	assign scr_lfsr_w[15:0]=
			({sc_lfsr_reset0}==1'b1) ? 16'hffff : 
			({sc_lfsr_reset0}==1'b0) ? scr_lfsr07[15:0] :
			16'b0;

	assign scr_lfsr_out_w[0]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr00[0];
	assign scr_lfsr_out_w[1]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr01[0];
	assign scr_lfsr_out_w[2]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr02[0];
	assign scr_lfsr_out_w[3]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr03[0];
	assign scr_lfsr_out_w[4]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr04[0];
	assign scr_lfsr_out_w[5]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr05[0];
	assign scr_lfsr_out_w[6]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr06[0];
	assign scr_lfsr_out_w[7]=(sc_lfsr_reset0==1'b1) ? 1'b1 :scr_lfsr07[0];

	// G(X)=X^16 + X^5 + X^4 + X^3 + 1

	assign scr_lfsr00[15:6]=scr_lfsr_r[14:5];
	assign scr_lfsr00[5]=scr_lfsr_r[4] ^ scr_lfsr_r[15];
	assign scr_lfsr00[4]=scr_lfsr_r[3] ^ scr_lfsr_r[15];
	assign scr_lfsr00[3]=scr_lfsr_r[2] ^ scr_lfsr_r[15];
	assign scr_lfsr00[2:1]=scr_lfsr_r[1:0];
	assign scr_lfsr00[0]=scr_lfsr_r[15];

	assign scr_lfsr01[15:6]=scr_lfsr00[14:5];
	assign scr_lfsr01[5]=scr_lfsr00[4] ^ scr_lfsr00[15];
	assign scr_lfsr01[4]=scr_lfsr00[3] ^ scr_lfsr00[15];
	assign scr_lfsr01[3]=scr_lfsr00[2] ^ scr_lfsr00[15];
	assign scr_lfsr01[2:1]=scr_lfsr00[1:0];
	assign scr_lfsr01[0]=scr_lfsr00[15];

	assign scr_lfsr02[15:6]=scr_lfsr01[14:5];
	assign scr_lfsr02[5]=scr_lfsr01[4] ^ scr_lfsr01[15];
	assign scr_lfsr02[4]=scr_lfsr01[3] ^ scr_lfsr01[15];
	assign scr_lfsr02[3]=scr_lfsr01[2] ^ scr_lfsr01[15];
	assign scr_lfsr02[2:1]=scr_lfsr01[1:0];
	assign scr_lfsr02[0]=scr_lfsr01[15];

	assign scr_lfsr03[15:6]=scr_lfsr02[14:5];
	assign scr_lfsr03[5]=scr_lfsr02[4] ^ scr_lfsr02[15];
	assign scr_lfsr03[4]=scr_lfsr02[3] ^ scr_lfsr02[15];
	assign scr_lfsr03[3]=scr_lfsr02[2] ^ scr_lfsr02[15];
	assign scr_lfsr03[2:1]=scr_lfsr02[1:0];
	assign scr_lfsr03[0]=scr_lfsr02[15];

	assign scr_lfsr04[15:6]=scr_lfsr03[14:5];
	assign scr_lfsr04[5]=scr_lfsr03[4] ^ scr_lfsr03[15];
	assign scr_lfsr04[4]=scr_lfsr03[3] ^ scr_lfsr03[15];
	assign scr_lfsr04[3]=scr_lfsr03[2] ^ scr_lfsr03[15];
	assign scr_lfsr04[2:1]=scr_lfsr03[1:0];
	assign scr_lfsr04[0]=scr_lfsr03[15];

	assign scr_lfsr05[15:6]=scr_lfsr04[14:5];
	assign scr_lfsr05[5]=scr_lfsr04[4] ^ scr_lfsr04[15];
	assign scr_lfsr05[4]=scr_lfsr04[3] ^ scr_lfsr04[15];
	assign scr_lfsr05[3]=scr_lfsr04[2] ^ scr_lfsr04[15];
	assign scr_lfsr05[2:1]=scr_lfsr04[1:0];
	assign scr_lfsr05[0]=scr_lfsr04[15];

	assign scr_lfsr06[15:6]=scr_lfsr05[14:5];
	assign scr_lfsr06[5]=scr_lfsr05[4] ^ scr_lfsr05[15];
	assign scr_lfsr06[4]=scr_lfsr05[3] ^ scr_lfsr05[15];
	assign scr_lfsr06[3]=scr_lfsr05[2] ^ scr_lfsr05[15];
	assign scr_lfsr06[2:1]=scr_lfsr05[1:0];
	assign scr_lfsr06[0]=scr_lfsr05[15];

	assign scr_lfsr07[15:6]=scr_lfsr06[14:5];
	assign scr_lfsr07[5]=scr_lfsr06[4] ^ scr_lfsr06[15];
	assign scr_lfsr07[4]=scr_lfsr06[3] ^ scr_lfsr06[15];
	assign scr_lfsr07[3]=scr_lfsr06[2] ^ scr_lfsr06[15];
	assign scr_lfsr07[2:1]=scr_lfsr06[1:0];
	assign scr_lfsr07[0]=scr_lfsr06[15];

	// ---- 8b10b encoder ----

	wire	[7:0] tr0_din;
	wire	tr0_kin;
	wire	tr0_clk;
	wire	[9:0] tr0_dout;
	wire	tr0_force_code;
	wire	tr0_force_disp;
	wire	tr0_disp_in;
	wire	tr0_disp_out;
	wire	tr0_kerr;

	wire	[7:0] tr1_din;
	wire	tr1_kin;
	wire	tr1_clk;
	wire	[9:0] tr1_dout;
	wire	tr1_force_code;
	wire	tr1_force_disp;
	wire	tr1_disp_in;
	wire	tr1_disp_out;
	wire	tr1_kerr;

	wire	[7:0] tr2_din;
	wire	tr2_kin;
	wire	tr2_clk;
	wire	[9:0] tr2_dout;
	wire	tr2_force_code;
	wire	tr2_force_disp;
	wire	tr2_disp_in;
	wire	tr2_disp_out;
	wire	tr2_kerr;

	wire	[7:0] tr3_din;
	wire	tr3_kin;
	wire	tr3_clk;
	wire	[9:0] tr3_dout;
	wire	tr3_force_code;
	wire	tr3_force_disp;
	wire	tr3_disp_in;
	wire	tr3_disp_out;
	wire	tr3_kerr;

	assign sc_enc0_out[9:0]=tr0_dout[9:0];
	assign sc_enc1_out[9:0]=tr1_dout[9:0];
	assign sc_enc2_out[9:0]=tr2_dout[9:0];
	assign sc_enc3_out[9:0]=tr3_dout[9:0];

`ifdef enc_dual

	assign tr0_din[7:0]=sc_data0_dly[7:0];
	assign tr0_kin=sc_data0_dly[8];
	assign tr0_clk=CLK;
	assign tr0_force_code=!SYSRST_N;
	assign tr0_force_disp=sc_data0_dly[10];
	assign tr0_disp_in=sc_data0_dly[9];

	assign tr1_din[7:0]=sc_data1_dly[7:0];
	assign tr1_kin=sc_data1_dly[8];
	assign tr1_clk=CLK;
	assign tr1_force_code=!SYSRST_N;
	assign tr1_force_disp=sc_data1_dly[10];
	assign tr1_disp_in=sc_data1_dly[9];

	assign tr2_din[7:0]=sc_data2_dly[7:0];
	assign tr2_kin=sc_data2_dly[8];
	assign tr2_clk=CLK;
	assign tr2_force_code=!SYSRST_N;
	assign tr2_force_disp=sc_data2_dly[10];
	assign tr2_disp_in=sc_data2_dly[9];

	assign tr3_din[7:0]=sc_data3_dly[7:0];
	assign tr3_kin=sc_data3_dly[8];
	assign tr3_clk=CLK;
	assign tr3_force_code=!SYSRST_N;
	assign tr3_force_disp=sc_data3_dly[10];
	assign tr3_disp_in=sc_data3_dly[9];

xil_8b10b_enc enc0(
	.din(tr0_din[7:0]),					// in
	.kin(tr0_kin),						// in
	.clk(tr0_clk),						// in
	.dout(tr0_dout[9:0]),				// out
	.force_code(tr0_force_code),		// in
	.force_disp(tr0_force_disp),		// in
	.disp_in(tr0_disp_in),				// in
	.disp_out(tr0_disp_out),			// out
	.kerr(tr0_kerr)						// out
);

xil_8b10b_enc enc1(
	.din(tr1_din[7:0]),					// in
	.kin(tr1_kin),						// in
	.clk(tr1_clk),						// in
	.dout(tr1_dout[9:0]),				// out
	.force_code(tr1_force_code),		// in
	.force_disp(tr1_force_disp),		// in
	.disp_in(tr1_disp_in),				// in
	.disp_out(tr1_disp_out),			// out
	.kerr(tr1_kerr)						// out
);

xil_8b10b_enc enc2(
	.din(tr2_din[7:0]),					// in
	.kin(tr2_kin),						// in
	.clk(tr2_clk),						// in
	.dout(tr2_dout[9:0]),				// out
	.force_code(tr2_force_code),		// in
	.force_disp(tr2_force_disp),		// in
	.disp_in(tr2_disp_in),				// in
	.disp_out(tr2_disp_out),			// out
	.kerr(tr2_kerr)						// out
);

xil_8b10b_enc enc3(
	.din(tr3_din[7:0]),					// in
	.kin(tr3_kin),						// in
	.clk(tr3_clk),						// in
	.dout(tr3_dout[9:0]),				// out
	.force_code(tr3_force_code),		// in
	.force_disp(tr3_force_disp),		// in
	.disp_in(tr3_disp_in),				// in
	.disp_out(tr3_disp_out),			// out
	.kerr(tr3_kerr)						// out
);

`else

	assign tr0_dout[9:0]=10'b0;
	assign tr0_disp_out=1'b0;
	assign tr0_kerr=1'b0;
	assign tr1_dout[9:0]=10'b0;
	assign tr1_disp_out=1'b0;
	assign tr1_kerr=1'b0;
	assign tr2_dout[9:0]=10'b0;
	assign tr2_disp_out=1'b0;
	assign tr2_kerr=1'b0;
	assign tr3_dout[9:0]=10'b0;
	assign tr3_disp_out=1'b0;
	assign tr3_kerr=1'b0;

`endif

endmodule
