//----------------------------------------------------------------------------------
// Company:        hdLab
// Engineer:       K.Date
// 
// Create Date:    06/15/2015 
// Design Name:    NEXYS4_verilog
// Module Name:    RGB_controller 
// Project Name:   NEXYS4
// Target Devices: Artix-7
// Tool versions:  Vivado2014.3
// Description: 
//
// Dependencies: 
//
// Revision: 1.00
// Revision 1.00 - File converted to verilog
// Additional Comments: 
//
//--------------------------------------------------------------------------------

module RGB_controller(
	input			GCLK,
	input	[3:0]	BTN,
	output	[2:0]	LED0_O,
	output	[2:0]	LED1_O,
	output	[2:0]	LED2_O,
	output	[2:0]	LED3_O
	);
//counter signals
	parameter	window		= 8'b11111111;
	parameter	windowMin	= 8'b00100000;
	reg 	[7:0]	windowcount;

	parameter	deltacountMax	= 20'hf4240; // 
	reg 	[19:0]	deltacount;

	parameter	valcountMax	= 9'b101111111;
	reg 	[8:0]	valcount;

//color intensity signals
	wire	[7:0]	incVal;
	wire	[7:0]	decVal;
	wire	[7:0]	halfIncVal;
	wire	[7:0]	halfDecVal;
	
	wire	[7:0]	pat0;
	wire	[7:0]	pat1;
	wire	[7:0]	pat2;
	wire	[7:0]	pat3;
	wire	[7:0]	pat4;
	wire	[7:0]	pat5;

	//PWM registers
	reg		[3:0]	btn_reg;
	reg 	[2:0]	rgbLedReg0;
	reg 	[2:0]	rgbLedReg1;
	reg 	[2:0]	rgbLedReg2;
	reg 	[2:0]	rgbLedReg3;
	wire 	[2:0]	rgbLed0;
	wire 	[2:0]	rgbLed1;
	wire 	[2:0]	rgbLed2;
	wire 	[2:0]	rgbLed3;
	reg 	[2:0]	LED0_reg;
	reg 	[2:0]	LED1_reg;
	reg 	[2:0]	LED2_reg;
	reg 	[2:0]	LED3_reg;
	
//btn_proc
	always @(posedge GCLK) begin
			btn_reg <= BTN;
	end

//window_counter
	always @(posedge GCLK) begin
			if (windowcount < (window)) begin
				windowcount	<= windowcount + 1;
			end else begin
				windowcount	<= windowMin;
			end
	end

//color_change_counter
	always @(posedge GCLK) begin
			if (deltacount < deltacountMax) begin
				deltacount	<= deltacount + 1;
			end else begin
				deltacount	<= 20'b0;
			end
	end

