`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