/*
 * Seven-segment LED emulator
 *
 * Stephen A. Edwards, Columbia University
 *
 */

module VGA_LED_Emulator(
 input logic 	    clk50, reset,
 //input logic [15:0] x,
 //input logic [15:0]  y,
 input logic [15:0]  hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7,
 
 input logic  [7:0] VGA_R_tankup, VGA_G_tankup, VGA_B_tankup,
 input logic  [7:0] VGA_R_brick, VGA_G_brick, VGA_B_brick,
 input logic  [7:0] VGA_R_grass, VGA_G_grass, VGA_B_grass,
 input logic  [7:0] VGA_R_water, VGA_G_water, VGA_B_water,
 input logic  [7:0] VGA_R_steel, VGA_G_steel, VGA_B_steel,
 input logic  [7:0] VGA_R_homebase, VGA_G_homebase, VGA_B_homebase,
	/*flag*/
input	logic               tank_up,//     flag for tank_down
input	logic               brick,//
input	logic               grass,
input logic               water,
input logic               steel,
input logic               homebase,
input logic               grey_background,
//input logic          test,

 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 [9:0] 			     vcount,
 output    logic [10:0]			     hcount);

/*
 * 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          |____|
 */

   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

   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 			     endOfLine;
	


   
   always_ff @(posedge clk50 or posedge reset)
     if (reset)         begin
                       hcount <= 0;
							  end
	                        
     else if (endOfLine) hcount <= 0;
     else  	          begin
	                   hcount <= hcount + 11'd 1;
						    end	 

   assign endOfLine = hcount == HTOTAL - 1;

   // Vertical counter
   logic 			     endOfField;
   
   always_ff @(posedge clk50 or posedge reset)
     if (reset)        begin
	                      vcount <= 0;

							  end
     else if (endOfLine)
	    begin
       if (endOfField)   vcount <= 0;
       else         begin     
		              vcount <= vcount + 10'd 1;
	
						  end
		end			  

   assign endOfField = vcount == VTOTAL - 1;
	
	
	/* judge the flag */
	
	
/*	assign tank_down= (hcount<11'd 64)&(vcount<10'd 32);
	assign brick= (hcount>=11'd 704)&(hcount<=11'd 767)&(vcount<10'd 32);
   assign grass= (((hcount>=11'd 384)&(hcount<=11'd 575)&(vcount>=10'd 96)&(vcount<=10'd 159))
	              ||((hcount>=11'd 512)&(hcount<=11'd 575)&(vcount>=10'd 160)&(vcount<=10'd 191))
					  ||((hcount>=11'd 64)&(hcount<=11'd 191)&(vcount>=10'd 192)&(vcount<=10'd 255))
					  ||((hcount>=11'd 192)&(hcount<=11'd 255)&(vcount>=10'd 224)&(vcount<=10'd 255))
					  ||((hcount>=11'd 320)&(hcount<=11'd 447)&(vcount>=10'd 288)&(vcount<=10'd 255))
					  ||((hcount>=11'd 320)&(hcount<=11'd 383)&(vcount>=10'd 320)&(vcount<=10'd 383))
					  ||((hcount>=11'd 576)&(hcount<=11'd 703)&(vcount>=10'd 288)&(vcount<=10'd 383))
					  ||((hcount>=11'd 320)&(hcount<=11'd 447)&(vcount>=10'd 288)&(vcount<=10'd 319))
					  );
   
*/	
	
	// Horizontal sync: from 0x520 to 0x57F
   // 101 0010 0000 to 101 0111 1111
   assign VGA_HS = !( (hcount[10:7] == 4'b1010) & (hcount[6] | hcount[5]));
   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) );   

   /* 
    *    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
    */

   logic 			     inChar; // In any character

   assign inChar = (vcount[9:7] == 3'd1) &
		   (hcount[10:7] != 4'd0 & hcount[10:7] != 4'd9);
   
   logic [2:0] 			     charx; // Coordinate within the 8x16 char
   logic [3:0] 			     chary;

   assign charx = hcount[6:4];
   assign chary = vcount[6:3];

   logic horizBar, leftCol, rightCol, topCol, botCol; // Parts of the disp.

   assign horizBar = !(charx[2:1] == 2'b11);  // When in any horizontal bar
   assign leftCol  = (charx == 3'd0);         // When in left column
   assign rightCol = (charx == 3'd5);         // When in right column
   assign topCol   = !chary[3] & !(chary[2:0] == 3'd7); // Top columns
   assign botCol   = (chary >= 4'd6) & (chary <= 4'd12); // Bottom columns

   logic [7:0] segment; // True when in each segment
   assign segment[0] = horizBar & (chary == 4'd 0);
   assign segment[1] = rightCol & topCol;
   assign segment[2] = rightCol & botCol;
   assign segment[3] = horizBar & (chary == 4'd 12);
   assign segment[4] = leftCol & botCol;
   assign segment[5] = leftCol & topCol;
   assign segment[6] = horizBar & (chary == 4'd 6);
   assign segment[7] = (charx == 3'd6) & (chary == 4'd14);

   logic [2:0] column; // Being displayed
   assign column = hcount[9:7];
   
   logic [7:0] curSegs;
   assign curSegs = column == 3'd1 ? hex0 :
		    column == 3'd2 ? hex1 :
		    column == 3'd3 ? hex2 :
		    column == 3'd4 ? hex3 :
		    column == 3'd5 ? hex4 :
		    column == 3'd6 ? hex5 :
		    column == 3'd7 ? hex6 :
		    hex7;

   assign VGA_CLK = hcount[0]; // 25 MHz clock: pixel latched on rising edge
   
   always_comb begin
      {VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // Black
     // if (inChar)
	//if (test)
	//  {VGA_R, VGA_G, VGA_B} = {8'h0, 8'haa, 8'h0};  
	if(grey_background)                                      //sprite priority up to down
	  {VGA_R, VGA_G, VGA_B} = {8'd192, 8'd192, 8'd192};
	if (tank_up) // In any active segment?
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_tankup, VGA_G_tankup, VGA_B_tankup}; 
	if (brick) // In any active segment?
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_brick, VGA_G_brick, VGA_B_brick}; 
	if (grass)
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_grass, VGA_G_grass, VGA_B_grass};
   if (water)
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_water, VGA_G_water, VGA_B_water};
	 if (steel)
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_steel, VGA_G_steel, VGA_B_steel};
	 if (homebase)
	  {VGA_R, VGA_G, VGA_B} = {VGA_R_homebase, VGA_G_homebase, VGA_B_homebase};
   end  
   
endmodule // VGA_LED_Emulator
