163 lines
5.0 KiB
Verilog
163 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-bit Transmit Interface
|
|
input Send_Go32, // 32-bit transmit start pulse
|
|
input [31:0] Tx_Data32, // 32-bit data to transmit
|
|
output Tx_Done32, // 32-bit transmit done flag
|
|
output uart_tx, // Physical TX pin
|
|
|
|
// 32-bit Receive Interface
|
|
input uart_rx, // Physical RX pin
|
|
output reg Rx_Done32, // 32-bit receive done flag
|
|
output reg [31:0] Rx_Data32 // 32-bit received data
|
|
);
|
|
|
|
// --- Internal Wires ---
|
|
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. Transmit Control Logic (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 // Wait for transmit trigger
|
|
if (Send_Go32) begin
|
|
tx_data_buffer <= Tx_Data32;
|
|
tx_state <= 1;
|
|
end
|
|
end
|
|
|
|
1, 2, 3, 4: begin // Send byte 0, 1, 2, 3 sequentially
|
|
byte_tx_data_reg <= tx_data_buffer[31:24]; // Send high byte first (Big-endian)
|
|
byte_tx_go_reg <= 1;
|
|
tx_state <= tx_state + 4; // Jump to wait state
|
|
end
|
|
|
|
// States 5, 6, 7, 8: Wait for 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; // Shift for next byte
|
|
if (tx_state == 8) tx_state <= 0; // 4 bytes sent
|
|
else tx_state <= tx_state - 3; // Return to next send state
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
assign Tx_Done32 = (tx_state == 8 && byte_tx_done);
|
|
|
|
// ============================================================
|
|
// 2. Receive Control Logic (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
|
|
// Concatenate data (Big-endian mode)
|
|
case(rx_cnt)
|
|
0: rx_data_buffer[31:24] <= byte_rx_data;
|
|
1: rx_data_buffer[23:16] <= byte_rx_data;
|
|
2: rx_data_buffer[15:8] <= byte_rx_data;
|
|
3: rx_data_buffer[7:0] <= 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 negedge 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. Module Instantiation
|
|
// ============================================================
|
|
|
|
// Instantiate byte transmit module
|
|
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)
|
|
);
|
|
|
|
// Instantiate byte receive module
|
|
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 |