// Converted from UART_TX_CTRL.vhd
// by VHDL2Verilog ver1.00(2004/05/06)  Copyright(c) S.Morioka (http://www02.so-net.ne.jp/~morioka/v2v.htm)
//----------------------------------------------------------------------------------
// Company:        hdLab
// Engineer:       K.Date
// 
// Create Date:    06/15/2015 
// Design Name:    NEXYS4_verilog
// Module Name:    NEXYS4_TOP 
// 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: 
//
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
//	UART_TX_CTRL.vhd -- UART Data Transfer Component
//--------------------------------------------------------------------------
// Author:  Sam Bobrowicz
//          Copyright 2011 Digilent, Inc.
//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
//	This component may be used to transfer data over a UART device. It will
// serialize a byte of data and transmit it over a TXD line. The serialized
// data has the following characteristics:
//         *9600 Baud Rate
//         *8 data bits, LSB first
//         *1 stop bit
//         *no parity
//         				
// Port Descriptions:
//
//    SEND - Used to trigger a send operation. The upper layer logic should 
//           set this signal high for a single clock cycle to trigger a 
//           send. When this signal is set high DATA must be valid . Should 
//           not be asserted unless READY is high.
//    DATA - The parallel data to be sent. Must be valid the clock cycle
//           that SEND has gone high.
//    CLK  - A 100 MHz clock is expected
//   READY - This signal goes low once a send operation has begun and
//           remains low until it has completed and the module is ready to
//           send another byte.
// UART_TX - This signal should be routed to the appropriate TX pin of the 
//           external UART device.
//   
//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
// Revision History:
//  08/08/2011(SamB): Created using Xilinx Tools 13.2
//--------------------------------------------------------------------------

module UART_TX_CTRL(
	input			SEND,
	input	[7:0]	DATA,
	input			CLK,
	output			READY,
	output			UART_TX
	);

    //TX_STATE_TYPE
	parameter RDY	    = 3'b100;
	parameter LOAD_BIT	= 3'b010;
	parameter SEND_BIT	= 3'b001;
	
	//constant BIT_TMR_MAX : std_logic_vector(13 downto 0) := "10100010110000"; --10416 = (round(100MHz / 9600)) - 1
	parameter	BIT_TMR_MAX	    = 10'b1101100011;	//867 = (round(100MHz / 115200)) - 1
	parameter	BIT_INDEX_MAX	= 4'd10;

	//Counter that keeps track of the number of clock cycles the current bit has been held stable over the
	//UART TX line. It is used to signal when the ne
(* keep = "true" *)	reg 	[9:0]	bitTmr = 10'b0;

	//combinatorial logic that goes high when bitTmr has counted to the proper value to ensure
	//a 9600 baud rate
(* keep = "true" *)	wire			bitDone;

	//Contains the index of the next bit in txData that needs to be transferred 
	reg 	[3:0]	bitIndex =10'b0;	//natural;

	//a register that holds the current data being sent over the UART TX line
(* keep = "true" *)	reg 			txBit = 1'b1;

	//A register that contains the whole data packet to be sent, including start and stop bits. 
	reg 	[9:0]	txData;
	reg 	[2:0]	txState = RDY;

	//attribute keep : string;
	//attribute keep of bitDone: signal is "TRUE";
	//attribute keep of bitTmr: signal is "TRUE";
	//attribute keep of txBit: signal is "TRUE";

    //Next state logic
	always @(posedge CLK) begin
			case (txState)
			RDY: begin
				if (SEND == 1'b1) begin
					   txState	<= LOAD_BIT;
				end
			end
			LOAD_BIT: begin
				        txState	<= SEND_BIT;
			end
			SEND_BIT: begin
				if (bitDone == 1'b1) begin
					if (bitIndex == BIT_INDEX_MAX) begin
						txState	<= RDY;
					end else begin
						txState	<= LOAD_BIT;
					end
				end
			end
			default: begin		//should never be reached
				        txState	<= RDY;
			end
			endcase
	end

	always @(posedge CLK) begin
			if (txState == RDY) begin
				    bitTmr	<= 10'b0;
			end else begin
				if (bitDone == 1'b1) begin
					bitTmr	<= 10'b0;
				end else begin
					bitTmr	<= bitTmr + 1;
				end
			end
	end

	assign	bitDone	= ((bitTmr == BIT_TMR_MAX)) ? (1'b1) : (1'b0);

	always @(posedge CLK) begin
			if (txState == RDY) begin
				bitIndex	<= 4'd0;
			end else if (txState == LOAD_BIT) begin
				bitIndex	<= bitIndex + 1;
			end
	end

	always @(posedge CLK) begin
			if (SEND == 1'b1) begin
				txData	<= {1'b1, DATA, 1'b0};
			end
    end

	always @(posedge CLK) begin
			if (txState == RDY) begin
				txBit	<= 1'b1;
			end else if (txState == LOAD_BIT) begin
				//txBit	<= txData[bitIndex];
				case(bitIndex)
				4'd0 : txBit <= txData[0];
				4'd1 : txBit <= txData[1];
				4'd2 : txBit <= txData[2];
				4'd3 : txBit <= txData[3];
				4'd4 : txBit <= txData[4];
				4'd5 : txBit <= txData[5];
				4'd6 : txBit <= txData[6];
				4'd7 : txBit <= txData[7];
				4'd8 : txBit <= txData[8];
				4'd9 : txBit <= txData[9];
				default :;
				endcase
			end
	end

	assign	UART_TX	= txBit;
	assign	READY	= (txState == RDY) ? 1'b1 : 1'b0 ;

endmodule