83 lines
3.0 KiB
Coq
83 lines
3.0 KiB
Coq
|
|
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
|