module UART_TX ( input i_Reset_Low, input i_Clk, input i_TransmitReady, input [7:0] i_TransmitByte, output reg o_Active, output reg o_Output, output reg o_Done ); parameter CLOCKS_PER_SECOND = 25000000; parameter BAUD_RATE = 115200; localparam integer CLOCKS_PER_BIT = CLOCKS_PER_SECOND / BAUD_RATE; localparam IDLE = 0; localparam SEND_START_BIT = 1; localparam SEND_DATA_BITS = 2; localparam SEND_STOP_BIT = 3; reg [$clog2(SEND_STOP_BIT)-1:0] r_currentState = IDLE; reg [$clog2(CLOCKS_PER_BIT)-1:0] r_clockCount = 0; reg [$clog2(8)-1:0] r_bitIndex = 0; reg [7:0] r_transmitData; always @(posedge i_Clk or negedge i_Reset_Low) begin if (!i_Reset_Low) begin r_currentState <= IDLE; end else begin o_Done <= 0; case (r_currentState) IDLE: begin // Drive line high for idle o_Output <= 1; r_clockCount <= 0; r_bitIndex <= 0; if (i_TransmitReady) begin o_Active <= 1; r_transmitData <= i_TransmitByte; r_currentState <= SEND_START_BIT; end end SEND_START_BIT: begin o_Output <= 0; if (r_clockCount < CLOCKS_PER_BIT - 1) begin r_clockCount <= r_clockCount + 1; end else begin r_clockCount <= 0; r_currentState <= SEND_DATA_BITS; end end SEND_DATA_BITS: begin o_Output <= r_transmitData[r_bitIndex]; if (r_clockCount < CLOCKS_PER_BIT - 1) begin r_clockCount <= r_clockCount + 1; end else begin r_clockCount <= 0; if (r_bitIndex == 7) begin r_bitIndex <= 0; r_currentState <= SEND_STOP_BIT; end else begin r_bitIndex <= r_bitIndex + 1; end end end SEND_STOP_BIT: begin o_Output <= 1; if (r_clockCount < CLOCKS_PER_BIT - 1) begin r_clockCount <= r_clockCount + 1; end else begin o_Done <= 1; r_clockCount <= 0; r_currentState <= IDLE; o_Output <= 0; end end default: begin r_currentState <= IDLE; end endcase end end endmodule