//------------------------------------------------------------------------------
//
//  xil_upscan.v : 640x480 -> 1024x768 pseudo upscan module
//
//  LICENSE : "as-is"
//  copyright (C) 2006, TakeshiNagashima caramelgate@gmail.com
//------------------------------------------------------------------------------
//  2009/aug/24 release -.-  upscan test
//
//------------------------------------------------------------------------------

module xil_upscan(
	input	[7:0]	TXW_RED,					// in    [CRT] [7:0] red
	input	[7:0]	TXW_GRN,					// in    [CRT] [7:0] green
	input	[7:0]	TXW_BLU,					// in    [CRT] [7:0] blue
	input			TXW_HS,						// in    [CRT] #hsync
	input			TXW_VS,						// in    [CRT] #vsync
	input			TXW_DE,						// in    [CRT] #blank/de
	input			TXW_CLK,					// in    [CRT] clock

	output	[7:0]	TXR_RED,					// out   [CRT] [7:0] red
	output	[7:0]	TXR_GRN,					// out   [CRT] [7:0] green
	output	[7:0]	TXR_BLU,					// out   [CRT] [7:0] blue
	output			TXR_HS,						// out   [CRT] #hsync
	output			TXR_VS,						// out   [CRT] #vsync
	output			TXR_DE,						// out   [CRT] #blank/de

	input			TXR_RST_N,					// in    [SYS] #reset
	input			TXR_CLK						// in    [SYS] clock
);

//--------------------------------------------------------------
//  constant

	parameter	param_hpos=12'h000;			// 0   : horizontal posiotn
	parameter	param_vpos=12'h000;			// 0   : vertical position

	// ---- 25MHz 640*480@60Hz(vga) timing ----

	parameter	param640x480_hsize=12'h27f;		// 640 : horizontal size
	parameter	param640x480_vsize=12'h1df;		// 480 : vertical size

	// ---- 40MHz 800*600@60Hz(svga) timing ----

	parameter	param800x600_hsize=12'h31f;		// 800 : horizontal size
	parameter	param800x600_vsize=12'h257;		// 600 : vertical size

	// ---- 65MHz 1024*768@60Hz(xga) timing ----

	parameter	param1024x768_hcount_sbp=12'h087;	//  136 : start back porch(end hsync)
//	parameter	param1024x768_hcount_ebp=12'h0dd;	//  222 : end back porch(start active video)
	parameter	param1024x768_hcount_sav=12'h0dd;	//  222 : start active video
	parameter	param1024x768_hcount_eav=12'h4dd;	// 1246 : end active video
//	parameter	param1024x768_hcount_sfp=12'h4dd;	// 1246 : start front porch(end active video)
//	parameter	param1024x768_hcount_efp=12'h4f5;	// 1270 : end front porch(start hsync)
	parameter	param1024x768_hcount_end=12'h4f5;	// 1270 : end horizontal

	parameter	param1024x768_vcount_sbp=12'h005;	//   6 : start back porch(end vsync)
//	parameter	param1024x768_vcount_ebp=12'h022;	//  35 : end back porch(start active video)
	parameter	param1024x768_vcount_sav=12'h022;	//  35 : start active video
	parameter	param1024x768_vcount_eav=12'h322;	// 803 : end active video
//	parameter	param1024x768_vcount_sfp=12'h322;	// 803 : start front porch(end active video)
//	parameter	param1024x768_vcount_efp=12'h325;	// 806 : end front porch(start vsync)
	parameter	param1024x768_vcount_end=12'h325;	// 806 : end vertical

	parameter	param1024x768_hsize=12'h3ff;		// 1024 : horizontal size
	parameter	param1024x768_vsize=12'h2ff;		// 768  : vertical size
