`timescale 1ns / 1ps module uart_ctrl_sysreg #( parameter BAUD = 115200, parameter CLOCK_FREQ = 50_000_000 )( input clk ,input rst_n // UART Interface ,input uart_rx ,output uart_tx // Register File Interface ,output reg [31:0] o_wrdata //write data to register file ,output reg [24:0] o_addr //register file address ,output reg o_wren //write enable to register file ,output reg o_rden //read enable to register file ,input [31:0] i_rddata //read data from register file // Auto-Report Mechanism ,input [23:0] i_report_data ,input i_report_vld ); // --- uart_top --- wire [31:0] uart_rx_data; wire uart_rx_done; reg [31:0] uart_tx_data; reg uart_tx_go; wire uart_tx_done; uart_top_32bit #( .BAUD(BAUD), .CLOCK_FREQ(CLOCK_FREQ) ) uart_32bit_inst ( .Clk(clk), .Reset_n(rst_n), .Send_Go32(uart_tx_go), .Tx_Data32(uart_tx_data), .Tx_Done32(uart_tx_done), .uart_tx(uart_tx), .uart_rx(uart_rx), .Rx_Done32(uart_rx_done), .Rx_Data32(uart_rx_data) ); // Protocol parsing registers reg [63:0] cmd_reg; reg [31:0] wr_data_buff; reg [19:0] data_bytes_len; // State machine definition reg [2:0] state; localparam S_IDLE = 3'd0, S_RX_CMD_L = 3'd1, S_PARSE = 3'd2, S_WAIT_RD = 3'd3, S_RD_DATA = 3'd4, S_WR_DATA = 3'd5, S_REPORT = 3'd6; // Auto-report state // Latch auto-report data reg [23:0] report_data_latch; reg report_pending; // Capture report pulse: store if busy always @(posedge clk or negedge rst_n) begin if(!rst_n) begin report_pending <= 1'b0; report_data_latch <= 24'd0; end else if(i_report_vld) begin report_pending <= 1'b1; report_data_latch <= i_report_data; end else if(state == S_REPORT) begin report_pending <= 1'b0; // Clear flag after entering report state end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= 0; cmd_reg <= 0; o_wrdata <= 0; o_wren <= 0; o_rden <= 0; uart_tx_go <= 1'b0; uart_tx_data <= 1'b0; end else begin case(state) S_IDLE : begin // IDLE state uart_tx_go <= 1'b0; if(uart_rx_done) begin cmd_reg[63:32] <= uart_rx_data; state <= S_RX_CMD_L; end else if(report_pending) begin state <= S_REPORT; end end S_RX_CMD_L : begin // Receive lower command word if(uart_rx_done)begin cmd_reg[31:0] <= uart_rx_data; state <= S_PARSE; end end S_PARSE : begin // Parse command o_addr <= cmd_reg[56:32]; data_bytes_len <= cmd_reg[19:0]; if(cmd_reg[63] == 1'b1) begin // Read command o_rden <= 1'b1; state <= S_WAIT_RD; end else begin // Write command state <= S_WR_DATA; end end S_WAIT_RD : begin // Wait for read data ready o_rden <= 1'b0; state <= S_RD_DATA; end S_RD_DATA :begin // Transmit read data uart_tx_data <= i_rddata; uart_tx_go <= 1'b1; state <= S_IDLE; end S_WR_DATA : begin // Receive and write data o_wren <= 1'b0; if(data_bytes_len != 0)begin if(uart_rx_done) begin o_wrdata <= uart_rx_data; o_wren <= 1'b1; data_bytes_len <= data_bytes_len - 20'd4; end end else begin state <= S_IDLE; end end S_REPORT : begin // Auto-report data // Construct report packet: [8'hAA (header) + 24bit sensor data] uart_tx_data <= {8'hAA, report_data_latch}; uart_tx_go <= 1'b1; state <= S_IDLE; end default: state <= S_IDLE; endcase end end endmodule