


module VGA_LED_Emulator(
								input logic 	    	clk50, reset,
								input logic [7:0] 	hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7,hex10,hex11,hex12,
								input logic [7:0] 	q_a,
								input logic [7:0] 	data_rom_bg,
								input logic [9:0] 	cursor_x, cursor_y,
								input logic [7:0] 	data_exam1,data_exam2,data_exam3,data_exam4,data_wel_ins,
								input logic [7:0] 	data_rom_win,data_rom_keep,data_rom_ins,
								output logic[13:0] 	addr_exam1,addr_exam2,addr_exam3,addr_exam4,
								output logic[14:0] 	addr_wel_ins,
								output logic[7:0] 	VGA_R, VGA_G, VGA_B,
								output logic 	    	VGA_CLK, VGA_HS, VGA_VS, VGA_BLANK_n, VGA_SYNC_n,
								output logic      	clk25, enable,
								output logic[14:0] 	address_a,
								output logic        	rden_a,wren_a,
								output logic[7:0]  	data_a,
								output logic[9:0]  	vcount,
								output logic[10:0] 	hcount,
								output logic[15:0] 	addr_rom_bg,
								output logic[13:0]   addr_slogan,
								output logic[12:0]   addr_ins

 );
   parameter HACTIVE      = 11'd 1280,
             HFRONT_PORCH = 11'd 32,
             HSYNC        = 11'd 192,
             HBACK_PORCH  = 11'd 96,   
             HTOTAL       = HACTIVE + HFRONT_PORCH + HSYNC + HBACK_PORCH; 
   
   parameter VACTIVE      = 10'd 480,
             VFRONT_PORCH = 10'd 10,
             VSYNC        = 10'd 2,
             VBACK_PORCH  = 10'd 33,
             VTOTAL       = VACTIVE + VFRONT_PORCH + VSYNC + VBACK_PORCH; 
   logic 			     endOfLine;
   
   always_ff @(posedge clk50 or posedge reset)
		if (reset)          
			hcount <= 0;
		else if (endOfLine) 
			hcount <= 0;
		else  	         
			hcount <= hcount + 11'd 1;

   assign endOfLine = hcount == HTOTAL - 1;

   logic 			     endOfField;
   
   always_ff @(posedge clk50 or posedge reset)
		if (reset)          
			vcount <= 0;
		else if (endOfLine)
			if (endOfField)   
				vcount <= 0;
			else              
				vcount <= vcount + 10'd 1;

	assign endOfField = vcount == VTOTAL - 1;
   assign VGA_HS = !( (hcount[10:8] == 3'b101) & !(hcount[7:5] == 3'b111));
   assign VGA_VS = !( vcount[9:1] == (VACTIVE + VFRONT_PORCH) / 2);
   assign VGA_SYNC_n = 1; 
   assign VGA_BLANK_n = !( hcount[10] & (hcount[9] | hcount[8]) ) &
			!( vcount[9] | (vcount[8:5] == 4'b1111) );   
	assign VGA_CLK = hcount[0];
   assign clk25 = VGA_CLK;
   
	parameter win_w=400;
	parameter win_h=70;
	 
	 
	logic inwin;
   assign inwin= (hcount[10:1]>=120&&hcount[10:1]<520&&vcount>=65&&vcount<=414);
    
	always@* 
		begin
			if (inwin) 
				begin
					enable = 1;
			   end
			else 
				enable = 0;
		end
	 
   always_ff@ (negedge clk50)
		begin
			if (reset)
				begin
					rden_a <=0;
					wren_a <=0;
					address_a<=0;
				end
			else if (VGA_CLK==1&&enable==1)
				begin
					rden_a<=1;
					wren_a<=0;
					address_a <= ((vcount-65)%win_h)*win_w + (hcount[10:1]-120);
				end
			else if (VGA_CLK==0&&enable==1&&vcount==65)
				begin
					rden_a<=0;
					wren_a<=1;
					address_a <= ((win_h-1)%win_h)*win_w + (hcount[10:1]-120);
					data_a<=0;
				end
			else if (VGA_CLK==0&&enable==1&&vcount!=65)
				begin
					rden_a<=0;
					wren_a<=1;
					address_a <= ((vcount-66)%win_h)*win_w + (hcount[10:1]-120);
					data_a<=0;
				end
			else 
				begin
					rden_a<=0;
					wren_a<=0;
				end
	end //end always


//--------------------------------------draw texture------counter=8191----------------------------	
	logic[19:0] counter_hl ;
	logic[8:0]  gray_hl;
	
   always@(posedge VGA_CLK)
		begin
			if (reset) 
				begin
					counter_hl<=20'h0;
					gray_hl<=8'd220;
				end
			else if (counter_hl<20'd8191&&gray_hl>8'd20)
				begin
					counter_hl<=counter_hl+'d1;
					gray_hl<=gray_hl;
				end
			else if (counter_hl<20'd8191&&gray_hl<=8'd20)
				begin
					counter_hl<=counter_hl+'d1;
					gray_hl<=gray_hl;
				end
			else if (counter_hl==20'd8191&&gray_hl>8'd20)
				begin
					counter_hl<=0;
					gray_hl<=gray_hl-8'd2;
				end
			else if (counter_hl==20'd8191&&gray_hl<=8'd20)
				begin
					counter_hl<=0;
					gray_hl<=8'd220;
				end
			else 
				begin
					counter_hl<=counter_hl;
					gray_hl<=gray_hl;
				end
		end//always
	
//----------------------------------cursor display----------------------------------------------
	logic    incursor;

	assign 	incursor= (hcount[10:1]>=cursor_x-4&&hcount[10:1]<=cursor_x+4&&vcount==cursor_y+2)||
							 (hcount[10:1]>=cursor_x-3&&hcount[10:1]<=cursor_x+3&&vcount==cursor_y+1)||
							 (hcount[10:1]>=cursor_x-2 && hcount[10:1]<=cursor_x+2&& vcount==cursor_y)||
							 (hcount[10:1]>=cursor_x-1 && hcount[10:1]<=cursor_x+1&& vcount==cursor_y-1)||
							 (hcount[10:1]==cursor_x&&vcount==cursor_y-2);

 //---------------------------------welcome window--------------------------------------------
 
	logic example1,example2,example3,example4,wel_ins;
	logic [9:0]cent_cir_x,cent_cir_y;
	logic sel_circle;
	logic[7:0] data_exam10,data_exam20,data_exam30,data_exam40;
 
	assign sel_circle=((hcount[10:1]-cent_cir_x)*(hcount[10:1]-cent_cir_x)+ 
							(vcount-cent_cir_y)*(vcount-cent_cir_y)>=48*48) &&
							((hcount[10:1]-cent_cir_x)*(hcount[10:1]-cent_cir_x)+ 
							(vcount-cent_cir_y)*(vcount-cent_cir_y)<=51*51);
 
	always@(posedge clk50)
		begin
			if (reset)
				begin
					cent_cir_x<=0;
					cent_cir_y<=0;
					data_exam10<=0;
					data_exam20<=0;
					data_exam30<=0;
					data_exam40<=0;
		end
			else if (hex11==1)
				begin
					cent_cir_x<=260;
					cent_cir_y<=130;
						if (data_exam1<=5)
							data_exam10<=data_exam1;
						else
							data_exam10<=data_exam1*2;
					data_exam20<=data_exam2;
					data_exam30<=data_exam3;
					data_exam40<=data_exam4;
				end
			else if (hex11==2)
				begin
					cent_cir_x=380;
					cent_cir_y=130;
					data_exam10<=data_exam1;
						if (data_exam2<=3)
							data_exam20<=data_exam2;
						else
							data_exam20<=data_exam2*2;
					data_exam30<=data_exam3;
					data_exam40<=data_exam4;
				end
			else if (hex11==3)
				begin
					cent_cir_x<=260;
					cent_cir_y<=250;
					data_exam10<=data_exam1;
					data_exam20<=data_exam2;
						if (data_exam3<=3)
							data_exam30<=data_exam3;
						else
							data_exam30<=data_exam3*2;
					data_exam40<=data_exam4;	
				end	
			else if (hex11==4)
				begin
					cent_cir_x<=380;
					cent_cir_y<=250;
					data_exam10<=data_exam1;
					data_exam20<=data_exam2;
					data_exam30<=data_exam3;
						if (data_exam4<=3)
							data_exam40<=data_exam4;
						else
							data_exam40<=data_exam4*2;
				end
			else 
				begin
					cent_cir_x<=cent_cir_x;
					cent_cir_y<=cent_cir_y;
					data_exam10<=data_exam1;
					data_exam20<=data_exam2;
					data_exam30<=data_exam3;
					data_exam40<=data_exam4;
				end
	end
 
 
  
	assign example1=(hcount[10:1]>=210&&hcount[10:1]<310&&vcount>=80&&vcount<180);
	assign example2=(hcount[10:1]>=330&&hcount[10:1]<430&&vcount>=80&&vcount<180);
	assign example3=(hcount[10:1]>=210&&hcount[10:1]<310&&vcount>=200&&vcount<300);
	assign example4=(hcount[10:1]>=330&&hcount[10:1]<430&&vcount>=200&&vcount<300);
	assign wel_ins =(hcount[10:1]>=170&&hcount[10:1]<470&&vcount>=320&&vcount<410); 


 //-----------------------------welcome window four example---------------------
	logic[13:0] addr_exam1_wel, addr_exam2_wel, addr_exam3_wel, addr_exam4_wel; 
	
	always@(negedge clk50)
		begin
			if (reset)
				begin
					addr_exam1_wel<=0;
					addr_exam2_wel<=0;
					addr_exam3_wel<=0;
					addr_exam4_wel<=0;
				end
			else if (example1)
					addr_exam1_wel<=(vcount-80)*100 + (hcount[10:1]-210);
		   else if (example2)
					addr_exam2_wel<=(vcount-80)*100 + (hcount[10:1]-330);
			else if (example3)
					addr_exam3_wel<=(vcount-200)*100 + (hcount[10:1]-210);
			else if (example4)
					addr_exam4_wel<=(vcount-200)*100 + (hcount[10:1]-330);
			else if (wel_ins)
					addr_wel_ins<=(vcount-320)*300 + (hcount[10:1]-170);
		end//endalways
 
	  
	always@(negedge clk50)
		begin
			if (reset)
				addr_rom_bg<=0;
			else if (!incursor&& q_a==0 && hcount[10:1]>55 && hcount[10:1]<320 && vcount>=0 && vcount<240)
				addr_rom_bg<=(239-vcount)*270+319-hcount[10:1];
			else if (!incursor&& q_a==0&& hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=0 && vcount<240)
				addr_rom_bg<=(239-vcount)*270+hcount[10:1]-320;
			else if (!incursor&&q_a==0 && hcount[10:1]>55 && hcount[10:1]<320 && vcount>=240 && vcount<480)
				addr_rom_bg<=(vcount-240)*270+319-hcount[10:1];
			else if (!incursor&& q_a==0 && hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=240 && vcount<480)
				addr_rom_bg<=(vcount-240)*270+hcount[10:1]-320;
			else 
				addr_rom_bg<=addr_rom_bg;
	  end

 //----------------------------------------example_ref choose--------------------------------
	logic example_ref;
	logic [7:0] data_ref;
	logic [13:0]  addr_exam1_dis,addr_exam2_dis,addr_exam3_dis,addr_exam4_dis;
	assign example_ref=(hcount[10:1]>=120&&hcount[10:1]<220&&vcount>=190&&vcount<290);
  
	always@* 
		begin
			if (hex11==1)
				begin
					addr_exam1_dis=(vcount-190)*100+hcount[10:1]-120;
					data_ref=data_exam1;
				end
			else if (hex11==2)
				begin
					addr_exam2_dis=(vcount-190)*100+hcount[10:1]-120;
					data_ref=data_exam2;
				end
			else if (hex11==3)
				begin
					addr_exam3_dis=(vcount-190)*100+hcount[10:1]-120;
					data_ref=data_exam3;
				end
			else if (hex11==4)
				begin
					addr_exam4_dis=(vcount-190)*100+hcount[10:1]-120;
					data_ref=data_exam4;
				end
		end// end always
 
 //------------------------------mux to choose addr_exam--------------------
 
	always@*
		begin
			if (hex10==0) 
				begin
					addr_exam1=addr_exam1_wel;
					addr_exam2=addr_exam2_wel;
					addr_exam3=addr_exam3_wel;
					addr_exam4=addr_exam4_wel;
				end
			else if (hex10==1)
				begin
					addr_exam1=addr_exam1_dis;
					addr_exam2=addr_exam2_dis;
					addr_exam3=addr_exam3_dis;
					addr_exam4=addr_exam4_dis;
				end
		end //endalways 

 //------------------------------win or keep doing-------------------------------------------
	logic         inslogan;
	logic [7:0]   data_slogan;
	assign inslogan=(hex12!=0&&(hcount[10:1]>=170&&hcount[10:1]<470&&vcount>=225&&vcount<255));
 
 
	always@(negedge clk50) 
		begin
			if (reset)
				begin
					addr_slogan<=0;
					data_slogan<=0;
				end
			else if (hex12==1&& inslogan)
				begin
					addr_slogan<= (vcount-225)*300+hcount[10:1]-170;
					data_slogan <= data_rom_win;
				end
			else if (hex12==2 && inslogan)
				begin
					addr_slogan <= (vcount-225)*300+hcount[10:1]-170;
					data_slogan <= data_rom_keep;
				end
		end // always
  
  
//--------------------------------instruction display------------------------------------------  
	logic inins;
	assign inins=(hcount[10:1]>=220&&hcount[10:1]<420&&vcount>=395&&vcount<435);
 
	always @(negedge clk50)
		begin
			if (reset)
				addr_ins<=0;
			else if (inins)
				addr_ins<=(vcount-395)*200+hcount[10:1]-220;
			else 
				addr_ins<=addr_ins;
		end//endalways
  
//--------------------------------display on VGA ------------------------------------------------

	
   always@*
		begin
			{VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // Black
			if (hex10==0)
				begin
					if (sel_circle)
						{VGA_R, VGA_G, VGA_B} = {8'hb0,8'h0,8'h0};
					else if (example1&&!sel_circle)
						{VGA_R, VGA_G, VGA_B} = {data_exam10,data_exam10, data_exam10};
					else if (example2&&!sel_circle)
						{VGA_R, VGA_G, VGA_B} = {data_exam20,data_exam20, data_exam20};
					else if (example3&&!sel_circle)
						{VGA_R, VGA_G, VGA_B} = {data_exam30,data_exam30, data_exam30};
					else if (example4&&!sel_circle)
						{VGA_R, VGA_G, VGA_B} = {data_exam40,data_exam40, data_exam40};
					else if (wel_ins&&data_wel_ins!=0)
						{VGA_R, VGA_G, VGA_B} = {data_wel_ins,data_wel_ins, data_wel_ins};
					else if (wel_ins&&data_wel_ins==0)
						{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
					else if ( hcount[10:1]>55 && hcount[10:1]<320 && vcount>=0 && vcount<240)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if ( hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=0 && vcount<240)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if ( hcount[10:1]>55 && hcount[10:1]<320 && vcount>=240 && vcount<480)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if ( hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=240 && vcount<480)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
				end
			else if (hex10==1)
				begin
					if (inslogan&&hex12==1&&data_slogan>=100)
						{VGA_R, VGA_G, VGA_B} = {data_slogan, 8'h0, 8'h0}; 
					else if   (inslogan&&hex12==2&&data_slogan>=100)
						{VGA_R, VGA_G, VGA_B} = {8'd2, 8'd147, 8'd230}; 
					else if (example_ref && data_ref!=0)
						{VGA_R, VGA_G, VGA_B} = {data_ref,data_ref, data_ref}; 
					else if (incursor)
						{VGA_R, VGA_G, VGA_B} = {8'hff, 8'h0, 8'h0}; 
					else  if (inwin && q_a!=0 && q_a!=(gray_hl-2)&&q_a!=gray_hl&&q_a!=(gray_hl+2))
						{VGA_R, VGA_G, VGA_B} = {q_a, q_a, q_a}; //read win gray scale 
					else if (inins && q_a==0 && data_rom_ins!=0)
						{VGA_R, VGA_G, VGA_B} = {data_rom_ins,data_rom_ins, data_rom_ins}; //read win gray scale 
					else if(inwin && (q_a==(gray_hl-2)||q_a==gray_hl||q_a==(gray_hl+2)))
						{VGA_R, VGA_G, VGA_B} = {8'd20, 8'd20, 8'd20};
					else if ( q_a==0 && hcount[10:1]>55 && hcount[10:1]<320 && vcount>=0 && vcount<240)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if (!incursor&& q_a==0 && hcount[10:1]>=320 && hcount[10:1]<590&&vcount>=0 && vcount<240)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if (!incursor&&q_a==0 && hcount[10:1]>55 && hcount[10:1]<320 && vcount>=240 && vcount<480)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if (!incursor&& q_a==0 && hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=240 && vcount<480)
						begin
							{VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
						end
					else if (data_rom_bg==0)
						{VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // Black
					else 
						{VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0};
				end  
		end
 

 
endmodule // VGA_LED_Emulator
