`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    09:28:58 11/23/2006 
// Design Name: 
// Module Name:    vgacontrol 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module vgacontrol( /* auxin, */ en, addrout, datin, r, g, b, hso, vso, clk, clk2, rst);

input clk, rst;
output clk2;

parameter addrwidth = 24;
parameter datawidth = 32;


output en;
output[addrwidth-1:0] addrout;
input[datawidth-1:0] datin;

// input[15:0] auxin;

output r, g, b, hso, vso;

reg r, g, b;

wire[10:0] dummyx;
wire[10:0] dummyy;

wire allow;
wire hs0, vs0;

syncgen syncgen0 ( .allow(allow), .xcnto(dummyx), .ycnto(dummyy), 
								.hs(hs0), .vs(vs0), .clk2(clk2), .clk(clk), .rst(rst) );


wire[7:0] cg_dob, cg_dia, gl_dob, gl_dia;
wire[7:0] cg_doa, cg_dib, gl_doa, gl_dib;


wire[10:0] cg_addrb, cg_addra;

/*
RAMB16_S9_S9 chargen_ram ( .DOA ( cg_doa ),
									.DOB ( cg_dob ),
									.DOPA ( cg_dopa ),
									.DOPB ( cg_dopb ),
									.ADDRA ( cg_addra ),
									.ADDRB ( cg_addrb ),
									.CLKA ( cg_clka ),
									.CLKB ( cg_clkb ),
									.DIA ( cg_dia ),
									.DIB ( cg_dib ),
									.DIPA ( cg_dipa ),
									.DIPB ( cg_dipb ),
									.ENA ( cg_ena ),
									.ENB ( cg_enb ),
									.SSRA ( cg_ssra ),
									.SSRB ( cg_ssrb ),
									.WEA ( cg_wea ),
									.WEB ( cg_web ) );

*/


wire[7:0] gl_dobx;

wire[7:0] new_dob;



wire[2:0] xpix;
wire[3:0] ypix;

reg[2:0] xpixc;
reg[3:0] ypixc;

reg[7:0] datinreg; //provisionary


//wire[10:0] font_addr = gl_dobx[6:0]*12 + ypixc;
wire[6:0] gl_dobxl = gl_dobx[6:0];

wire[10:0] font_addr = (gl_dobxl * 11)  + ypixc;

xfont cg_ram (.addr(font_addr),.clk(clk2),.row(new_dob));


assign cg_clka = clk2;
assign cg_clkb = clk2;

wire[12:0] gl_addrb;




// gldata gldat ( .gl_enb(gl_enb), .gl_dob(gl_dob), .gl_addrb_l(gl_addrb), .gl_clka(gl_clka), .gl_clkb(gl_clkb) );

assign addrout = {9'b0, gl_addrb,2'b0};
assign gl_dob = datin[31:24];
assign gl_dobx = datin[31:24];

wire[1:0] aux_datin = datin[17:16];
reg[1:0] aux_akt;

assign gl_clka = clk2;
assign gl_clkb = clk2;

parameter xpixmax = 6;
parameter ypixmax = 11;

`define xrest 2


wire loadpix;

//assign xpix = dummyx[2:0];

assign xpix = xpixc[2:0];
assign ypix = dummyy[3:0];

reg[13:0] gl_addr_akt;
reg[13:0] gl_addr_reset;

assign ypre = dummyy[10];


wire upper = (dummyy == 0);
wire lower = (dummyy == 600);
wire right = (dummyx == 800 - 1);



always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				xpixc <= 0;
			end
		else
			begin
				if (dummyx == (2048 - xpixmax - 1))
					begin
						xpixc <= 0;
					end
				else
					begin
						if (xpixc == (xpixmax -1))
							xpixc <= 0;
						else	
							xpixc <= xpixc + 1;
					end
			end
	end


wire allow_1;

assign allow_1 = allow & (dummyx < (800 - `xrest));


always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				gl_addr_akt <= 0;
				gl_addr_reset <= 0;
				ypixc <= 0;
			end
		else
			begin
				if (ypre)
					begin
						gl_addr_akt <= 0;
						gl_addr_reset <= 0;
					end
				else
					begin
						if (lower)
							begin
								gl_addr_akt <= 0;
								gl_addr_reset <= 0;
								ypixc <= 0;
							end
						else
							begin
								if (dummyx == (800 - `xrest))
									begin
										if (ypixc == (ypixmax-1))
											begin
												gl_addr_reset <= gl_addr_akt;
												gl_addr_akt <= gl_addr_akt;
												ypixc <= 0;
											end
										else
											begin
												gl_addr_akt <= gl_addr_reset;
												gl_addr_reset <= gl_addr_reset;
												ypixc <= ypixc + 1;
											end
									end
								else
									begin
										if (dummyy < 583)
											begin
												if (allow_1 && (xpix==(xpixmax-4)))
													begin
														gl_addr_akt <= gl_addr_akt + 1;
														gl_addr_reset <= gl_addr_reset;
													end
												else
													begin
														gl_addr_akt <= gl_addr_akt;
														gl_addr_reset <= gl_addr_reset;
													end
											end
										else
											begin
												gl_addr_akt <= gl_addr_akt;
												gl_addr_reset <= gl_addr_reset;
											end
									end
							end
					end
			end	
	end

 
