waveform_acquisition_FPGA_code/puart2/uart_tx.v

83 lines
3.0 KiB
Coq
Raw Normal View History

2025-12-11 18:35:48 +08:00
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