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

// Top-level module for the ALU project, must match the name in info.yaml
module tt_um_32_bit_fp_ALU_S_M (
    input  wire [7:0] ui_in,    // 8-bit dedicated input bus (operand input)
    output wire [7:0] uo_out,   // 8-bit dedicated output bus (result output)
    
    input  wire [7:0] uio_in,   // 8-bit bidirectional I/O input side (e.g., opcode, start)
    output wire [7:0] uio_out,  // 8-bit bidirectional I/O output side (e.g., done signal, debug)
    output wire [7:0] uio_oe,   // Output enable for each IO pin (1 = drive uio_out, 0 = tri-state)
    
    input  wire       ena,      // High when the project is enabled (can usually be ignored)
    input  wire       clk,      // System clock provided by Tiny Tapeout
    input  wire       rst_n     // Active-low reset signal
);
    // Set the direction for shared IO pins (it is static, direction never changes)
    assign uio_oe = 8'b1111_1000;   // io[7:4] outputs state, io[3] is the 'done' signal.

    // Instantiate the ALU top module with standard interface
    alu_top u_alu (
        .clk       (clk),           // Connect clock
        .rst_n     (rst_n),         // Connect active-low reset
        .in        (ui_in),         // Operand input byte from input pins
        .out       (uo_out),        // Result output byte to output pins
        .opcode    (uio_in[0]),     // Opcode: choose which operation for ALU to do
        .start     (uio_in[2]),     // 'Start' signal: request ALU to do an operation
        .done      (uio_out[3]),    // 'Done' signal: ready for outputting
        .state_out (uio_out[7:4])   // Current state of ALU
    );

    assign uio_out[2:0] = 3'b000;   // Avoid "undriven" warning

    // List all unused inputs to prevent warnings
    wire _unused = &{ena, uio_in[7:3], uio_in[1], 1'b0};

endmodule


`default_nettype none

module alu_top (
    input  wire       clk,       // Clock input
    input  wire       rst_n,     // Active-low reset input
    input  wire [7:0] in,        // 8-bit input data bus for operand bytes
    output reg  [7:0] out,       // 8-bit output data bus for result bytes

    input  wire       opcode,    // 1-bit opcode (0 for add, 1 for subtract)
    input  wire       start,     // 'Start' signal for user to request an operation
    output reg        done,      // 'Done' signal indicating ready to output data
    output wire [3:0] state_out  // Current state of the ALU
);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule




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

`default_nettype none

// Prevent synthesis tools from flattening this module to reduce synthesis memory usage
// (* keep_hierarchy = "yes" *)
module fp_addsub (
    input  wire [31:0] a,      // Input float A (IEEE 754 format)
    input  wire [31:0] b,      // Input float B (IEEE 754 format)
    input  wire        sub,    // Operation select: 0 = add, 1 = subtract
    output reg  [31:0] result  // Resulting float (IEEE 754 format)
);

    // Step 1: Unpack inputs

    wire sign_a = a[31];             // Sign bit of A
    wire sign_b = b[31] ^ sub;       // Sign bit of B, flipped if subtracting

    wire [7:0] raw_exp_a = a[30:23]; // Raw exponent of A
    wire [7:0] raw_exp_b = b[30:23]; // Raw exponent of B

    wire is_subnormal_a = (raw_exp_a == 8'b0); // Check if A is subnormal
    wire is_subnormal_b = (raw_exp_b == 8'b0); // Check if B is subnormal

    wire [7:0] exp_a = is_subnormal_a ? 8'd1 : raw_exp_a; // Adjust exponent of A for subnormal numbers
    wire [7:0] exp_b = is_subnormal_b ? 8'd1 : raw_exp_b; // Adjust exponent of B for subnormal numbers

    wire [23:0] man_a = is_subnormal_a ? {1'b0, a[22:0]} : {1'b1, a[22:0]}; // Mantissa of A with implicit leading 1 if normalized
    wire [23:0] man_b = is_subnormal_b ? {1'b0, b[22:0]} : {1'b1, b[22:0]}; // Mantissa of B with implicit leading 1 if normalized

    // Step 1.5: Handle special cases (NaN, infinity, zero)

    wire is_special_a = (raw_exp_a == 8'hFF);
    wire is_special_b = (raw_exp_b == 8'hFF);

    wire is_man_zero_a = (a[22:0] == 0);
    wire is_man_zero_b = (b[22:0] == 0);

    wire is_nan_a = is_special_a & (~is_man_zero_a);  // A is NaN if exponent is all 1s and mantissa is nonzero
    wire is_nan_b = is_special_b & (~is_man_zero_b);  // B is NaN

    wire is_inf_a = is_special_a & is_man_zero_a;  // A is infinity if exponent is all 1s and mantissa is zero
    wire is_inf_b = is_special_b & is_man_zero_b;  // B is infinity

    wire is_zero_a = is_subnormal_a & is_man_zero_a;  // A is zero if exponenet is all 0s and mantissa is zero (otherwise there's an implicit leading 1)
    wire is_zero_b = is_subnormal_b & is_man_zero_b;  // B is zero

    // Step 2: Align exponents

    wire exp_a_greater = (exp_a >= exp_b);  // Determine which operand has greater exponent
    wire [7:0] exp_diff = exp_a_greater ? (exp_a - exp_b) : (exp_b - exp_a); // Compute exponent difference

    wire [23:0] man_a_shifted = exp_a_greater ? man_a : (man_a >> exp_diff);  // Shift A's mantissa if needed
    wire [23:0] man_b_shifted = exp_a_greater ? (man_b >> exp_diff) : man_b;  // Shift B's mantissa if needed

    wire [7:0] exp_base = exp_a_greater ? exp_a : exp_b;  // Base exponent used after alignment

    // Step 3: Add/Sub aligned mantissas

    wire [24:0] extended_a = {1'b0, man_a_shifted};  // Extend mantissas to 25 bits (guard bit to capture overflow)
    wire [24:0] extended_b = {1'b0, man_b_shifted};

    wire extended_a_greater = (extended_a >= extended_b);  // Determine dominant magnitude
    wire sign_equal = (sign_a == sign_b);                  // True if signs are the same

    wire [24:0] sum = sign_equal ? (extended_a + extended_b) :  // If same sign: add
                      (extended_a_greater ? extended_a - extended_b : extended_b - extended_a);  // Else: subtract smaller from larger

    wire sign_res = extended_a_greater ? sign_a : sign_b; // Determine result sign based on dominant operand

    // Step 4: Normalize result using static priority encoder (no for-loop)

    reg [7:0] shift;     // Number of left shifts required for normalization

    always @(*) begin
        // Special case: NaN or inf - inf
        if (is_nan_a | is_nan_b | (is_inf_a & is_inf_b & (sign_a ^ sign_b))) begin
            result = 32'h7FC00000;  // Return quiet NaN (+qNaN)
        end
        // Special case: A is infinity
        else if (is_inf_a) begin
            result = {sign_a, 8'hFF, 23'd0};  // Return signed infinity
        end
        // Special case: B is infinity
        else if (is_inf_b) begin
            result = {sign_b, 8'hFF, 23'd0};  // Return signed infinity
        end
        // Special case: -0 + -0 = -0 - +0 = -0, all other signed zero operations result in +0
        // A negative 0 can only appear from this signed zero operation, x - x = x + -x = +0 for any non-zero x
        else if (sum == 25'd0) begin
            if(sign_a & sign_b & is_zero_a & is_zero_b) begin
                result = {1'b1, 31'd0};  // -0 + -0 = -0
            end
            else begin
                result = 32'd0;  // Otherwise, it is always +0
            end
        end
        // If MSB is 1 (overflow), shift right and increment exponent
        else if (sum[24] == 1'b1) begin
            result[31]    = sign_res;           // Sign bit
            result[30:23] = exp_base + 1;       // Increase exponent
            result[22:0]  = (exp_base + 1 == 8'hFF) ? 0 : sum[23:1];  // If overflow, set to infinity. Otherwise, drop LSB and implicit 1
        end
        // Else normalize using priority encoder
        else begin
            // Priority encoder to detect how much to left-shift the mantissa
            casez (sum[23:0])
                24'b1???????????????????????: shift = 0;
                24'b01??????????????????????: shift = 1;
                24'b001?????????????????????: shift = 2;
                24'b0001????????????????????: shift = 3;
                24'b00001???????????????????: shift = 4;
                24'b000001??????????????????: shift = 5;
                24'b0000001?????????????????: shift = 6;
                24'b00000001????????????????: shift = 7;
                24'b000000001???????????????: shift = 8;
                24'b0000000001??????????????: shift = 9;
                24'b00000000001?????????????: shift = 10;
                24'b000000000001????????????: shift = 11;
                24'b0000000000001???????????: shift = 12;
                24'b00000000000001??????????: shift = 13;
                24'b000000000000001?????????: shift = 14;
                24'b0000000000000001????????: shift = 15;
                24'b00000000000000001???????: shift = 16;
                24'b000000000000000001??????: shift = 17;
                24'b0000000000000000001?????: shift = 18;
                24'b00000000000000000001????: shift = 19;
                24'b000000000000000000001???: shift = 20;
                24'b0000000000000000000001??: shift = 21;
                24'b00000000000000000000001?: shift = 22;
                24'b000000000000000000000001: shift = 23;
                default: shift = 8'd24; // Should never happen
            endcase

            // Adjust the result's exponent
            if (exp_base <= shift) begin
                // Subnormal result (exponent becomes <= 0, which is no longer a normalized number)
                result[31]    = sign_res;       // Sign bit
                result[30:23] = 8'd0;           // Exponent = 0
                result[22:0]  = sum[22:0];      // Unshifted mantissa
            end
            else begin
                result[31]    = sign_res;             // Sign bit
                result[30:23] = exp_base - shift;     // Adjusted exponent
                result[22:0]  = sum[22:0] << shift;   // Left-shifted mantissa (without leading 1)
            end
        end
    end

endmodule


Reference solution:
rtl/generated.v:     // Define the finite state machine (FSM) states
    parameter IDLE        = 4'd0;   // Waiting for start signal
    parameter LOAD_A_0    = 4'd1;   // Load byte 0 of operand A
    parameter LOAD_A_1    = 4'd2;   // Load byte 1 of operand A
    parameter LOAD_A_2    = 4'd3;   // Load byte 2 of operand A
    parameter LOAD_A_3    = 4'd4;   // Load byte 3 of operand A
    parameter LOAD_B_0    = 4'd5;   // Load byte 0 of operand B
    parameter LOAD_B_1    = 4'd6;   // Load byte 1 of operand B
    parameter LOAD_B_2    = 4'd7;   // Load byte 2 of operand B
    parameter LOAD_B_3    = 4'd8;   // Load byte 3 of operand B
    parameter EXECUTE     = 4'd9;   // Perform the operation
    parameter OUTPUT_0    = 4'd10;  // Output byte 0 of result
    parameter OUTPUT_1    = 4'd11;  // Output byte 1 of result
    parameter OUTPUT_2    = 4'd12;  // Output byte 2 of result
    parameter OUTPUT_3    = 4'd13;  // Output byte 3 of result

    // Register declaration
    reg [3:0]  state;               // Current state of ALU
    reg [31:0] operand_a;           // First input operand
    reg [31:0] operand_b;           // Second input operand
    reg [23:0] partial_result;      // Final result after computation

    // Decide if operation is subtraction based on opcode
    wire sub = opcode;  // 1 if subtract, 0 if add

    // Wire to receive the result from the floating-point adder/subtractor
    wire [31:0] addsub_result;

    // Connect state register to the output for debug
    assign state_out = state;

    // Instantiate the floating-point add/subtract unit
    fp_addsub u_addsub (
        .a      (operand_a),       // First operand input
        .b      (operand_b),       // Second operand input
        .sub    (sub),             // Control: 1 for subtract, 0 for add
        .result (addsub_result)    // Output result
    );

    // Sequential logic: handles state transitions, input loading, and output
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            // Reset all internal registers and return to IDLE
            state          <= IDLE;
            operand_a      <= 32'd0;
            operand_b      <= 32'd0;
            partial_result <= 24'd0;
            out            <= 8'd0;
            done           <= 1'b0;
        end else begin
            // FSM: handle each phase of the ALU operation
            case (state)
                IDLE: begin
                    done <= 1'b0;  // Reset done signal just in case
                    if (start)     // Wait for start signal
                        state <= LOAD_A_0;
                end

                // Load 32-bit operand A one byte per cycle (LSB to MSB)
                LOAD_A_0: begin operand_a[7:0]    <= in; state <= LOAD_A_1; end
                LOAD_A_1: begin operand_a[15:8]   <= in; state <= LOAD_A_2; end
                LOAD_A_2: begin operand_a[23:16]  <= in; state <= LOAD_A_3; end
                LOAD_A_3: begin operand_a[31:24]  <= in; state <= LOAD_B_0; end

                // Load 32-bit operand B one byte per cycle (LSB to MSB)
                LOAD_B_0: begin operand_b[7:0]    <= in; state <= LOAD_B_1; end
                LOAD_B_1: begin operand_b[15:8]   <= in; state <= LOAD_B_2; end
                LOAD_B_2: begin operand_b[23:16]  <= in; state <= LOAD_B_3; end
                LOAD_B_3: begin operand_b[31:24]  <= in; state <= EXECUTE;  end

                // Perform the selected floating-point operation
                EXECUTE: begin
                    partial_result <= addsub_result[31:8];  // Capture result TODO: We will need to make sure that fp_addsub finishes within 1 clock cycle
                    state  <= OUTPUT_0;                     // Begin output phase
                    done   <= 1'b1;                         // Set 'done' high, which will begin to be high in the next state
                    out    <= addsub_result[7:0];           // Set first byte, which will begin to send in the next state
                end

                // Output result byte-by-byte, LSB to MSB
                OUTPUT_0: begin
                    out        <= partial_result[7:0];   // Set byte 1
                    state      <= OUTPUT_1;
                end
                OUTPUT_1: begin
                    out        <= partial_result[15:8];  // Set byte 2
                    state      <= OUTPUT_2;
                end
                OUTPUT_2: begin
                    out        <= partial_result[23:16];  // Set byte 3
                    state      <= OUTPUT_3;
                end
                OUTPUT_3: begin
                    state      <= IDLE;           // Go back to IDLE
                    done       <= 1'b0;           // Set done back to low, which will take effect in the next state
                end
                default: begin
                    state <= IDLE;
                end
            endcase
        end
    end