


module VGA_LED_Emulator(
 input logic 	    clk50, reset,
 input logic [7:0]  hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7,
 input logic [7:0]  q_a,
 input logic  [7:0] data_rom_bg,
 input logic  [9:0] cursor_x, cursor_y,
 
 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
 );
/*
 * 640 X 480 VGA timing for a 50 MHz clock: one pixel every other cycle
 * 
 * HCOUNT 1599 0             1279       1599 0
 *             _______________              ________
 * ___________|    Video      |____________|  Video
 * 
 * 
 * |SYNC| BP |<-- HACTIVE -->|FP|SYNC| BP |<-- HACTIVE
 *       _______________________      _____________
 * |____|       VGA_HS          |____|
 */
   // Parameters for hcount
   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; // 1600
   
   // Parameters for vcount
   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; // 525

   //logic [10:0]			     hcount; // Horizontal counter
                                             // Hcount[10:1] indicates pixel column (0-639)
   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;

   // Vertical counter
  // logic [9:0] 			     vcount;
   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;

   // Horizontal sync: from 0x520 to 0x5DF (0x57F)
   // 101 0010 0000 to 101 1101 1111
   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; // For adding sync to video signals; not used for VGA
   
   // Horizontal active: 0 to 1279     Vertical active: 0 to 479
   // 101 0000 0000  1280	       01 1110 0000  480
   // 110 0011 1111  1599	       10 0000 1100  524
   assign VGA_BLANK_n = !( hcount[10] & (hcount[9] | hcount[8]) ) &
			!( vcount[9] | (vcount[8:5] == 4'b1111) );   

   /* VGA_CLK is 25 MHz
    *             __    __    __
    * clk50    __|  |__|  |__|
    *        
    *             _____       __
    * hcount[0]__|     |_____|
    */
   assign VGA_CLK = hcount[0]; // 25 MHz clock: pixel latched on rising edge
   assign clk25 = VGA_CLK;
   /* 
    *    0 1 2 3 4 5 6 7
    * 
    * 0  afa a a a ab
    * 1  f         b
    * 2  f         b
    * 3  f         b
    * 4  f         b
    * 5  f         b
    * 6 efgggggggggbc 
    * 7  e         c
    * 8  e         c
    * 9  e         c
    * 10 e         c
    * 11 e         c
    * 12 edddddddddc
    * 13
    * 14             h
    * 15
    *
    * 640 x 480
    * 
    * Each seven-segment "pixel" is 8x8: 64 pixels across, 512 pixels for
    * 8 characters being displayed
    * 64 + 512 + 64 = 640  Start in column 64, end in column 576
    * 
    * 128 pixels high: start at row 128, end at row 256
    * 128 + 128 + 224 = 480  Start in row 128
    */
	 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;
		// address_a = ((vcount-10)%win_h)*win_w + (hcount[10:1]-170); 
		   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----------------------------------	
	logic[12:0] counter_hl ;
	logic[8:0]  gray_hl;
	
   always@(posedge VGA_CLK)begin
		if (reset) begin
		counter_hl<=13'd0;
		gray_hl<=8'd220;
		end
		else if (counter_hl<13'd8191&&gray_hl>8'd20)begin
		counter_hl<=counter_hl+'d1;
		gray_hl<=gray_hl;
		end
		else if (counter_hl<13'd8191&&gray_hl<=8'd20)begin
		counter_hl<=counter_hl+'d1;
		gray_hl<=gray_hl;
		end
		else if (counter_hl==13'd8191&&gray_hl>8'd20)begin
		counter_hl<=0;
		gray_hl<=gray_hl-8'd2;
		end
		else if (counter_hl==13'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);

//--------------------------------display on VGA ------------------------------------------------

	
   always@* begin
		  
	 {VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // Black

	 if (incursor)
	// if(cursor)
	 {VGA_R, VGA_G, VGA_B} = {8'hff, 8'h0, 8'h0}; 
	 
	 
    else  if (!incursor&&inwin && 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(!incursor&&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 (!incursor&&!inwin && hcount[10:1]>=50 && hcount[10:1]<320 && vcount>=0 && vcount<240)begin
	  addr_rom_bg=(239-vcount)*270+319-hcount[10:1];
     {VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
	  end

	  else if (!incursor&&!inwin && hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=0 && vcount<240)begin
	  addr_rom_bg=(239-vcount)*270+hcount[10:1]-320;
     {VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
     end

	  else if (!incursor&&!inwin && hcount[10:1]>=50 && hcount[10:1]<320 && vcount>=240 && vcount<480)begin
	  addr_rom_bg=(vcount-240)*270+319-hcount[10:1];
     {VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
     end
	 
	 else if (!incursor&&!inwin && hcount[10:1]>=320 && hcount[10:1]<590 && vcount>=240 && vcount<480)begin
	  addr_rom_bg=(vcount-240)*270+hcount[10:1]-320;
     {VGA_R, VGA_G, VGA_B} = {data_rom_bg, data_rom_bg, data_rom_bg};
     end
	
	else 
	  {VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // Black

	 
    end  
   
endmodule // VGA_LED_Emulator
