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