thermometer_digital/rtl/uart_top_32bit.v

164 lines
5.0 KiB
Verilog

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: yangshenbo
//
// Create Date: 2026/03/31 10:53:24
// Design Name:
// Module Name: uart_top_32bit
//
//////////////////////////////////////////////////////////////////////////////////
module uart_top_32bit #(
parameter BAUD = 9600,
parameter CLOCK_FREQ = 50_000_000
)
(
input Clk,
input Reset_n,
// 32位发送接口
input Send_Go32, // 32位发送启动脉冲
input [31:0] Tx_Data32, // 待发送的32位数据
output Tx_Done32, // 32位发送完成标志
output uart_tx, // 物理引脚TX
// 32位接收接口
input uart_rx, // 物理引脚RX
output reg Rx_Done32, // 32位接收完成标志
output reg [31:0] Rx_Data32 // 接收到的32位数据
);
// --- 内部连线 ---
wire byte_tx_go;
wire [7:0] byte_tx_data;
wire byte_tx_done;
wire byte_rx_done;
wire [7:0] byte_rx_data;
// ============================================================
// 1. 发送逻辑控制 (32-bit to 4x8-bit)
// ============================================================
reg [3:0] tx_state;
reg [31:0] tx_data_buffer;
reg byte_tx_go_reg;
reg [7:0] byte_tx_data_reg;
assign byte_tx_go = byte_tx_go_reg;
assign byte_tx_data = byte_tx_data_reg;
always @(posedge Clk or negedge Reset_n) begin
if (!Reset_n) begin
tx_state <= 0;
byte_tx_go_reg <= 0;
tx_data_buffer <= 0;
end else begin
case (tx_state)
0: begin // 等待发送触发
if (Send_Go32) begin
tx_data_buffer <= Tx_Data32;
tx_state <= 1;
end
end
1, 2, 3, 4: begin // 依次发送字节0, 1, 2, 3
byte_tx_data_reg <= tx_data_buffer[7:0]; // 优先发低位(小端)
byte_tx_go_reg <= 1;
tx_state <= tx_state + 4; // 跳转到等待状态 (利用加法偏移)
end
// 状态 5, 6, 7, 8 用于等待 byte_tx_done
5, 6, 7, 8: begin
byte_tx_go_reg <= 0;
if (byte_tx_done) begin
tx_data_buffer <= tx_data_buffer >> 8; // 移位,准备下一字节
if (tx_state == 8) tx_state <= 0; // 发完4个
else tx_state <= tx_state - 3; // 回到下一个发送状态
end
end
endcase
end
end
assign Tx_Done32 = (tx_state == 8 && byte_tx_done);
// ============================================================
// 2. 接收逻辑控制 (4x8-bit to 32-bit)
// ============================================================
reg [1:0] rx_cnt;
reg [31:0] rx_data_buffer;
reg rx_done32_reg;
always @(posedge Clk or negedge Reset_n) begin
if (!Reset_n) begin
rx_cnt <= 0;
rx_data_buffer <= 0;
rx_done32_reg <= 0;
end else begin
rx_done32_reg <= 0;
if (byte_rx_done) begin
// 拼接数据 (小端模式)
case(rx_cnt)
0: rx_data_buffer[7:0] <= byte_rx_data;
1: rx_data_buffer[15:8] <= byte_rx_data;
2: rx_data_buffer[23:16] <= byte_rx_data;
3: rx_data_buffer[31:24] <= byte_rx_data;
endcase
if (rx_cnt == 3) begin
rx_cnt <= 0;
rx_done32_reg <= 1;
end else begin
rx_cnt <= rx_cnt + 1;
end
end
end
end
always @(posedge Clk or Reset_n) begin
if(!Reset_n) begin
Rx_Data32 <= 1'b0;
Rx_Done32 <= 1'b0;
end
else if(rx_done32_reg)begin
Rx_Data32 <= rx_data_buffer;
Rx_Done32 <= rx_done32_reg;
end
else begin
Rx_Data32 <= Rx_Data32;
Rx_Done32 <= 0;
end
end
// ============================================================
// 3. 模块实例化
// ============================================================
// 实例化发送字节模块
uart_byte_tx #(
.BAUD(BAUD),
.CLOCK_FREQ(CLOCK_FREQ)
) u_uart_byte_tx (
.Clk(Clk),
.Reset_n(Reset_n),
.Send_Go(byte_tx_go),
.Data(byte_tx_data),
.uart_tx(uart_tx),
.Tx_Done(byte_tx_done)
);
// 实例化接收字节模块
uart_byte_rx #(
.BAUD(BAUD),
.CLOCK_FREQ(CLOCK_FREQ)
) u_uart_byte_rx (
.Clk(Clk),
.Reset_n(Reset_n),
.uart_rx(uart_rx),
.Rx_Done(byte_rx_done),
.Rx_Data(byte_rx_data)
);
endmodule