module uart_tx ( input wire clk, // 时钟信号 input wire rst, // 复位信号 input wire tx_start, // 开始发送信号 input wire [15:0] tx_data, // 顶层输入的16位待发送数据 output wire tx, // 串行输出信号 output reg tx_done // 发送完成信号 ); parameter BAUD_RATE = 115200; parameter CLOCK_FREQ = 115200; // 12 MHz时钟 localparam integer BAUD_TICK = CLOCK_FREQ / BAUD_RATE; // 波特率计数,计算出每个比特的时钟周期数 // 波特率计数器 reg [15:0] baud_counter; reg [7:0] data_to_send; // 用于存储当前要发送的8位数据 reg [1:0] byte_select; // 控制发送高8位还是低8位数据 // 发送状态机定义 reg [3:0] tx_state; reg [9:0] tx_shift_reg; // 10位移位寄存器(8位数据 + 起始位 + 停止位) reg [3:0] tx_bit_counter; // 用于计数8位数据发送的每一位 // 波特率计数器更新 always @(posedge clk or negedge rst) begin if (!rst) baud_counter <= 0; else if (baud_counter == BAUD_TICK - 1) baud_counter <= 0; else baud_counter <= baud_counter + 1; end // UART发送逻辑 always @(posedge clk or negedge rst) begin if (!rst) begin tx_state <= 0; tx_done <= 0; byte_select <= 0; tx_shift_reg <= 10'b1111111111; // 空闲状态(全1表示停止位) end else if (baud_counter == BAUD_TICK - 1) begin case (tx_state) 0: begin if (tx_start) begin // 根据 byte_select 选择发送高8位或低8位数据 if (byte_select == 0) data_to_send <= tx_data[15:8]; // 发送低8位 else data_to_send <= tx_data[7:0]; // 发送高8位 // 将要发送的8位数据加上起始位(0)和停止位(1) tx_shift_reg <= {1'b1, data_to_send, 1'b0}; // 1位停止位,8位数据,1位起始位 tx_state <= 1; tx_done <= 0; end end 1: begin // 每个波特率时钟周期发送一位 if (tx_bit_counter == 9) begin // 所有位发送完成后回到空闲状态 if (byte_select == 0) byte_select <= 1; // 切换到发送高8位 else begin byte_select <= 0; // 重置为低8位 tx_done <= 1; // 完成整个16位数据的发送 end tx_state <= 0; tx_bit_counter<= 0; end else begin tx_shift_reg <= {1'b1, tx_shift_reg[9:1]}; // 右移移位寄存器 tx_bit_counter <= tx_bit_counter + 1; end end endcase end end assign tx = tx_shift_reg[0]; // 串行输出当前最低位 endmodule