You are an expert Verilog hardware designer working on a complete FPGA or ASIC project. You are given the full source code of a Verilog project. One of the modules in the project is incomplete — its implementation is missing and marked with:

// >>> Module Implementation Begin

// <<< Module Implementation End

Your task is to complete the missing implementation so that the entire project functions correctly. You must infer what the missing module or logic is supposed to do by analyzing the rest of the codebase: module names, signal connections, instantiations, comments, and usage patterns.

Follow these rules:

1. Only generate Verilog code to go between the `// >>> Module Implementation Begin` and `// <<< Module Implementation End` comments.
2. Use Verilog-2001 syntax. Ensure the code is synthesizable.
3. Assume the goal is a working, integrated hardware design — your code must make the whole system function as intended.
4. Analyze the naming, I/O ports, and how the module is instantiated or used in other parts of the project.
5. Implement correct behavior based on design context. Do not guess randomly — reason it out.
6. Avoid vendor-specific features unless explicitly required.
7. Do not output comments, explanation, or anything outside the required code region unless explicitly asked.

Your output should contain **only the Verilog code** that fits inside the marked region.

/*
 * Copyright (c) 2024 Your Name
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module tt_um_kmakise_sram (
`ifdef USE_POWER_PINS
    inout             VDPWR,
    inout             VGND,
`endif
    input  wire [7:0] ui_in,    // Dedicated inputs
    output wire [7:0] uo_out,   // Dedicated outputs
    input  wire [7:0] uio_in,   // IOs: Input path
    output wire [7:0] uio_out,  // IOs: Output path
    output wire [7:0] uio_oe,   // IOs: Enable path (active high: 0=input, 1=output)
    input  wire       ena,      // always 1 when the design is powered, so you can ignore it
    input  wire       clk,      // clock
    input  wire       rst_n     // reset_n - low to reset
);
//the bi-direction IO
assign uio_oe     = 8'b00010000; 
assign uio_out[7] = 1'b0;
assign uio_out[6] = 1'b0;
assign uio_out[5] = 1'b0;
assign uio_out[3] = 1'b0;
assign uio_out[2] = 1'b0;
assign uio_out[1] = 1'b0;
assign uio_out[0] = 1'b0;
//the noraml output IO
assign uo_out[1] = 1'b0;
assign uo_out[2] = 1'b0;
assign uo_out[3] = 1'b0;
assign uo_out[4] = 1'b0;
assign uo_out[5] = 1'b0;

wire        reset;
wire        rx_enable;
wire        rx_ready;
wire        rx_valid;
wire [ 7:0] rx_data_out;
wire        tx_enable;
wire        tx_valid;
wire [ 7:0] tx_data_in;
wire        tx_ready;
wire        csb_n;
wire        we_n;
wire [ 4:0] addr;
wire [31:0] sram_data_in;
wire [31:0] sram_data_out;
//wire [32:0] sram_data_out_full;
//wire [32:0] sram_data_in_full;
wire        rx_in;
wire        tx_out;
wire        dpu_load_cmd;
wire        requst_valid;
wire [ 7:0] nxt_cmd;
wire [31:0] sram_data_from_dpu;
wire [31:0] sram_data_to_dpu;
wire [ 4:0] sram_addr_from_dpu;  
//assign sram_data_in_full = {1'b0, sram_data_in};
assign reset      = ~rst_n;
assign rx_in      = ui_in[3];
assign uio_out[4] = tx_out;
//============================================//
//=================INSTANCES==================//
//============================================//
UARTReceiver UARTReceiver_ins (
    .clk        (clk        ),      // clock
    .reset      (reset      ),    // reset
    .enable     (rx_enable  ),   // enable
    .in         (rx_in      ),       // RX line
    .ready      (rx_ready   ),    // OK to transmit
    .out        (rx_data_out),      // received data
    .valid      (rx_valid   ),    // RX completed
    .error      (uo_out[7]  ),    // frame error
    .overrun    (uo_out[6]  )   // overrun
);

UARTTransmitter UARTTransmitter_ins (
    .clk        (clk        ),   // clock
    .reset      (reset      ),   // reset
    .enable     (tx_enable  ),   // TX enable
    .valid      (tx_valid   ),   // start transaction
    .in         (tx_data_in ),   // data to transmit
    .out        (tx_out     ),   // TX line
    .ready      (tx_ready   )    // ready for TX
);

SRAMController SRAMController_ins (
	.clk           (clk          ),
	.rst_n         (rst_n        ),
	.uart_ready    (uo_out[0]    ),
	// tx 
	.tx_ready      (tx_ready     ),
	.tx_enable     (tx_enable    ),
	.tx_valid      (tx_valid     ), 
	.tx_data_in    (tx_data_in   ),
	// rx
	.rx_data_out   (rx_data_out  ),
	.rx_valid      (rx_valid     ),
	.rx_enable     (rx_enable    ),
	.rx_ready      (rx_ready     ),
	// sram
	.csb_n         (csb_n        ),
	.we_n          (we_n         ),
	.addr          (addr         ),
	//.sram_data_out (sram_data_out_full[31:0]),
	.sram_data_out (sram_data_out),
	.sram_data_in  (sram_data_in ),
	.dpu_load_cmd  (dpu_load_cmd ), // from controller
	.requst_valid  (requst_valid ), // from controller
	.nxt_cmd       (nxt_cmd      ), 
	.sram_data_to_dpu   (sram_data_to_dpu ),
	.sram_data_from_dpu (sram_data_from_dpu),
	.sram_addr_from_dpu (sram_addr_from_dpu)
);

myconfig_sky_dual sram_ins (
`ifdef USE_POWER_PINS
    .vccd1  (VDPWR         ),
    .vssd1  (VGND          ),
`endif		
	.clk0   (clk           ),
	.csb0   (csb_n         ),
	.web0   (we_n          ),
	.addr0  (addr[3:0]     ),
	.din0   (sram_data_in  ),
	.dout0  (sram_data_out ),
	.clk1   (1'b0          ),
	.addr1  (4'b0          ),
	.csb1   (1'b1          ),
	.dout1  ()
);

dpu dpu_ins (
	.clk           (clk               ),
	.rst_n         (rst_n             ),
	//sram controller
	.dpu_load_cmd  (dpu_load_cmd      ), // from controller
	.requst_valid  (requst_valid      ), // from controller
	.nxt_cmd       (nxt_cmd           ), 
	.sram_data_read(sram_data_to_dpu  ),
	.sram_data_out (sram_data_from_dpu),
	.sram_addr     (sram_addr_from_dpu)
);

endmodule


// OpenRAM SRAM model
// Words: 16
// Word size: 32
/// sta-blackbox
module myconfig_sky_dual(
`ifdef USE_POWER_PINS
    vccd1,
    vssd1,
`endif
// Port 0: RW
    clk0,csb0,web0,addr0,din0,dout0,
// Port 1: R
    clk1,csb1,addr1,dout1
  );

  parameter DATA_WIDTH = 32 ;
  parameter ADDR_WIDTH = 4 ;
  parameter RAM_DEPTH = 1 << ADDR_WIDTH;
  // FIXME: This delay is arbitrary.
  parameter DELAY = 3 ;
  parameter VERBOSE = 1 ; //Set to 0 to only display warnings
  parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary

`ifdef USE_POWER_PINS
    inout vccd1;
    inout vssd1;
`endif
  input  clk0; // clock
  input   csb0; // active low chip select
  input  web0; // active low write control
  input [ADDR_WIDTH-1:0]  addr0;
  input [DATA_WIDTH-1:0]  din0;
  output [DATA_WIDTH-1:0] dout0;
  input  clk1; // clock
  input   csb1; // active low chip select
  input [ADDR_WIDTH-1:0]  addr1;
  output [DATA_WIDTH-1:0] dout1;

endmodule


module SRAMController (
	input wire        clk,
	input wire        rst_n,
	output reg        uart_ready,
	// tx 
	input wire        tx_ready,
	output reg        tx_enable,
	output reg        tx_valid, 
	output reg [ 7:0] tx_data_in,
	// rx
	input wire [ 7:0] rx_data_out,
	input wire        rx_valid,
	output reg        rx_enable,
	output reg        rx_ready,
	// sram
	output reg        csb_n,
	output reg        we_n,
	output reg [ 4:0] addr,
	input wire [31:0] sram_data_out,
	output reg [31:0] sram_data_in,
	// dpu
	output  reg        dpu_load_cmd, // from controller
	output  reg        requst_valid, // from controller
	output  reg  [7:0] nxt_cmd, 
	output  reg [31:0] sram_data_to_dpu,
	input  wire [31:0] sram_data_from_dpu,
	input  wire  [4:0] sram_addr_from_dpu
);
//=====================================//
//==========INTERNAL_SIGNAL============//
//=====================================//
localparam IDLE       = 4'b0000;
localparam READ_STORE = 4'b0001;
localparam RD_0       = 4'b0010;
localparam RD_1       = 4'b0011;
localparam RD_2       = 4'b0100;
localparam RD_3       = 4'b0101;
localparam WD_0       = 4'b0110;
localparam WD_1       = 4'b0111;
localparam WD_2       = 4'b1000;
localparam WD_3       = 4'b1001;
localparam WRITE      = 4'b1010;
localparam DPU        = 4'b1011;
localparam DPU_TMP    = 4'b1111;
localparam DPU_RD     = 4'b1100;
localparam DPU_WD     = 4'b1101;
localparam DPU_FIN    = 4'b1110;
reg [ 3:0] cur_state;
reg [ 3:0] nxt_state;
reg [ 7:0] addr_tmp;
reg [31:0] data_tmp;
reg [31:0] sram_tmp;
reg        addr_tmp_en;
reg        data_tmp_en;
reg        sram_tmp_en;
//============ADDR_TMP_REG==============//
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		addr_tmp <= 'b0;
	end
	else begin
		if (addr_tmp_en) begin
			addr_tmp <= rx_data_out;
		end
	end
end
//=============DATA_TMP_REG=============//
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		data_tmp <= 'b0;
	end
	else begin
		if (data_tmp_en) begin
			data_tmp <= {rx_data_out, data_tmp[31:8]};
		end
	end
end
//==============SRAM_TMP_REG============//
// store the dout0 port information at sram, otherwire the data will be lost 
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		sram_tmp <= 'b0;
	end
	else begin
		if (sram_tmp_en) begin
			sram_tmp <= sram_data_out;
		end
	end
end
//======================================//
//============STATE_MACHINE=============//
//======================================//
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		cur_state <= IDLE;
	end
	else begin
		cur_state <= nxt_state;
	end
end

always @(*) begin
	//defualt value
	addr_tmp_en      = 'b0;
	we_n             = 'b0;
	csb_n            = 'b1;
	tx_enable        = 'b0;
	tx_valid         = 'b0; 
	rx_ready         = 'b0;
	data_tmp_en      = 'b0;
	rx_enable        = 'b1;
	addr             = 'b0;
	sram_data_in     = 'b0;
	tx_data_in       = 'b0;
	sram_tmp_en      = 'b0;
	dpu_load_cmd     = 'b0;
	requst_valid     = 'b0;
	nxt_cmd          = 'b0;
	sram_data_to_dpu = 'b0;
	uart_ready       = 'b0;
	case (cur_state)
		IDLE: begin
			uart_ready = 'b1;
			if (rx_valid) begin
				if (rx_data_out[7] == 'b1) begin // dpu
					dpu_load_cmd = 'b1;
					nxt_cmd = rx_data_out;
					rx_ready ='b1;
					nxt_state = DPU;
				end
				else begin
				    if (rx_data_out[5] == 'b1) begin // read 
                        we_n      = 'b1;
					    csb_n     = 'b0;
					    addr      = rx_data_out[4:0];
					    rx_ready  = 'b1;
					    nxt_state = READ_STORE;
				    end 
				    else begin // write
					    addr_tmp_en = 'b1;// store the address
					    rx_ready    = 'b1;
					    nxt_state   = WD_0;
				    end
				end
			end
			else begin
				nxt_state = IDLE;
			end
		end 
		READ_STORE: begin
			sram_tmp_en = 'b1;
			tx_enable   = 'b1;
			nxt_state   = RD_0;
		end
		RD_0: begin
			if (tx_ready) begin
				tx_enable  = 'b1;
				tx_data_in = sram_tmp[7:0];	
				tx_valid   = 'b1;
				nxt_state  = RD_1;
			end
			else begin
				tx_enable = 'b1;
				nxt_state = RD_0;
			end
		end
		RD_1: begin
			if (tx_ready) begin
				tx_enable  = 'b1;
				tx_data_in = sram_tmp[15:8];
				tx_valid   = 'b1;
				nxt_state  = RD_2;
			end
			else begin
				tx_enable = 'b1;
				nxt_state = RD_1;
			end
		end
		RD_2: begin
			if (tx_ready) begin
				tx_enable  = 'b1;
				tx_data_in = sram_tmp[23:16];
				tx_valid   = 'b1;
				nxt_state  = RD_3;
			end
			else begin
				tx_enable = 'b1;
				nxt_state = RD_2;
			end
		end
		RD_3: begin
			if (tx_ready) begin
				tx_enable  = 'b1;
				tx_data_in = sram_tmp[31:24];
				tx_valid   = 'b1;
				nxt_state  = IDLE;
			end
			else begin
				tx_enable = 'b1;
				nxt_state = RD_3;
			end
		end
		WD_0: begin
			if (rx_valid) begin
				data_tmp_en = 'b1;
				rx_ready    = 'b1;
				nxt_state   = WD_1;
			end
			else begin
				nxt_state = WD_0;
			end
		end
		WD_1: begin
			if (rx_valid) begin
				data_tmp_en = 'b1;
				rx_ready    = 'b1;
				nxt_state   = WD_2;
			end
			else begin
				nxt_state = WD_1;
			end
		end
		WD_2: begin
			if (rx_valid) begin
				data_tmp_en = 'b1;
				rx_ready    = 'b1;
				nxt_state   = WD_3;
			end
			else begin
				nxt_state = WD_2;
			end
		end
		WD_3: begin
			if (rx_valid) begin
				data_tmp_en = 'b1;
				rx_ready    = 'b1;
				nxt_state   = WRITE;
			end
			else begin
				nxt_state = WD_3;
			end
		end
		WRITE: begin
            we_n         = 'b0;
			csb_n        = 'b0;
			addr         = addr_tmp[4:0];
			sram_data_in = data_tmp;	
			nxt_state    = IDLE;
		end
		DPU: begin
			we_n      = 'b1;
			csb_n     = 'b0;
			addr      = sram_addr_from_dpu;
			nxt_state = DPU_TMP;
		end
		DPU_TMP: begin // the data read from sram will be saved 
			sram_tmp_en = 'b1;
			nxt_state   = DPU_RD;
		end
		DPU_RD: begin // transfer the data read to dpu
			sram_data_to_dpu = sram_tmp;
			requst_valid     = 'b1;
			nxt_state        = DPU_WD;
		end
		DPU_WD: begin // during this state, the dpu is calculating the data, and put it in the dpu output
			nxt_state    = DPU_FIN;
		end
		DPU_FIN: begin
			we_n         = 'b0;
			csb_n        ='b0;
			addr         = sram_addr_from_dpu;
			sram_data_in = sram_data_from_dpu;
			requst_valid = 'b1;
			nxt_state    = IDLE;
		end
		default: begin
			nxt_state = IDLE;
		end 
	endcase
end
endmodule


//
// Simple Verilog implementation of an UART receiver
//
//  - 8N1 only (8-bit data word, 1 start bit, 1 stop bit)
//  - "valid" goes high after successful RX and stays high for at least 1 clock cycle
//  - "valid" is cleared as soon as a high "ready" is detected
//  - internal baud rate generation
//  - 16x baud rate oversampling, majority voting over 3 samples for bit sensing
//  - buffered read: a new RX can start before the last byte has been read
//  - tested on an FPGA at 115200 baud driven by a 48 MHz clock
//
//
// MIT License
//
// Copyright (c) 2024 Ciro Cattuto <ciro.cattuto@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Originally based on Dmitry Pchelkin's verilog-uart (https://github.com/hell03end/verilog-uart)
//

module UARTReceiver #(
    parameter CLOCK_RATE = 25000000,
    parameter BAUD_RATE = 9600
)(
    input  wire       clk,      // clock
    input  wire       reset,    // reset
    input  wire       enable,   // enable
    input  wire       in,       // RX line
    input  wire       ready,    // OK to transmit
    output reg  [7:0] out,      // received data
    output reg        valid,    // RX completed
    output reg        error,    // frame error
    output reg        overrun   // overrun
);
    localparam RX_PERIOD_COUNT = $rtoi(CLOCK_RATE / (BAUD_RATE * 16) + 0.5); // 16x oversample
    localparam RX_COUNT_WIDTH = $clog2(RX_PERIOD_COUNT);
    reg [RX_COUNT_WIDTH-1:0] rxCounter;

    // state machine
    localparam RESET = 0, IDLE = 1, DATA_BITS = 2, STOP_BIT = 3;
    reg [1:0] state;

    reg [2:0] bitIndex;     // bit index
    reg [2:0] inputReg;     // shift reg for input signal
    reg [3:0] sampleCount;  // clock count for 16x oversample
    reg [7:0] data;         // input data buffer
    reg out_latched;        // out register is valid

    always @(posedge clk) begin
        if (reset || !enable) begin
            out <= 8'b0;
            error <= 0;
            overrun <= 0;
            valid <= 0;
            inputReg <= 3'b111;
            bitIndex <= 3'b0;
            sampleCount <= 4'b0;
            data <= 8'b0;
            out_latched <= 0;
            state <= RESET;
            rxCounter <= 0;
        end else if (rxCounter < (RX_PERIOD_COUNT - 1)) begin
            // RX baud generation
            rxCounter <= rxCounter + 1;
            if (out_latched) begin
                out_latched <= 0;
                valid <= 1;
            end else if (ready) begin
                valid <= 0;
            end
        end else begin
            rxCounter <= 0;

            inputReg <= { inputReg[1], inputReg[0], in };

            case (state)
                RESET: begin
                    out <= 8'b0;
                    error <= 0;
                    overrun <= 0;
                    valid <= 0;
                    inputReg <= 3'b111;
                    bitIndex <= 3'b0;
                    sampleCount <= 4'b0;
                    data <= 8'b0;
                    out_latched <= 0;
                    if (enable) begin
                        state <= IDLE;
                    end
                end

                IDLE: begin
                    if (sampleCount >= 4'h5) begin
                        state <= DATA_BITS;
                        bitIndex <= 3'b0;
                        sampleCount <= 4'b0;
                        data <= 8'b0;
                        out_latched <= 0;
                        error <= 0;
                        overrun <= 0;
                    end else if (!(|inputReg) || (|sampleCount)) begin
                        // Check bit to make sure it's still low
                        if (|inputReg) begin
                            error <= 1;
                            state <= RESET;
                        end
                        sampleCount <= sampleCount + 1;
                    end
                end

                // receive 8 bits of data
                DATA_BITS: begin
                    if (&sampleCount) begin
                        sampleCount <= 4'b0;
                        data[bitIndex] <= (inputReg[0] & inputReg[1]) | (inputReg[0] & inputReg[2]) | (inputReg[1] & inputReg[2]);
                        if (&bitIndex) begin
                            bitIndex <= 3'b0;
                            state <= STOP_BIT;
                        end else begin
                            bitIndex <= bitIndex + 1;
                        end
                    end else begin
                        sampleCount <= sampleCount + 1;
                    end
                end

                STOP_BIT: begin
                    if (&sampleCount) begin
                        if (&inputReg) begin
                            if (!valid) begin
                                out <= data;
                                out_latched <= 1;
                            end else begin
                                overrun <= 1;
                            end
                            state <= IDLE;
                        end else begin
                            error <= 1;
                            state <= RESET;
                        end
                    end
                    sampleCount <= sampleCount + 1;
                end

                default: begin
                    state <= RESET;
                end
            endcase
        end
    end

endmodule


//
// Simple Verilog implementation of an UART transmitter
//
//  - 8N1 only (8-bit data word, 1 start bit, 1 stop bit)
//  - "ready" is high when ready for TX
//  - user drives "valid" high for 1 clock cycle to start TX
//  - internal baud rate generation
//  - tested on an FPGA at 115200 baud driven by a 48 MHz clock
//
//
// MIT License
//
// Copyright (c) 2024 Ciro Cattuto <ciro.cattuto@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Originally based on Dmitry Pchelkin's verilog-uart (https://github.com/hell03end/verilog-uart)
//

module UARTTransmitter #(
    parameter CLOCK_RATE = 25000000,
    parameter BAUD_RATE = 9600
)(
    input  wire       clk,      // clock
    input  wire       reset,    // reset
    input  wire       enable,   // TX enable
    input  wire       valid,    // start transaction
    input  wire [7:0] in,       // data to transmit
    output reg        out,      // TX line
    output reg        ready     // ready for TX
);
    localparam TX_PERIOD_COUNT = $rtoi(CLOCK_RATE / BAUD_RATE + 0.5);
    localparam TX_COUNT_WIDTH = $clog2(TX_PERIOD_COUNT);
    reg [TX_COUNT_WIDTH-1:0] txCounter = 0;
   
    // state machine
    localparam IDLE = 0, START_BIT = 1, DATA_BITS = 2, STOP_BIT = 3;
    reg [1:0] state;

    reg [7:0] data;         // input byte
    reg [2:0] bitIndex;     // bit index

    always @(posedge clk) begin
        if (reset) begin
            ready <= 0;
            out <= 1; 
            bitIndex <= 3'b0;
            data <= 8'b0;
            state <= IDLE;
            txCounter <= 0;
        end else if (enable & ready & valid) begin
            data    <= in; // latch input data
            ready   <= 1'b0;
            state   <= START_BIT;
        end else if (txCounter < (TX_PERIOD_COUNT - 1)) begin
            // TX baud generation
            txCounter <= txCounter + 1;
        end else begin
            txCounter <= 0;
            case (state)
                default: begin
                    state <= IDLE;
                end
                
                IDLE: begin
                    out <= 1; // drive line high
                    ready <= 1;
                    bitIndex <= 3'b0;
                    data <= 8'b0;
                end

                START_BIT: begin
                    out <= 0; // send start bit (low)
                    state <= DATA_BITS;
                end

                DATA_BITS: begin // send data bits
                    out <= data[bitIndex];
                    if (&bitIndex) begin
                        bitIndex <= 3'b0;
                        state <= STOP_BIT;
                    end else begin
                        bitIndex <= bitIndex + 1;
                    end
                end

                STOP_BIT: begin // send stop bit (high)
                    out <= 1;
                    state <= IDLE;
                end
            endcase
        end
    end

endmodule


module dpu (
	input wire         clk,
	input wire         rst_n,
	//sram controller
	input  wire        dpu_load_cmd, // from controller
	input  wire        requst_valid, // from controller
	input  wire  [7:0] nxt_cmd, 
	input  wire [31:0] sram_data_read,
	output reg  [31:0] sram_data_out,
	output wire  [4:0] sram_addr
);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule



Reference solution:
rtl/generated.v: //===============================================================//
// INTERNAL SIGNAL
//===============================================================//
localparam ADD  = 2'b00;
localparam SUB  = 2'b01;
localparam MUL  = 2'b10;
localparam DIV  = 2'b11;
localparam IDLE = 2'b00;
localparam RD   = 2'b01;
localparam CAL  = 2'b10;
localparam SEND = 2'b11;
reg  [7:0] cur_cmd;
reg  [1:0] cur_state;
reg  [1:0] nxt_state;
wire [1:0] mod;
reg [31:0] data_in;
reg [31:0] data_out;
reg        load;
//===============================================================//
// CMD REG
//===============================================================//
// CONFIGURATION
// [7] -> reserved, judge if we use dpu, used in sram controller
// [6:5] -> mod -- 00: +1 
//                 01: -1
//                 10: *2
//                 11: /2
// [4:0] -> reserved, sram address, used in sram controller
//===============================================================// 
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		cur_cmd <= 8'b0;
	end
	else begin
		if (dpu_load_cmd) begin
			cur_cmd <= nxt_cmd;
		end
	end
end

assign sram_addr = cur_cmd[4:0];//opration on this address
assign mod       = cur_cmd[6:5];
//==============================================================//
// CONTROL PATH
//==============================================================//
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		cur_state <= IDLE;
	end
	else begin
		cur_state <= nxt_state;
	end
end
always @(*) begin
	load         = 1'b0;
	case (cur_state)
		IDLE: begin
			if (dpu_load_cmd) begin
				nxt_state = RD;
			end
			else begin
				nxt_state = IDLE;
			end
		end
		RD: begin
			if (requst_valid) begin
				load = 'b1;
				nxt_state = CAL;
			end
			else begin
				nxt_state = RD;
			end
		end
		CAL: begin
			nxt_state = SEND;
		end
		SEND: begin
			if (requst_valid) begin
				nxt_state = IDLE;
			end
			else begin
				nxt_state = SEND;
			end
		end 
		default: begin
			nxt_state = IDLE;
		end

	endcase
end
//==============================================================//
// DATA PATH
//==============================================================//
always @(*) begin
	case (mod)
		ADD: begin
			data_out = data_in + 1;
		end
		SUB: begin
			data_out = data_in - 1;
		end
		MUL: begin
			data_out = data_in << 1;
		end
		DIV: begin
			data_out = data_in >> 1;
		end 
		default: begin
			data_out = data_in + 1; 
		end
	endcase
end
//==============================================================//
// DATA REGS
//==============================================================//
always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		data_in <= 32'b0;
	end
	else begin
		if (load) begin
		    data_in <= sram_data_read;
		end
	end
end

always @(posedge clk, negedge rst_n) begin
	if (!rst_n) begin
		sram_data_out <= 32'b0;
	end
	else begin
		sram_data_out <= data_out;
	end
end