//color_intensity_counter
	always @(posedge GCLK) begin
			if (deltacount == 0) begin
				if (valcount < valcountMax) begin
					valcount	<= valcount + 1;
				end else begin
					valcount	<= 9'b0;
				end
			end
	end

	assign	incVal	= {1'b0, valcount[6:0]};

	//The folowing code sets decVal to (128 - incVal)
	assign	decVal[7]	= 1'b0;
	assign	decVal[6]	=  ~(valcount[6]);
	assign	decVal[5]	=  ~(valcount[5]);
	assign	decVal[4]	=  ~(valcount[4]);
	assign	decVal[3]	=  ~(valcount[3]);
	assign	decVal[2]	=  ~(valcount[2]);
	assign	decVal[1]	=  ~(valcount[1]);
	assign	decVal[0]	=  ~(valcount[0]);

	assign	halfIncVal = {1'b0, incVal[6:0]};
	assign	halfDecVal = {1'b0, decVal[6:0]};

	assign	pat0=  (valcount[8:7] == 2'b00) ? incVal :
				  ((valcount[8:7] == 2'b01) ? decVal :
				                              8'b00000000);
	assign	pat1=  (valcount[8:7] == 2'b00) ? decVal :
				  ((valcount[8:7] == 2'b01) ? 8'b00000000:
				                              incVal);
	assign	pat2=  (valcount[8:7] == 2'b00) ? 8'b00000000:
				  ((valcount[8:7] == 2'b01) ? incVal :
				                              decVal);
	assign	pat3=  (valcount[8:7] == 2'b00) ? halfIncVal :
				  ((valcount[8:7] == 2'b01) ? 8'b00111111:
				                              halfDecVal);
	assign	pat4=  (valcount[8:7] == 2'b00) ? 8'b00111111:
				  ((valcount[8:7] == 2'b01) ? halfDecVal:
				                              halfIncVal);
	assign	pat5=  (valcount[8:7] == 2'b00) ? halfDecVal:
				  ((valcount[8:7] == 2'b01) ? halfIncVal:
				                              8'b00111111);
//RGB0 processes
	//red processes
	always @(posedge GCLK) begin
			if (pat0 > windowcount) begin
				rgbLedReg0[2]	<= 1'b1;
			end else begin
				rgbLedReg0[2]	<= 1'b0;
			end
	end

	//green processes
	always @(posedge GCLK) begin
			if (pat1 > windowcount) begin
				rgbLedReg0[1]	<= 1'b1;
			end else begin
				rgbLedReg0[1]	<= 1'b0;
			end
	end

	//blue processes
	always @(posedge GCLK) begin
			if (pat2 > windowcount) begin
				rgbLedReg0[0]	<= 1'b1;
			end else begin
				rgbLedReg0[0]	<= 1'b0;
			end
	end
	
//RGB1 processes---	
	//red processes
	always @(posedge GCLK) begin
			if (pat1 > windowcount) begin
				rgbLedReg1[2]	<= 1'b1;
			end else begin
				rgbLedReg1[2]	<= 1'b0;
			end
	end

	//green processes
	always @(posedge GCLK) begin
			if (pat2 > windowcount) begin
				rgbLedReg1[1]	<= 1'b1;
			end else begin
				rgbLedReg1[1]	<= 1'b0;
			end
	end

	//blue processes
	always @(posedge GCLK) begin
			if (pat0 > windowcount) begin
				rgbLedReg1[0]	<= 1'b1;
			end else begin
				rgbLedReg1[0]	<= 1'b0;
			end
	end

//RGB2 processes---	
	//red processes
	always @(posedge GCLK) begin
			if (pat2 > windowcount) begin
				rgbLedReg2[2]	<= 1'b1;
			end else begin
				rgbLedReg2[2]	<= 1'b0;
			end
	end

	//green processes
	always @(posedge GCLK) begin
			if (pat3 > windowcount) begin
				rgbLedReg2[1]	<= 1'b1;
			end else begin
				rgbLedReg2[1]	<= 1'b0;
			end
	end

	//blue processes
	always @(posedge GCLK) begin
			if (pat1 > windowcount) begin
				rgbLedReg2[0]	<= 1'b1;
			end else begin
				rgbLedReg2[0]	<= 1'b0;
			end
	end

//RGB3 processes---	
	//red processes
	always @(posedge GCLK) begin
			if (pat3 > windowcount) begin
				rgbLedReg3[2]	<= 1'b1;
			end else begin
				rgbLedReg3[2]	<= 1'b0;
			end
	end

	//green processes
	always @(posedge GCLK) begin
			if (pat0 > windowcount) begin
				rgbLedReg3[1]	<= 1'b1;
			end else begin
				rgbLedReg3[1]	<= 1'b0;
			end
	end

	//blue processes
	always @(posedge GCLK) begin
			if (pat5 > windowcount) begin
				rgbLedReg3[0]	<= 1'b1;
			end else begin
				rgbLedReg3[0]	<= 1'b0;
			end
	end

//Button controll process
	assign	rgbLed0 = btn_reg[0] ? 3'b000 : rgbLedReg0;
	assign	rgbLed1 = btn_reg[1] ? 3'b000 : rgbLedReg1;
	assign	rgbLed2 = btn_reg[2] ? 3'b000 : rgbLedReg2;
	assign	rgbLed3 = btn_reg[3] ? 3'b000 : rgbLedReg3;

//output register process
	always @(posedge GCLK) begin
		LED0_reg <= rgbLed0;
        LED1_reg <= rgbLed1;
        LED2_reg <= rgbLed2;
        LED3_reg <= rgbLed3;
	end

//output port
	assign LED0_O = LED0_reg;
	assign LED1_O = LED1_reg;
	assign LED2_O = LED2_reg;
	assign LED3_O = LED3_reg;
	
endmodule
