//----------------------------------------------------------------------------------
// Company:        hdLab
// Engineer:       K.Date
// 
// Create Date:    06/15/2015 
// Design Name:    NEXYS4_verilog
// Module Name:    Uart_TX_State 
// 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 Uart_TX_StateB(
	input			CLK,
	input			RESET,
	output			uartSend,
	input			uartRdy,
	output	[5:0]	Rom_addr
	);

	//The type definition for the UART state machine type. Here is a description of what
	//occurs during each state:
	// RST_REG     -- Do Nothing. This state is entered after configuration or a user reset.
	//                The state is set to LD_INIT_STR.
	// LD_INIT_STR -- The Welcome String is loaded into the sendStr variable and the strIndex
	//                variable is set to zero. The welcome string length is stored in the StrEnd
	//                variable. The state is set to SEND_CHAR.
	// SEND_CHAR   -- uartSend is set high for a single clock cycle, signaling the character
	//                data at sendStr(strIndex) to be registered by the UART_TX_CTRL at the next
	//                cycle. Also, strIndex is incremented (behaves as if it were post 
	//                incremented after reading the sendStr data). The state is set to RDY_LOW.
	// RDY_LOW     -- Do nothing. Wait for the READY signal from the UART_TX_CTRL to go low, 
	//                indicating a send operation has begun. State is set to WAIT_RDY.
	// WAIT_RDY    -- Do nothing. Wait for the READY signal from the UART_TX_CTRL to go high, 
	//                indicating a send operation has finished. If READY is high and strEnd = 
	//                StrIndex then state is set to WAIT_BTN, else if READY is high and strEnd /=
	//                StrIndex then state is set to SEND_CHAR.
	// WAIT_BTN    -- Do nothing. Wait for a button press on BTNU, BTNL, BTND, or BTNR. If a 
	//                button press is detected, set the state to LD_BTN_STR.

	parameter RST_REG      = 3'b000;
	parameter LD_INIT_STR  = 3'b001;
	parameter SEND_CHAR    = 3'b010;
	parameter RDY_LOW      = 3'b011;
	parameter WAIT_RDY     = 3'b100;
	parameter WAIT_BTN     = 3'b101;
	parameter LD_BTN_STR   = 3'b110;
	parameter	RESET_CNTR_MAX	= 18'b110000110101000000;	// 100,000,000 * 0.002 = 200,000 = clk cycles per 2 ms
	parameter	ADDR_MAX	= 63;

	//UART_TX_CTRL control signals
	reg 			uartSend1 = 1'b0;
	wire	[7:0]	uartData  = 8'b0;
	wire			uartTX;

	//Current uart state signal
	reg 	[2:0]	uartState = RST_REG;

	reg 	[17:0]	reset_cntr = 18'b0;
	reg 	[5:0]	addra     = 6'b0;

	always @(posedge CLK) begin
			if ((reset_cntr == RESET_CNTR_MAX) || (uartState != RST_REG)) begin
				reset_cntr	<= 18'b0;
			end else begin
				reset_cntr	<= reset_cntr + 1;
			end
	end

	//Next Uart state logic (states described above)
	always @(posedge CLK) begin
			if (RESET == 1'b1) begin
				uartState	<= RST_REG;
			end else begin
				case (uartState)
				RST_REG: begin
					if (reset_cntr == RESET_CNTR_MAX) begin
						uartState	<= LD_INIT_STR;
					end
				end
				LD_INIT_STR: begin
					uartState	<= SEND_CHAR;
				end
				SEND_CHAR: begin
					uartState	<= RDY_LOW;
				end
				RDY_LOW: begin
					uartState	<= WAIT_RDY;
				end
				WAIT_RDY: begin
					if (uartRdy == 1'b1) begin
						if (addra == ADDR_MAX) begin
							uartState	<= WAIT_BTN;
						end else begin
							uartState	<= SEND_CHAR;
						end
					end
				end
				WAIT_BTN: begin
					uartState	<= LD_INIT_STR; //RM_B
				end
				default: begin					//should never be reached
					uartState	<= RST_REG;
				end
				endcase
			end
	end


	//Conrols the strIndex signal so that it contains the index
	//of the next character that needs to be sent over uart
	always @(posedge CLK) begin
			if (uartState == RST_REG) begin
				addra	<= 6'b000000;
			end else if (uartState == SEND_CHAR) begin
				addra	<= addra + 1;
			end
	end

	//Controls the UART_TX_CTRL signals
	always @(posedge CLK) begin
			if (uartState == SEND_CHAR) begin
				uartSend1	<= 1'b1;
			end else begin
				uartSend1	<= 1'b0;
			end
	end

	assign	Rom_addr	= addra;
	assign	uartSend	= uartSend1;

endmodule