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

module VGA_LED_Emulator(
 input logic 	    clk50, reset,
 input logic [7:0]  hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7,
 output logic [7:0] VGA_R, VGA_G, VGA_B,
 output logic 	    VGA_CLK, VGA_HS, VGA_VS, VGA_BLANK_n, VGA_SYNC_n);

/*
 * 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 radius_square = 20'd 1024;
 
   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 [10:0]			     hcount; // Horizontal counter
   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 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) );   

   assign VGA_CLK = hcount[0]; // 25 MHz clock: pixel latched on rising edge
 





 
  
		/*added by cong*/
		logic					inEdge; 
//		logic					inSurface;					
	
		integer 				x;
		integer 				y;
		integer 				z;
		integer 				x_r1;
		integer 				y_r1;
		integer	 			z_r1;
		integer 				x_r2;
		integer 				y_r2;
		integer	 			z_r2;
		integer				x0;
				
		integer				sin_x;
		integer				cos_x;
		integer				sin_y;
		integer				cos_y;

		reg[7:0]				scan_count;
		reg[255:0][1:0]		plane;

		/*object information*/		
		integer	x1 = 50;
		integer	x2 = 140;
		integer	y1 = 60;
		integer	y2 = 150;
		integer	z1 = 90;
		integer	z2 = 160;


//		assign inSurface  ;
		assign inEdge = (&plane[hcount[10:1]]);// && hcount >= 11'd235 && hcount <= 11'd511;


		
		always_ff @(posedge clk50) begin
			if (hcount == 11'd 1280) begin
				scan_count <= 0;
				for (x = 0; x < 256; x++) plane[x] <= 2'b0;
			end
			else if (scan_count != 8'b1111111111) begin
				scan_count <= scan_count + 8'd1;		
				for (x = 0; x < 256; x++) begin
						x0 = x - 128;
						x_r1 = x0;
						y_r1 = (cos_x*y - sin_x*z)>>10;
						z_r1 = (sin_x*y + cos_x*z)>>10;
						
						x_r2 = (sin_y*z_r1 + cos_y*x_r1)>>10;
						y_r2 = y_r1;
						z_r2 = (cos_y*z_r1 - sin_y*x_r1)>>10;
						
//					
//						if (plane[x] == 2'b0) plane[x][0] <= 	(x_r2[7:1] == x1[7:1] || x_r2[7:1] == x2[7:1]) && y_r2[7:1] >= y1[7:1] && y_r2[7:1] <= y2[7:1] && z_r2[7:1] >= z1[7:1] && z_r2[7:1] <= z2[7:1] ||
//																			(y_r2[7:1] == y1[7:1] || y_r2[7:1] == y2[7:1]) && z_r2[7:1] >= z1[7:1] && z_r2[7:1] <= z2[7:1] && x_r2[7:1] >= x1[7:1] && x_r2[7:1] <= x2[7:1] ||
//																			(z_r2[7:1] == z1[7:1] || z_r2[7:1] == z2[7:1]) && x_r2[7:1] >= x1[7:1] && x_r2[7:1] <= x2[7:1] && y_r2[7:1] >= y1[7:1] && y_r2[7:1] <= y2[7:1];	
//						
//						if (plane[x] == 2'b0) plane[x][1] <= 	(x_r2[7:1] == x1[7:1] || x_r2[7:1] == x2[7:1]) && (y_r2[7:1] == y1[7:1] || y_r2[7:1] == y2[7:1]) && z_r2[7:1] >= z1[7:1] && z_r2[7:1] <= z2[7:1] ||
//																			(y_r2[7:1] == y1[7:1] || y_r2[7:1] == y2[7:1]) && (z_r2[7:1] == z1[7:1] || z_r2[7:1] == z2[7:1]) && x_r2[7:1] >= x1[7:1] && x_r2[7:1] <= x2[7:1] ||
//																			(z_r2[7:1] == z1[7:1] || z_r2[7:1] == z2[7:1]) && (x_r2[7:1] == x1[7:1] || x_r2[7:1] == x2[7:1]) && y_r2[7:1] >= y1[7:1] && y_r2[7:1] <= y2[7:1];				
//							
						if (plane[x] == 2'b0) plane[x][0] <= 	(x_r2 == x1 || x_r2 == x2) && y_r2 >= y1 && y_r2 <= y2 && z_r2 >= z1 && z_r2 <= z2 ||
																			(y_r2 == y1 || y_r2 == y2) && z_r2 >= z1 && z_r2 <= z2 && x_r2 >= x1 && x_r2 <= x2 ||
																			(z_r2 == z1 || z_r2 == z2) && x_r2 >= x1 && x_r2 <= x2 && y_r2 >= y1 && y_r2 <= y2;	
						
						if (plane[x] == 2'b0) plane[x][1] <= 	(x_r2 == x1 || x_r2 == x2) && (y_r2 == y1 || y_r2 == y2) && z_r2 >= z1 && z_r2 <= z2 ||
																			(y_r2 == y1 || y_r2 == y2) && (z_r2 == z1 || z_r2 == z2) && x_r2 >= x1 && x_r2 <= x2 ||
																			(z_r2 == z1 || z_r2 == z2) && (x_r2 == x1 || x_r2 == x2) && y_r2 >= y1 && y_r2 <= y2;								
				end
			end	
		end
		
		
		always_comb begin
		
			sin_x = {hex1[1:0], hex0};
			cos_x = {hex3[1:0], hex2};
			sin_y = {hex5[1:0], hex4};
			cos_y = {hex7[1:0], hex6};
		
			z = scan_count - 128;
			y = vcount[9:0] - 128;
			
			{VGA_R, VGA_G, VGA_B} = {8'hFF, 8'hFF, 8'hFF}; // white	
			if (inEdge)
				{VGA_R, VGA_G, VGA_B} = {8'h0, 8'h0, 8'h0}; // black
		end  
   
endmodule // VGA_LED_Emulator





module VGA_LED_Emulator_tb();

	integer				sin_x;

initial begin 
	integer = 100;
	&display("result: %0d", sin_x);
end

endmodule

end


