/*
 * Avalon memory-mapped peripheral for the VGA LED Emulator
 *
 * Stephen A. Edwards
 * Columbia University
 */

module VGA_LED(input logic        clk,
	       input logic 	  reset,
	       input logic [15:0]  writedata,
	       input logic 	  write,
	       input 		  chipselect,
	       input logic        address,


	       output logic [7:0] VGA_R, VGA_G, VGA_B,
	       output logic 	  VGA_CLK, VGA_HS, VGA_VS, VGA_BLANK_n,
	       output logic 	  VGA_SYNC_n);

	 
          logic [15:0]	  hex0, hex1, hex2, hex3,
				              hex4, hex5, hex6, hex7;
			 //logic [15:0]  x;
			 //logic [15:0]  y;
			 logic [10:0] tank_x=11'd320;
			 logic [9:0]  tank_y=10'd416;
			 
			 
			 logic  [10:0] sprite_tankup_addr;
			 logic  [10:0] sprite_brick_addr;
			 logic  [10:0] sprite_grass_addr;
			 logic  [10:0] sprite_water_addr;
			 logic  [10:0] sprite_steel_addr;
			 logic  [10:0] sprite_homebase_addr;
			 
			 logic  [23:0] sprite_tankup_data;
			 logic  [23:0] sprite_brick_data;
			 logic  [23:0] sprite_grass_data;
			 logic  [23:0] sprite_water_data;
			 logic  [23:0] sprite_steel_data;
			 logic  [23:0] sprite_homebase_data;
			 
			 logic  [7:0] VGA_R_tankup, VGA_G_tankup, VGA_B_tankup;
			 logic  [7:0] VGA_R_brick, VGA_G_brick, VGA_B_brick;
			 logic  [7:0] VGA_R_grass, VGA_G_grass, VGA_B_grass;
			 logic  [7:0] VGA_R_water, VGA_G_water, VGA_B_water;
			 logic  [7:0] VGA_R_steel, VGA_G_steel, VGA_B_steel;
			 logic  [7:0] VGA_R_homebase, VGA_G_homebase, VGA_B_homebase;
			 /*flag for offset*/
		//	 logic                    grass_flag;
			 logic                    grass;
			 logic                    tank_down;
			 logic 						  tank_up;
			 logic                    brick;
			 logic                    water;
			 logic                    steel;
			 logic                    homebase;
			 logic						  grey_background;

			 
			// logic  [9:0] 			     vcount_steel_offset;
         //logic  [10:0]			     hcount_steel_offset;
			 
			 
			 logic  [9:0] 			     vcount;
          logic  [10:0]			     hcount;


       
   VGA_LED_Emulator led_emulator(.clk50(clk), .*);
	tank1_up tankup_draw(.address(sprite_tankup_addr),	.clock(clk),.q(sprite_tankup_data));
   brick16   brick_draw(.address(sprite_brick_addr),.clock(clk),.q(sprite_brick_data));
	grass   grass_draw(.address(sprite_grass_addr),.clock(clk),.q(sprite_grass_data));
	water   water_draw(.address(sprite_water_addr),.clock(clk),.q(sprite_water_data));
	steel   steel_draw(.address(sprite_steel_addr),.clock(clk),.q(sprite_steel_data));
	homebase   homebase_draw(.address(sprite_homebase_addr),.clock(clk),.q(sprite_homebase_data));
	
	//always_ff @(posedge clk or posedge reset)
	//begin
	/*if (reset)        
       begin
	      sprite_x <= 0;
	      sprite_y <= 0;
		
       end  */
	//if (reset !=0)
	  /* begin
         int sprite_i, sprite_j;	     
         for (sprite_i=0; sprite_i<32;sprite_i++)
		     begin
			    for (sprite_j=0; sprite_j<40; sprite_j++)
				   begin
				    sprite_y <= sprite_i;
					 sprite_x <= sprite_j;
					 					 end
			  end 
		 end	  
	end
  */
  
  /* tankdown
	assign VGA_B1= sprite_data[7:0];
	assign VGA_G1= sprite_data[15:8];
	assign VGA_R1= sprite_data[23:16];
	assign sprite_addr=hcount/2+vcount*32;
	  birck
	assign VGA_B_brick= sprite_brick_data[7:0];
	assign VGA_G_brick= sprite_brick_data[15:8];
	assign VGA_R_brick= sprite_brick_data[23:16];
   assign sprite_brick_addr=(hcount-11'd704)/2+vcount*32;*/
	
	//logic test;
	
	/*Draw block*/



				 
	always @ ( hcount||vcount )
	 begin


	  /* judge the flag */
	
	 homebase= (hcount>=11'd 448)&(hcount<=11'd 511)&(vcount>=10'd 416)&(vcount<=10'd 447);
	 //tank_up= (hcount>=11'd 320)&(hcount<=11'd 383)&(vcount>=10'd 416)&(vcount<=10'd 447);
	 tank_up= (hcount>=tank_x)&(hcount<=(tank_x+11'd 63))&(vcount>=tank_y)&(vcount<=(tank_y+10'd 31));
	 //brick
    brick= (((hcount>=11'd 704)&(hcount<=11'd 767)&(vcount>=10'd 32)&(vcount<=10'd 63))
	              ||((hcount>=11'd 128)&(hcount<=11'd 191)&(vcount>=10'd 64)&(vcount<=10'd 95))
					  ||((hcount>=11'd 512)&(hcount<=11'd 575)&(vcount>=10'd 64)&(vcount<=10'd 95))
					  ||((hcount>=11'd 320)&(hcount<=11'd 383)&(vcount>=10'd 96)&(vcount<=10'd 127))
					  ||((hcount>=11'd 704)&(hcount<=11'd 767)&(vcount>=10'd 128)&(vcount<=10'd 159))
					  ||((hcount>=11'd 192)&(hcount<=11'd 255)&(vcount>=10'd 192)&(vcount<=10'd 223))
					  ||((hcount>=11'd 768)&(hcount<=11'd 799)&(vcount>=10'd 192)&(vcount<=10'd 223))
					  ||((hcount>=11'd 128)&(hcount<=11'd 191)&(vcount>=10'd 256)&(vcount<=10'd 287))
					  ||((hcount>=11'd 384)&(hcount<=11'd 447)&(vcount>=10'd 256)&(vcount<=10'd 287))
					  ||((hcount>=11'd 768)&(hcount<=11'd 831)&(vcount>=10'd 288)&(vcount<=10'd 319))
					  ||((hcount>=11'd 192)&(hcount<=11'd 255)&(vcount>=10'd 384)&(vcount<=10'd 415))
					  ||((hcount>=11'd 320)&(hcount<=11'd 383)&(vcount>=10'd 384)&(vcount<=10'd 415))
					  ||((hcount>=11'd 64)&(hcount<=11'd 127)&(vcount>=10'd 416)&(vcount<=10'd 447))
					  ||((hcount>=11'd 640)&(hcount<=11'd 703)&(vcount>=10'd 416)&(vcount<=10'd 447))
					  ||((hcount>=11'd 416)&(hcount<=11'd 543)&(vcount>=10'd 400)&(vcount<=10'd 415))
					  ||((hcount>=11'd 416)&(hcount<=11'd 447)&(vcount>=10'd 416)&(vcount<=10'd 447))
					  ||((hcount>=11'd 512)&(hcount<=11'd 543)&(vcount>=10'd 416)&(vcount<=10'd 447))
					  );
	 //grass
    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))
					  );
	//water
	water=(((hcount>=11'd 192)&(hcount<=11'd 319)&(vcount>=10'd 64)&(vcount<=10'd 127))
	      ||((hcount>=11'd 576)&(hcount<=11'd 703)&(vcount>=10'd 96)&(vcount<=10'd 159))
			||((hcount>=11'd 320)&(hcount<=11'd 447)&(vcount>=10'd 160)&(vcount<=10'd 223))
			||((hcount>=11'd 192)&(hcount<=11'd 319)&(vcount>=10'd 256)&(vcount<=10'd 319))
			||((hcount>=11'd 448)&(hcount<=11'd 575)&(vcount>=10'd 288)&(vcount<=10'd 351))
			||((hcount>=11'd 704)&(hcount<=11'd 831)&(vcount>=10'd 320)&(vcount<=10'd 383))
				);
	//steel			
    steel=(((hcount>=11'd 384)&(hcount<=11'd 447)&(vcount>=10'd 64)&(vcount<=10'd 95))
	      ||((hcount>=11'd 768)&(hcount<=11'd 831)&(vcount>=10'd 96)&(vcount<=10'd 127))
			||((hcount>=11'd 128)&(hcount<=11'd 191)&(vcount>=10'd 160)&(vcount<=10'd 191))
			||((hcount>=11'd 448)&(hcount<=11'd 511)&(vcount>=10'd 192)&(vcount<=10'd 223))
			||((hcount>=11'd 640)&(hcount<=11'd 703)&(vcount>=10'd 224)&(vcount<=10'd 255))
			||((hcount>=11'd 832)&(hcount<=11'd 895)&(vcount>=10'd 224)&(vcount<=10'd 255))
	      ||((hcount>=11'd 64)&(hcount<=11'd 127)&(vcount>=10'd 288)&(vcount<=10'd 319))
			||((hcount>=11'd 256)&(hcount<=11'd 319)&(vcount>=10'd 352)&(vcount<=10'd 383))
			||((hcount>=11'd 704)&(hcount<=11'd 767)&(vcount>=10'd 416)&(vcount<=10'd 447))
				); 
				
	grey_background=((vcount<=31)||(vcount>=448)||(hcount<=63)||(hcount>=1088)); 
	
	

	
