module tx(
    input wire clk,
    input wire rst_n,
    input wire start,
    input wire [7:0] data_tx,

    output reg tx_G1,
    output done_tx
);

parameter sys_clk = 50_000_000;
parameter bps = 115200;
parameter delay = sys_clk / bps;


parameter [4:0] IDLE    = 00001;
parameter [4:0] START   = 00010;
parameter [4:0] CNTBIT  = 00100;
parameter [4:0] SEND    = 01000;
parameter [4:0] STOP    = 10000;

(* preserve *)reg [4:0] cur_state;
(* preserve *)reg [4:0] next_state;

// 发送的bit 数
reg [3:0] bit_num;
reg [15:0] cnt;

// 第一段
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cur_state <= IDLE;
    else
        cur_state <= next_state;
end
// 第二段
always @(*) begin
    if(!rst_n)
        next_state = IDLE;
    else begin
        case (cur_state)
            IDLE    :begin
                if(start == 1'b1)
                    next_state = START;
                else
                    next_state = cur_state;
            end
            START   :begin
                if(cnt == delay - 1'b1)
                    next_state = CNTBIT;
                else
                    next_state = cur_state;
            end
            CNTBIT  :begin
                if(bit_num == 4'd8)
                    next_state = STOP;
                else
                    next_state = SEND;
            end
            SEND    :begin
                if(cnt == delay - 1'b1)
                    next_state = CNTBIT;
                else
                    next_state = cur_state;
            end
            STOP    :begin
                if(cnt == delay - 1'b1)
                    next_state = IDLE;
                else
                    next_state = cur_state;
            end
            default:next_state = IDLE; 
        endcase
    end
end
// 第三段
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        tx_G1   <= 1'b1;
        done_tx <= 0;
        bit_num <= 0;
        cnt     <= 0;
    else begin
        case (cur_state)
            IDLE    :begin
                tx_G1   <= 1'b1;
                done_tx <= 0;
                bit_num <= 0;
                cnt     <= 0;
            end
            START   :begin
                tx_G1   <= 0;
                done_tx <= 0;
                bit_num <= 0;
                if(cnt == delay - 1'b1)
                    cnt     <= 0;
                else
                    cnt     <= cnt + 1'b1;
            end
            CNTBIT  :begin
                done_tx <= 0;
                bit_num <= bit_num + 1'b1;
                cnt     <= 0;
            end
            SEND    :begin
                tx_G1   <= data_tx[bit_num-1];
                done_tx <= 0;
                if(cnt == delay - 1'b1)
                    cnt     <= 0;
                else
                    cnt     <= cnt + 1'b1;
            end
            STOP    :begin
                tx_G1   <= 1'b1;
                bit_num <= 0;
                if(cnt == delay - 1'b1)
                    cnt     <= 0;
                    // 结束发送
                    done_tx <= 1'b1;
                else
                    cnt     <= cnt + 1'b1;
            end
            default:begin
                tx_G1   <= 1'b1;
                done_tx <= 0;
                bit_num <= 0;
                cnt     <= 0;
            end
        endcase
    end
end

endmodule