module uart_tx_V2(
    input wire clk,
    input wire [7:0] din,
    input wire wr_en,
    output wire tx_busy,

    output reg tx_p    
);

initial begin
    tx_p = 1'b1;
end

parameter clk_freq = 12000000;
parameter uart_freq = 115200;

localparam STATE_IDLE	= 2'b00;
localparam STATE_START	= 2'b01;
localparam STATE_DATA	= 2'b10;
localparam STATE_STOP	= 2'b11;

reg[7:0] localdin;
reg localwr_en;

//always@(posedge clk)begin
always@(*)begin	
    localdin<=din;
    localwr_en<=wr_en;
end

reg [7:0] data= 8'h00;
reg [2:0] bitpos= 3'h0;
reg [1:0] state= STATE_IDLE;

wire tx_clk;

localparam TX_CLK_MAX = (clk_freq / uart_freq)-1;

reg[$clog2(TX_CLK_MAX+1)+1:0] tx_clkcnt;

assign tx_clk = (tx_clkcnt == 0);

initial tx_clkcnt=0;

always @(posedge clk) begin
    if (tx_clkcnt >= TX_CLK_MAX)
        tx_clkcnt <= 0;
    else
        tx_clkcnt <= tx_clkcnt + 1;
end
    

always @(posedge clk) begin
    case (state)
    STATE_IDLE: begin
        if (localwr_en) begin
            state <= STATE_START;
            data <= localdin;
            bitpos <= 3'h0;
        end
    end
    STATE_START: begin
        if (tx_clk) begin
            tx_p <= 1'b0;
            state <= STATE_DATA;
        end
    end
    STATE_DATA: begin
        if (tx_clk) begin
            if (bitpos == 3'h7)
                state <= STATE_STOP;
            else
                bitpos <= bitpos + 3'h1;
            tx_p <= data[bitpos];
        end
    end
    STATE_STOP: begin
        if (tx_clk) begin
            tx_p <= 1'b1;
            state <= STATE_IDLE;
        end
    end
    default: begin
        tx_p <= 1'b1;
        state <= STATE_IDLE;
    end
    endcase
end

assign tx_busy = (state != STATE_IDLE);

endmodule