module uart_tx(
    input sys_clk,  // U18
    input sys_rst,  //J15
    input start_en,
    input [7:0] tx_data,  // 需要发送出去的并行数据

    output reg txd,  // 连接到了外部的 rx, 该信号持续发送串行信号
    output reg tx_busy
);

parameter CLK_FREQ = 5000_0000;
parameter BPS = 115200;
localparam B_MAX = CLK_FREQ / BPS;

reg [3:0]tx_d_cnt;
reg [15:0] baud_cnt;

// 当start_en 为高的时候, 临时保存输入的并行数据, 并拉高busy信号
reg [7:0] temp_tx_data;  // 临时保存数据的寄存器
always @(posedge sys_clk or negedge sys_rst) begin
    if (sys_rst == 1'b0) begin
        temp_tx_data <= 'b0;
        tx_busy <= 'b0;
    end
    else if(start_en) begin
        temp_tx_data <= tx_data;  // 记录外部传过来的并行数据备份
        tx_busy <= 'b1;  // 拉高 忙信号
    end
    else if (tx_d_cnt == 'b1001 && baud_cnt == B_MAX-1) begin  // 发送一个完整的停止位
        temp_tx_data <= 'b0;
        tx_busy <= 0;
    end
    else begin
        temp_tx_data <= temp_tx_data;
        tx_busy <= tx_busy;
    end
end

// 波特率计数器
always @(posedge sys_clk or negedge sys_rst) begin
    if (sys_rst == 1'b0) begin
        baud_cnt <= 'b0;
    end
    else if (start_en) begin  // 又要发送新数据了, 立刻清零重新计数
        baud_cnt <= 'b0;
    end
    // 必须要开始传输数据
    else if (tx_busy) begin
        if (baud_cnt == B_MAX-'b1) begin  // 从0开始计数的 0~433  一共计数434次
            baud_cnt <= 'b0;
        end
        else begin
            baud_cnt <= baud_cnt + 'b1; 
        end
    end
    else begin
        baud_cnt <= 'b0;
    end
end

// 当前发送数据的数据数量
always @(posedge sys_clk or negedge sys_rst) begin
    if (sys_rst == 1'b0) begin
        tx_d_cnt <= 'b0;
    end
    else if (start_en) begin  // 又要发送新数据了, 立刻清零重新计数
        tx_d_cnt <= 'b0;
    end
    // 必须要开始传输数据
    else if (tx_busy) begin
        if (baud_cnt == B_MAX-'b1) begin
            tx_d_cnt <= tx_d_cnt + 'b1;
        end
        else begin
            tx_d_cnt <= tx_d_cnt;
        end
    end
    else begin
        tx_d_cnt <= 'b0;
    end
end


always @(posedge sys_clk or negedge sys_rst) begin
    if (sys_rst == 1'b0) begin
        txd <= 'b1;
    end
    else if (tx_busy) begin
        case (tx_d_cnt)
            'b0000: txd <= 'b0;
            'b0001: txd <= temp_tx_data[0];
            'b0010: txd <= temp_tx_data[1];
            'b0011: txd <= temp_tx_data[2];
            'b0100: txd <= temp_tx_data[3];
            'b0101: txd <= temp_tx_data[4];
            'b0110: txd <= temp_tx_data[5];
            'b0111: txd <= temp_tx_data[6];
            'b1000: txd <= temp_tx_data[7];
            'b1001: txd <= 'b1;
            default: txd <= 'b1;
        endcase
    end
    else begin
        txd <= 'b1;
    end
end




endmodule