//	parameter	param1024x768_vsize=12'h02f;		// 768  : vertical size

	parameter	param1024x768_hsize_up=24'h000_a00;	// 1024 : horizontal up 640->1024
	parameter	param1024x768_vsize_up=24'h000_a00;	// 768  : vertical up 480->768

	// ---- 69MHz 1280*768@60Hz(wxga) timing ----

	parameter	param1280x768_hsize=12'h4ff;		// 1280 : horizontal size
	parameter	param1280x768_vsize=12'h2ff;		// 768  : vertical size

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

	wire	[31:0] data_out;
	wire	hsync_out_n;
	wire	vsync_out_n;
	wire	blank_out_n;

	wire	[23:0] data_out_w;
	reg		[23:0] data_out_r;
	wire	[7:0] hsync_out_n_w;
	reg		[7:0] hsync_out_n_r;
	wire	[7:0] vsync_out_n_w;
	reg		[7:0] vsync_out_n_r;
	wire	[7:0] blank_out_n_w;
	reg		[7:0] blank_out_n_r;

	wire	hcount_stop_w;
	wire	hcount_ack_w;
	reg		hcount_stop_r;
	reg		hcount_ack_r;
	wire	[11:0] hcount_w;
	reg		[11:0] hcount_r;
	wire	[11:0] vcount_w;
	reg		[11:0] vcount_r;
	wire	[11:0] hcount_inc;
	wire	[11:0] vcount_inc;
	wire	hcount_end;
	wire	[7:0] htiming_w;
	reg		[7:0] htiming_r;
	wire	vcount_end;
	wire	[7:0] vtiming_w;
	reg		[7:0] vtiming_r;

	wire	hsync_n_w;
	reg		hsync_n_r;
	wire	vsync_n_w;
	reg		vsync_n_r;
	wire	hblank_n_w;
	reg		hblank_n_r;
	wire	vblank_n_w;
	reg		vblank_n_r;
	wire	blank_n_w;
	reg		blank_n_r;

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

	// ---- display signal ----

	assign TXR_RED[7:0]=data_out[23:16];
	assign TXR_GRN[7:0]=data_out[15:8];
	assign TXR_BLU[7:0]=data_out[7:0];

	assign TXR_HS=hsync_out_n;
	assign TXR_VS=vsync_out_n;
	assign TXR_DE=blank_out_n;

	// ---- line buffer store ----

	wire	[10:0] lbw_addr;
	wire	[23:0] lbw_data;
	wire	lbw_we;
	wire	lbw_disp;

	wire	[10:0] lbr_addr;
	wire	[23:0] lbr_data;

	wire	lbw_req;
	wire	[3:0] lbw_req_w;
	reg		[3:0] lbw_req_r;

	wire	[23:0] lbw_data_w;
	wire	[9:0] lbw_addr_w;
	wire	lbw_flip_w;
	wire	lbw_hs_w;
	wire	lbw_vs_w;
	wire	lbw_de_w;
	wire	lbw_disp_w;
	wire	lbw_disp_req_w;

	reg		[23:0] lbw_data_r;
	reg		[9:0] lbw_addr_r;
	reg		lbw_flip_r;
	reg		lbw_hs_r;
	reg		lbw_vs_r;
	reg		lbw_de_r;
	reg		lbw_disp_r;
	reg		lbw_disp_req_r;

	assign lbw_addr[10]=lbw_flip_r;
	assign lbw_addr[9:0]=lbw_addr_r[9:0];
	assign lbw_data[23:0]=lbw_data_r[23:0];
	assign lbw_we=lbw_de_r;
	assign lbw_disp=lbw_disp_req_r;

	assign lbw_req=lbw_req_r[3];

	always @(posedge TXW_CLK or negedge TXR_RST_N)
	begin
		if (TXR_RST_N==1'b0)
			begin
				lbw_req_r[3:0] <= 4'b0;
				lbw_data_r[23:0] <= 24'b0;
				lbw_addr_r[9:0] <= 10'b0;
				lbw_flip_r <= 1'b0;
				lbw_hs_r <= 1'b0;
				lbw_vs_r <= 1'b0;
				lbw_de_r <= 1'b0;
				lbw_disp_r <= 1'b0;
				lbw_disp_req_r <= 1'b0;
			end
		else
			begin
				lbw_req_r[3:0] <= lbw_req_w[3:0];
				lbw_data_r[23:0] <= lbw_data_w[23:0];
				lbw_addr_r[9:0] <= lbw_addr_w[9:0];
				lbw_flip_r <= lbw_flip_w;
				lbw_hs_r <= lbw_hs_w;
				lbw_vs_r <= lbw_vs_w;
				lbw_de_r <= lbw_de_w;
				lbw_disp_r <= lbw_disp_w;
				lbw_disp_req_r <= lbw_disp_req_w;
			end
	end

	assign lbw_req_w[0]=TXW_HS;
	assign lbw_req_w[1]=lbw_req_r[0];
	assign lbw_req_w[2]=(lbw_req_r[1:0]==2'b10) ? 1'b1 : 1'b0;
	assign lbw_req_w[3]=(lbw_req_r[1:0]==2'b10) ? !lbw_req_r[3] : lbw_req_r[3];

	assign lbw_data_w[23:0]={TXW_RED[7:0],TXW_GRN[7:0],TXW_BLU[7:0]};

	assign lbw_addr_w[9:0]=(lbw_de_r==1'b0) ? 10'b0 : lbw_addr_r[9:0]+10'h001;
	assign lbw_flip_w=1'b0;
	assign lbw_hs_w=TXW_HS;
	assign lbw_vs_w=TXW_VS;
	assign lbw_de_w=TXW_DE;

	assign lbw_disp_w=
			({TXW_VS,TXW_DE}==2'b10) ? lbw_disp_r :
			({TXW_VS,TXW_DE}==2'b11) ? 1'b1 :
			(TXW_VS         ==1'b0 ) ? 1'b0 :
			1'b0;
	assign lbw_disp_req_w=
			({TXW_VS,lbw_disp_r,TXW_HS,lbw_hs_r}==4'b1100) ? lbw_disp_req_r :
			({TXW_VS,lbw_disp_r,TXW_HS,lbw_hs_r}==4'b1110) ? lbw_disp_req_r :
			({TXW_VS,lbw_disp_r,TXW_HS,lbw_hs_r}==4'b1111) ? lbw_disp_req_r :
			({TXW_VS,lbw_disp_r,TXW_HS,lbw_hs_r}==4'b1101) ? 1'b1 :
			({TXW_VS,lbw_disp_r}                ==2'b10  ) ? 1'b0 :
			({TXW_VS,lbw_disp_r}                ==2'b01  ) ? 1'b0 :
			({TXW_VS,lbw_disp_r}                ==2'b00  ) ? 1'b0 :
			1'b0;

xil_dpram_2048x8 dpram_2048x8_0 (
	.clka(TXW_CLK),
	.dina(lbw_data[7:0]),
	.addra(lbw_addr[10:0]),
	.wea(lbw_we),
	.clkb(TXR_CLK),
	.addrb(lbr_addr[10:0]),
	.doutb(lbr_data[7:0])
);

xil_dpram_2048x8 dpram_2048x8_1 (
	.clka(TXW_CLK),
	.dina(lbw_data[15:8]),
	.addra(lbw_addr[10:0]),
	.wea(lbw_we),
	.clkb(TXR_CLK),
	.addrb(lbr_addr[10:0]),
	.doutb(lbr_data[15:8])
);

xil_dpram_2048x8 dpram_2048x8_2 (
	.clka(TXW_CLK),
	.dina(lbw_data[23:16]),
	.addra(lbw_addr[10:0]),
	.wea(lbw_we),
	.clkb(TXR_CLK),
	.addrb(lbr_addr[10:0]),
	.doutb(lbr_data[23:16])
);

	// ---- diplay timing control ----

	wire	[11:0] reg_hcount_sbp_w;
	wire	[11:0] reg_hcount_sav_w;
	wire	[11:0] reg_hcount_eav_w;
	wire	[11:0] reg_hcount_end_w;
	wire	[11:0] reg_vcount_sbp_w;
	wire	[11:0] reg_vcount_sav_w;
	wire	[11:0] reg_vcount_eav_w;
	wire	[11:0] reg_vcount_end_w;
	wire	[11:0] reg_hsize_w;
	wire	[11:0] reg_vsize_w;

	reg		[11:0] reg_hcount_sbp_r;
	reg		[11:0] reg_hcount_sav_r;
	reg		[11:0] reg_hcount_eav_r;
	reg		[11:0] reg_hcount_end_r;
	reg		[11:0] reg_vcount_sbp_r;
	reg		[11:0] reg_vcount_sav_r;
	reg		[11:0] reg_vcount_eav_r;
	reg		[11:0] reg_vcount_end_r;
	reg		[11:0] reg_hsize_r;
	reg		[11:0] reg_vsize_r;

	always @(posedge TXR_CLK or negedge TXR_RST_N)
	begin
		if (TXR_RST_N==1'b0)
			begin
				reg_hcount_sbp_r[11:0] <= param1024x768_hcount_sbp[11:0];
				reg_hcount_sav_r[11:0] <= param1024x768_hcount_sav[11:0];
				reg_hcount_eav_r[11:0] <= param1024x768_hcount_eav[11:0];
				reg_hcount_end_r[11:0] <= param1024x768_hcount_end[11:0];
				reg_vcount_sbp_r[11:0] <= param1024x768_vcount_sbp[11:0];
				reg_vcount_sav_r[11:0] <= param1024x768_vcount_sav[11:0];
				reg_vcount_eav_r[11:0] <= param1024x768_vcount_eav[11:0];
				reg_vcount_end_r[11:0] <= param1024x768_vcount_end[11:0];
				reg_hsize_r[11:0] <= param1024x768_hsize[11:0];
				reg_vsize_r[11:0] <= param1024x768_vsize[11:0];
			end
		else
			begin
				reg_hcount_sbp_r[11:0] <= reg_hcount_sbp_w[11:0];
				reg_hcount_sav_r[11:0] <= reg_hcount_sav_w[11:0];
				reg_hcount_eav_r[11:0] <= reg_hcount_eav_w[11:0];
				reg_hcount_end_r[11:0] <= reg_hcount_end_w[11:0];
				reg_vcount_sbp_r[11:0] <= reg_vcount_sbp_w[11:0];
				reg_vcount_sav_r[11:0] <= reg_vcount_sav_w[11:0];
				reg_vcount_eav_r[11:0] <= reg_vcount_eav_w[11:0];
				reg_vcount_end_r[11:0] <= reg_vcount_end_w[11:0];
				reg_hsize_r[11:0] <= reg_hsize_w[11:0];
				reg_vsize_r[11:0] <= reg_vsize_w[11:0];
			end
	end

	assign reg_hcount_sbp_w[11:0]=param1024x768_hcount_sbp[11:0];
	assign reg_hcount_sav_w[11:0]=param1024x768_hcount_sav[11:0];
	assign reg_hcount_eav_w[11:0]=param1024x768_hcount_eav[11:0];
	assign reg_hcount_end_w[11:0]=param1024x768_hcount_end[11:0];
	assign reg_vcount_sbp_w[11:0]=param1024x768_vcount_sbp[11:0];
	assign reg_vcount_sav_w[11:0]=param1024x768_vcount_sav[11:0];
	assign reg_vcount_eav_w[11:0]=param1024x768_vcount_eav[11:0];
	assign reg_vcount_end_w[11:0]=param1024x768_vcount_end[11:0];
	assign reg_hsize_w[11:0]=param1024x768_hsize[11:0];
	assign reg_vsize_w[11:0]=param1024x768_vsize[11:0];

	// ---- ----

	wire	disp_req;
	wire	hsync_req;
	wire	vsync_req;
	wire	hcount_req;
	wire	hcount_ack;
	wire	vcount_req;

	wire	[1:0] disp_req_w;
	wire	[1:0] hsync_req_w;
	wire	[1:0] vsync_req_w;
	wire	[7:0] hcount_req_w;
	wire	[5:0] vcount_req_w;
	reg		[1:0] disp_req_r;
	reg		[1:0] hsync_req_r;
	reg		[1:0] vsync_req_r;
	reg		[7:0] hcount_req_r;
	reg		[5:0] vcount_req_r;

	assign disp_req=disp_req_r[1];
	assign hsync_req=hsync_req_r[1];
	assign vsync_req=vsync_req_r[1];
	assign hcount_req=hcount_req_r[5];
	assign vcount_req=vcount_req_r[5];

	assign hcount_ack=hcount_ack_r;

	always @(posedge TXR_CLK or negedge TXR_RST_N)
	begin
		if (TXR_RST_N==1'b0)
			begin
				disp_req_r[1:0] <= 2'b0;
				hsync_req_r[1:0] <= 2'b0;
				vsync_req_r[1:0] <= 2'b0;
				hcount_req_r[7:0] <= 8'b0;
				vcount_req_r[5:0] <= 6'b0;

				hcount_stop_r <= 1'b1;
				hcount_ack_r <= 1'b0;
				hcount_r[11:0] <= 12'h001;
				htiming_r[7:0] <= 8'h00;
				vcount_r[11:0] <= 12'h000;
				vtiming_r[7:0] <= 8'h00;
				hsync_n_r <= 1'b0;
				vsync_n_r <= 1'b0;
				hblank_n_r <= 1'b0;
				vblank_n_r <= 1'b0;
				blank_n_r <= 1'b0;
			end
		else
			begin
				disp_req_r[1:0] <= disp_req_w[1:0];
				hsync_req_r[1:0] <= hsync_req_w[1:0];
				vsync_req_r[1:0] <= vsync_req_w[1:0];
				hcount_req_r[7:0] <= hcount_req_w[7:0];
				vcount_req_r[5:0] <= vcount_req_w[5:0];

				hcount_stop_r <= hcount_stop_w;
				hcount_ack_r <= hcount_ack_w;
				hcount_r[11:0] <= hcount_w[11:0];
				htiming_r[7:0] <= htiming_w[7:0];
				vcount_r[11:0] <= vcount_w[11:0];
				vtiming_r[7:0] <= vtiming_w[7:0];
				hsync_n_r <= hsync_n_w;
				vsync_n_r <= vsync_n_w;
				hblank_n_r <= hblank_n_w;
				vblank_n_r <= vblank_n_w;
				blank_n_r <= blank_n_w;
			end
	end

	assign disp_req_w[0]=lbw_disp;
	assign disp_req_w[1]=(hcount_req_r[3]==1'b1) ? disp_req_r[0] : disp_req_r[1];

	assign hsync_req_w[0]=lbw_hs_r;
	assign hsync_req_w[1]=hsync_req_r[0];
	assign vsync_req_w[0]=lbw_vs_r;
	assign vsync_req_w[1]=vsync_req_r[0];

	wire	line_repeat;

	assign hcount_req_w[0]=lbw_req;
	assign hcount_req_w[1]=hcount_req_r[0];
	assign hcount_req_w[2]=hcount_req_r[1];
	assign hcount_req_w[3]=(hcount_req_r[2:1]==2'b01) | (hcount_req_r[2:1]==2'b10) ? 1'b1 : 1'b0;

	assign hcount_req_w[4]=(hcount_req_r[3]==1'b1) ? !hcount_req_r[4] : hcount_req_r[4];

	assign hcount_req_w[5]=
			(hcount_req_r[3]==1'b1) ? 1'b1 :
			(hcount_req_r[3]==1'b0) & ({line_repeat,hcount_end}==2'b01) ? 1'b0 :
			(hcount_req_r[3]==1'b0) & ({line_repeat,hcount_end}!=2'b01) ? hcount_req_r[5] :
			1'b0;

	assign hcount_req_w[6]=
			(hcount_req_r[3]==1'b1) ? 1'b1 :
			(hcount_req_r[3]==1'b0) & (hcount_ack==1'b1) ? 1'b0 :
			(hcount_req_r[3]==1'b0) & (hcount_ack==1'b0) ? hcount_req_r[6] :
			1'b0;

	assign hcount_req_w[7]=1'b0;

	assign vcount_req_w[5:0]=6'b0;

	assign hcount_inc[11:0]=hcount_r[11:0]+12'h001;
	assign vcount_inc[11:0]=vcount_r[11:0]+12'h001;

	assign hcount_end=(htiming_r[7]==1'b1) ? 1'b1 : 1'b0;
	assign vcount_end=1'b0;

	assign hcount_stop_w=
			(disp_req==1'b1) & (hcount_req_r[6]==1'b1) ? 1'b0 :
			(disp_req==1'b1) & (hcount_req_r[6]==1'b0) & (hcount_end==1'b1) & (line_repeat==1'b0) ? 1'b1 :
			(disp_req==1'b1) & (hcount_req_r[6]==1'b0) & (hcount_end==1'b1) & (line_repeat==1'b1) ? hcount_stop_r :
			(disp_req==1'b1) & (hcount_req_r[6]==1'b0) & (hcount_end==1'b0) ? hcount_stop_r :
			1'b1;

	assign hcount_ack_w=(disp_req==1'b1) & (hcount_req_r[6]==1'b1) & (htiming_r[1]==1'b1) ? 1'b1 : 1'b0;

	assign hcount_w[11:0]=
			(disp_req==1'b0) ? 12'h000 :
			(disp_req==1'b1) & (hcount_end==1'b1) ? 12'h001 :
			(disp_req==1'b1) & (hcount_end==1'b0) & (hcount_stop_r==1'b0) ? hcount_inc[11:0] :
			(disp_req==1'b1) & (hcount_end==1'b0) & (hcount_stop_r==1'b1) ? 12'h001 :
			12'h001;

	assign vcount_w[11:0]=
			(disp_req==1'b0) ? 12'h000 :
			(disp_req==1'b1) & (hcount_end==1'b1) ? vcount_inc[11:0] :
			(disp_req==1'b1) & (hcount_end==1'b0) ? vcount_r[11:0] :
			12'h000;

	assign htiming_w[0]=(hcount_r[2:0]==3'b110) ? 1'b1 : 1'b0;
	assign htiming_w[1]=(hcount_r[11:0]==reg_hcount_sbp_r[11:0]) ? 1'b1 : 1'b0;
	assign htiming_w[2]=1'b0;
	assign htiming_w[3]=(hcount_r[11:0]==reg_hcount_sav_r[11:0]) ? 1'b1 : 1'b0;
	assign htiming_w[4]=(hcount_r[11:0]==reg_hcount_eav_r[11:0]) ? 1'b1 : 1'b0;
	assign htiming_w[5]=1'b0;
	assign htiming_w[6]=hsync_req;
	assign htiming_w[7]=
			(disp_req==1'b0) & ({htiming_r[6],hsync_req}==2'b01) ? 1'b1 :
			(disp_req==1'b1) & (hcount_r[11:0]==reg_hcount_end_r[11:0]) ? 1'b1 :
			1'b0;

	assign vtiming_w[0]=(hcount_r[2:0]==3'b101) ? 1'b1 : 1'b0;
	assign vtiming_w[1]=(vcount_r[11:0]==reg_vcount_sbp_r[11:0]) ? 1'b1 : 1'b0;
	assign vtiming_w[2]=1'b0;
	assign vtiming_w[3]=(vcount_r[11:0]==reg_vcount_sav_r[11:0]) ? 1'b1 : 1'b0;
	assign vtiming_w[4]=(vcount_r[11:0]==reg_vcount_eav_r[11:0]) ? 1'b1 : 1'b0;
	assign vtiming_w[5]=1'b0;
	assign vtiming_w[6]=1'b0;
	assign vtiming_w[7]=(vcount_r[11:0]==reg_vcount_end_r[11:0]) ? 1'b1 : 1'b0;

	assign hsync_n_w=
			(disp_req==1'b0) ? hsync_req :
			(disp_req==1'b1) & (htiming_r[7]==1'b1) ? 1'b0 :
			(disp_req==1'b1) & (htiming_r[7]==1'b0) & (htiming_r[1]==1'b1) ? 1'b1 :
			(disp_req==1'b1) & (htiming_r[7]==1'b0) & (htiming_r[1]==1'b0) ? hsync_n_r :
			1'b0;

	assign vsync_n_w=(hblank_n_r==1'b0) ? vsync_req : vsync_n_r;

	assign hblank_n_w=
			(htiming_r[4]==1'b1) ? 1'b0 :
			(htiming_r[4]==1'b0) & (htiming_r[3]==1'b1) ? 1'b1 :
			(htiming_r[4]==1'b0) & (htiming_r[3]==1'b0) ? hblank_n_r :
			1'b0;

	assign vblank_n_w=
			(vsync_req==1'b0) ? 1'b1 :
			(vsync_req==1'b1) &  ((hcount_end==1'b1) & (vcount_r[11:0]==reg_vsize_r[11:0])) ? 1'b0 :
			(vsync_req==1'b1) & !((hcount_end==1'b1) & (vcount_r[11:0]==reg_vsize_r[11:0])) ? vblank_n_r :
			1'b0;

	assign blank_n_w=(hblank_n_w==1'b0) | (vblank_n_r==1'b0) | (disp_req==1'b0) ? 1'b0 : 1'b1;

	// ---- buff output control ----

	assign data_out[23:0]=data_out_r[23:0];
	assign hsync_out_n=hsync_out_n_r[2];
	assign vsync_out_n=vsync_out_n_r[2];
	assign blank_out_n=blank_out_n_r[2];

	wire	line_flip_w;
	reg		line_flip_r;

	wire	[23:0] hdisp_count_inc;
	wire	[23:0] vdisp_count_inc;

	wire	[23:0] hdisp_count_w;
	wire	[23:0] vdisp_count_w;
	wire	line_repeat_w;
	reg		[23:0] hdisp_count_r;
	reg		[23:0] vdisp_count_r;
	reg		line_repeat_r;

	wire	[23:0] hdisp_add_w;
	wire	[23:0] vdisp_add_w;
	reg		[23:0] hdisp_add_r;
	reg		[23:0] vdisp_add_r;

	assign lbr_addr[10]=line_flip_r;
	assign lbr_addr[9:0]=(blank_n_r==1'b0) ? 10'h3ff : hdisp_count_r[21:12];

	always @(posedge TXR_CLK or negedge TXR_RST_N)
	begin
		if (TXR_RST_N==1'b0)
			begin
				data_out_r[23:0] <= 24'h0;
				hsync_out_n_r[7:0] <= 8'b00;
				vsync_out_n_r[7:0] <= 8'b00;
				blank_out_n_r[7:0] <= 8'b00;

				line_flip_r <= 1'b0;
				hdisp_count_r[23:0] <= 24'b00;
				vdisp_count_r[23:0] <= 24'b00;
				line_repeat_r <= 1'b0;
				hdisp_add_r[23:0] <= 24'b0;
				vdisp_add_r[23:0] <= 24'b0;
			end
		else
			begin
				data_out_r[23:0] <= data_out_w[23:0];
				hsync_out_n_r[7:0] <= hsync_out_n_w[7:0];
				vsync_out_n_r[7:0] <= vsync_out_n_w[7:0];
				blank_out_n_r[7:0] <= blank_out_n_w[7:0];

				line_flip_r <= line_flip_w;
				hdisp_count_r[23:0] <= hdisp_count_w[23:0];
				vdisp_count_r[23:0] <= vdisp_count_w[23:0];
				line_repeat_r <= line_repeat_w;
				hdisp_add_r[23:0] <= hdisp_add_w[23:0];
				vdisp_add_r[23:0] <= vdisp_add_w[23:0];
			end
	end

	assign hsync_out_n_w[7:0]={hsync_out_n_r[6:0],hsync_n_r};
	assign vsync_out_n_w[7:0]={vsync_out_n_r[6:0],vsync_n_r};
	assign blank_out_n_w[7:0]={blank_out_n_r[6:0],blank_n_r};

	assign data_out_w[23:0]=
			(blank_out_n_r[1]==1'b0) ? 24'h0 :
			(blank_out_n_r[1]==1'b1) ? lbr_data[23:0] :
			24'h0;

	assign line_flip_w=1'b0;

	assign hdisp_count_inc[23:0]=hdisp_count_r[23:0]+hdisp_add_r[23:0];
	assign vdisp_count_inc[23:0]=vdisp_count_r[23:0]+vdisp_add_r[23:0];

//	assign line_repeat=(disp_req==1'b1) & (vdisp_count_r[23:12]==vdisp_count_inc[23:12]) ? 1'b1 : 1'b0;
	assign line_repeat=(disp_req==1'b1) & (line_repeat_r==1'b1) ? 1'b1 : 1'b0;

	assign hdisp_count_w[23:0]=(blank_n_r==1'b0) ? 24'h0 : hdisp_count_inc[23:0];
	assign vdisp_count_w[23:0]=
			(vsync_n_r==1'b0) ? 24'h0 :
			(vsync_n_r==1'b1) & ({disp_req,hcount_end}==2'b11) ? vdisp_count_inc[23:0] :
			(vsync_n_r==1'b1) & ({disp_req,hcount_end}!=2'b11) ? vdisp_count_r[23:0] :
			24'h0;
	assign line_repeat_w=(vdisp_count_r[23:12]==vdisp_count_inc[23:12]) ? 1'b1 : 1'b0;

	assign hdisp_add_w[23:0]=param1024x768_hsize_up[23:0];
	assign vdisp_add_w[23:0]=param1024x768_vsize_up[23:0];

endmodule