/*homebase*/
	if(homebase)			  
	    begin
		   /*if((hcount%11'd64==11'd0)&(vcount%10'd32==10'd0))
			   begin
	  		       hcount_offset=hcount;
		          vcount_offset=vcount;
				 end*/
	       VGA_B_homebase= sprite_homebase_data[7:0];
	       VGA_G_homebase= sprite_homebase_data[15:8];
	       VGA_R_homebase= sprite_homebase_data[23:16];
	       sprite_homebase_addr=(hcount-11'd 448)/2+(vcount-10'd 416)*32;
		 end		
	
	/*tank_down*/				  
	 if(tank_up)			  
	    begin
		  /* if((hcount%11'd64==11'd0)&(vcount%10'd32==10'd0))
			   begin
	  		       hcount_offset=hcount;
		          vcount_offset=vcount;
				 end*/
	       VGA_B_tankup= sprite_tankup_data[7:0];
	       VGA_G_tankup= sprite_tankup_data[15:8];
	       VGA_R_tankup= sprite_tankup_data[23:16];
	       sprite_tankup_addr=(hcount[5:1]-tank_x[5:1])+(vcount[4:0]-tank_y[4:0])*32;
		 end					  
	 				  
	/*	brick mif:16*16 */			  
		 if (brick) 
	   begin

         VGA_B_brick= sprite_brick_data[7:0];
	      VGA_G_brick= sprite_brick_data[15:8];
	      VGA_R_brick= sprite_brick_data[23:16];
         sprite_brick_addr=hcount[4:1]+vcount[3:0]*16;
	
		 end 


		
	/*grass*/  
	 if (grass) 
	    begin
		   /* if((hcount%11'd64==11'd0)&(vcount%10'd32==10'd0))
			    begin
	  		       hcount_offset=hcount;
		          vcount_offset=vcount;
				 end*/
	        VGA_B_grass= sprite_grass_data[7:0];
	        VGA_G_grass= sprite_grass_data[15:8];
	        VGA_R_grass= sprite_grass_data[23:16];
	        sprite_grass_addr=hcount[5:1]+vcount[4:0]*32;
		 end
	/*water*/
    if(water)
	     begin
		   /* if((hcount%11'd64==11'd0)&(vcount%10'd32==10'd0))
			    begin
	  		       hcount_offset=hcount;
		          vcount_offset=vcount;
				 end*/
	        VGA_B_water= sprite_water_data[7:0];
	        VGA_G_water= sprite_water_data[15:8];
	        VGA_R_water= sprite_water_data[23:16];
	        sprite_water_addr=hcount[5:1]+vcount[4:0]*32;
		 end 
	/*steel*/
    if(steel)
	     begin
		    /*if((hcount%11'd64==11'd0)&(vcount%10'd32==10'd0))
			    begin
	  		       hcount_steel_offset=hcount;
		          vcount_steel_offset=vcount;
				 end*/
	        
			  VGA_B_steel= sprite_steel_data[7:0];
	        VGA_G_steel= sprite_steel_data[15:8];
	        VGA_R_steel= sprite_steel_data[23:16];
	        sprite_steel_addr=hcount[5:1]+vcount[4:0]*32;
		 end  	
		 
		 
	end
	
	
    always_ff @(posedge clk) begin 
	  if(reset) begin
	    tank_x<=11'd320;
		 tank_y<=10'd416;
		end
	  else if (chipselect && write)          //use enable signal
      case(address)
        1'd0: tank_x<=writedata;
        1'd1: tank_y<=writedata;
		  
      endcase

   //tank_x<=hex0;
	//tank_y<=hex1;
     end
	/*  if(((hcount==11'd 384)&(vcount==10'd 96))||((hcount==11'd 384)&(vcount==10'd 96))||((hcount==11'd 512)&(vcount==10'd 160))||((hcount==11'd 64)&(vcount==10'd 192))
	     ||((hcount==11'd 192)&(vcount==10'd 224))||((hcount==11'd 320)&(vcount==10'd 320))||((hcount==11'd 576)&(vcount==10'd 288))
		  ||((hcount==11'd 320)&(vcount==10'd 288)) )
	  begin
      	grass_flag=1'd1;
		   hcount_grass_offset=hcount;
		   vcount_grass_offset=vcount;
	  end
	  
	if(grass_flag==1'd1)
	  begin
 	     VGA_B_grass= sprite_grass_data[7:0];
	     VGA_G_grass= sprite_grass_data[15:8];
	     VGA_R_grass= sprite_grass_data[23:16];
	     sprite_grass_addr=(hcount-hcount_grass_offset)/2+(vcount-vcount_grass_offset)*32;
	  end
	 end*/
	//always_comb
	//begin

      
  //end
	/*else if((hcount>=11'd 512)&(hcount<=11'd 575)&(vcount>=10'd 160)&(vcount<=10'd 191))
	    assign sprite_grass_addr=(hcount-11'd512)/2+(vcount-10'd160)*32;
	else if((hcount>=11'd 64)&(hcount<=11'd 191)&(vcount>=10'd 192)&(vcount<=10'd 255))
	    assign sprite_grass_addr=(hcount-11'd64)/2+(vcount-10'd192)*32;
	else if((hcount>=11'd 192)&(hcount<=11'd 255)&(vcount>=10'd 224)&(vcount<=10'd 255))
	    assign sprite_grass_addr=(hcount-11'd192)/2+(vcount-10'd224)*32;	
	   end*/
	//assign x=sprite_x;
	//assign y=sprite_y;
	       
endmodule
