/*
 * Avalon memory-mapped peripheral for the VGA LED Emulator
 *
 * XiaoWen Han
 * MuQing Liu
 * Hao Jin
 * Chengxue Qian
 * Columbia University
 */

module VGA_LED(
					input logic         clk,
					input logic   	     reset,
					input logic  [7:0]  writedata,
					input logic 	     write,
					input 		        chipselect,
					input logic  [3:0]  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 [7:0] 		hex0,hex1,hex2,hex3,hex4,hex5,hex6, 
							hex7,hex8,hex9,hex10,hex11,hex12;
	logic [14:0]      address_a,address_b;
	logic [7:0]       data_a,data_b;
	logic             rden_a,rden_b,wren_a,wren_b;
	logic [7:0]       q_a,q_b;
	logic             clk25; ///vga_emulator
   logic [8:0]       y_in;
	logic [9:0]       y_in_buf;
	logic [7:0]       data_rom_f,data_rom_b;//gray rom output
	logic [7:0]			data_rom_h;
   logic [13:0]      addr_rom_f,addr_rom_b; //gray rom address
	logic [12:0]      addr_rom_h; //height rom address
	logic             ready,enable,valid_y_in_buf;
	logic [9:0]       vcount;
	logic [10:0]      hcount;
   logic [7:0]       x_in;
	logic             rden_x_in;
	logic [7:0]       addr_rom_xin;
	logic [15:0]      addr_rom_bg;
	logic [7:0]       data_rom_bg;
	logic [9:0]       cursor_x,cursor_y;
	
//--------------------- logic for welcome-------------------------------------------	
  logic [7:0] 			data_exam1,data_exam2,data_exam3,data_exam4,data_wel_ins;
  logic [13:0] 		addr_exam1,addr_exam2,addr_exam3,addr_exam4;
  logic [14:0] 		addr_wel_ins;
	
//----------------------logic for slogan-------------------------------------------
  logic [7:0]  		data_rom_win,data_rom_keep;
  logic [13:0]  		addr_slogan;
  logic [12:0]  		addr_ins;
  logic [7:0]   		data_rom_ins; 
	
	parameter y_in_st=100;
	
	assign valid_y_in_buf = (ready&& (y_in_buf>=vcount+37)&&(y_in_buf<=vcount+40));
	
	
	always@(posedge ready or posedge reset) 
		begin
			if (reset)
				y_in_buf<=y_in_st;
			else if (addr_rom_xin<=138 && (y_in_buf>380||y_in_buf<100))
				y_in_buf<=y_in_st;
			else if (addr_rom_xin<=138 && y_in_buf<=380&&y_in_buf>=100)
				y_in_buf<=y_in_buf+'d2;
			else if (addr_rom_xin>=139 && (y_in_buf>380||y_in_buf<100))
				y_in_buf<=y_in_st;
			else if (addr_rom_xin>=139 && y_in_buf<=380&&y_in_buf>=100)
				y_in_buf<=y_in_st;
			else 
				y_in_buf<=y_in_buf;
		end //end always
   
	
	
//--------------------------------------modify y_in----------------------------
	
	always@(negedge clk) 
		begin
			if (reset)
				begin
					addr_rom_xin<=0;
					y_in<=y_in_st;
					rden_x_in<=1;
				end
			else if (ready&&valid_y_in_buf&&addr_rom_xin<=138)
				begin
					y_in<=y_in_buf;
					addr_rom_xin<=addr_rom_xin+'d1;
					rden_x_in<=1;
				end
			else if (ready&&valid_y_in_buf&&addr_rom_xin>=139)
				begin
					y_in<=y_in_buf;
					addr_rom_xin<=0;
					rden_x_in<=1;
				end
			else 
				begin
					y_in<=y_in;
					addr_rom_xin<=addr_rom_xin;
					rden_x_in<=1;
				end
		end //always 
	
	

	
   ram_win ram_win (address_a,address_b,clk,data_a,data_b,rden_a,rden_b,wren_a,wren_b,q_a,q_b);
		 	
	ellipse_draw ellipse_draw(clk,reset,clk25,x_in,y_in,data_rom_f,data_rom_b,data_rom_h,q_b,valid_y_in_buf,
	
	addr_rom_f,addr_rom_b,addr_rom_h,address_b,data_b,wren_b,rden_b,ready);
   
	rom150front rom150front(addr_rom_f,clk,data_rom_f);
	
	rom150back rom150back(addr_rom_b,clk,data_rom_b);
	
	romheight romheight(addr_rom_h,clk,data_rom_h);
	
	VGA_LED_Emulator led_emulator(.clk50(clk), .*);
	
	rom_bg rom_bg (addr_rom_bg,clk,data_rom_bg);
		
	inter_face_top inter_face_top(clk,reset,addr_rom_xin,hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7,x_in);

	rom_exam1 rom_exam1 (addr_exam1,clk,data_exam1);

	rom_exam2 rom_exam2 (addr_exam2,clk,data_exam2);

	rom_exam3 rom_exam3 (addr_exam3,clk,data_exam3);

	rom_exam4 rom_exam4 (addr_exam4,clk,data_exam4);

	rom_select_pottery rom_select_pottery (addr_wel_ins,clk,data_wel_ins);
	
	rom_win rom_win (addr_slogan,clk,data_rom_win);

	rom_keep rom_keep (addr_slogan,clk,data_rom_keep);
	
	rom_ins rom_ins (addr_ins,clk,data_rom_ins);
	
	assign cursor_x = hex8+320;
	assign cursor_y = hex9*10;


   always_ff @(posedge clk)
     if (reset) 
		begin
			hex0 <= 8'b0; 
			hex1 <= 8'b0; 
			hex2 <= 8'b0; 
			hex3 <= 8'b0; 
			hex4 <= 8'b0; 
			hex5 <= 8'b0; 
			hex6 <= 8'b0; 
			hex7 <= 8'b0; 
			hex8 <= 8'b0;
			hex9 <= 8'b0;
			hex10 <= 8'b0;
			hex11 <= 8'b0;
			hex12 <= 8'b0;
     end 
	  else if (chipselect && write)
       case (address)
			4'd0 : hex0 <= writedata;
			4'd1 : hex1 <= writedata;
			4'd2 : hex2 <= writedata;
			4'd3 : hex3 <= writedata;
			4'd4 : hex4 <= writedata;
			4'd5 : hex5 <= writedata;
			4'd6 : hex6 <= writedata;
			4'd7 : hex7 <= writedata;
			4'd8 : hex8 <= writedata;
			4'd9 : hex9 <= writedata;
			4'd10 : hex10 <= writedata;
			4'd11 : hex11 <= writedata;
			4'd12 : hex12 <= writedata;
       endcase
	       

			 
endmodule