assign gl_addrb = gl_addr_akt;

assign cg_addrb = {gl_dob, ypix};

assign gl_enb = (xpix==(xpixmax-4+1));

assign en = gl_enb;


assign cg_enb = (xpix==(xpixmax-4+2));


reg[7:0] pixshift;

always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				pixshift <= 0;
			end
		else
			begin
				if (xpix==(xpixmax-1))
					begin
//						pixshift <= cg_dob;
						pixshift <= {new_dob[4:0],3'b0};
					end
				else
					begin
						pixshift <= {pixshift[6:0],1'b0};
					end
			end
	end

always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				aux_akt <= 2'b00;
			end
		else
			begin
			  if (xpix == (xpixmax-1))
				begin
					aux_akt <= aux_datin;
				end
			end
	end


//wire left = (dummyx == auxin[10:0]);

//wire aktx = (dummyx == auxin[10:0]);

reg hso, vso;

wire rg_val = (pixshift[7]) & allow_1;


always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				r <= 0;
				g <= 0;
				b <= 0;
				hso <= 1;
				vso <= 1;
			end
		else
			begin
				r <= 1'b0 & allow & ~rg_val;
				g <= 1'b1 & allow & rg_val;
				b <= 1'b1 & allow & ~rg_val & (~|aux_akt);
				hso <= hs0;
				vso <= vs0;
			end
	end

endmodule


module syncgen ( allow, xcnto, ycnto, hs, vs, clk2, clk, rst );

input clk, rst;

output allow;
output clk2;

output[10:0] xcnto;
output[10:0] ycnto;

reg[10:0] xcnto;
reg[10:0] ycnto;

reg[10:0] xcnt;
reg[10:0] ycnt;



output hs, vs;

reg hs, vs;

wire clk2 = clk;


/*
always @(posedge clk or posedge rst)
	begin
		if (rst)
			clk2 <= 0;
		else
			clk2 <= ~clk2;
	end
*/

parameter hfp = 56;
parameter hbp = 64;
parameter hpw = 120;

parameter hwid = 800;

parameter vfp = 37;
parameter vbp = 23;
parameter vpw = 6;

parameter vwid = 600;
		
		
wire xcntmaxed = (xcnt == hpw + hbp + hwid + hfp - 1);
wire ycntmaxed = (ycnt == vpw + vbp + vwid + vfp - 1);

always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				hs <= 1;
				vs <= 1;
			end
		else
			begin
				hs <= !(xcnt < hpw);
				vs <= !(ycnt < vpw);
			end
	end	

reg allow;

wire	allowx = (xcnt >= hpw + hbp) && (xcnt < hpw + hbp + hwid);
wire	allowy = (ycnt >= vpw + vbp) && (ycnt < vpw + vbp + vwid); 

always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				allow <= 0;
			end
		else
			begin
				allow <= allowx & allowy;
			end
	end
	

`define xprel  (2048 - hpw - hbp - 1)
`define yprel  (2048 - vpw - vbp)


always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				xcnto <= `xprel ;
			end
		else
			begin
				if (xcntmaxed)
					begin
						xcnto <= `xprel ;
					end
				else
					begin
						xcnto <= xcnto + 1;
					end
			end
	end

always @(posedge clk2 or posedge rst)
	begin
		if (rst)
			begin
				ycnto <= `yprel ;
			end
		else
			begin
				if (xcntmaxed)
					begin
						if (ycntmaxed)
							begin
								ycnto <= `yprel ;
							end
						else
							begin
								ycnto <= ycnto + 1;
							end
					end
			end
	end





always @(posedge clk2 or posedge rst)
	if (rst)
		begin
			xcnt <= 0;
		end
	else
		begin
			if (xcntmaxed)
				xcnt <= 0;
			else
				xcnt <= xcnt + 1;
		end



always @(posedge clk2 or posedge rst)
	if (rst)
		begin
			ycnt <= 0;
		end
	else
		begin
			if (xcntmaxed)
				begin
					if (ycntmaxed)
						ycnt <= 0;
					else
						ycnt <= ycnt + 1;
				end
		end





endmodule
