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.

`default_nettype none

module tt_um_btflv_subleq (
	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
);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule




module SPI_FRAM_Interface (
    input  wire            clk     ,
    input  wire            rst_n   ,
    input                  spi_miso,
    output      reg        spi_mosi,
    output      reg        spi_sck ,
    output      reg        spi_cs  ,
    input  wire     [15:0] addr    ,
    input  wire     [15:0] data_in ,
    input  wire            we      ,
    input  wire            start   ,
    output      reg [15:0] data_out,
    output      reg        done
);

    assign write_data_l = data_in[7:0];
    assign write_data_h = data_in[15:8];
    assign address      = (addr[14:0] << 1)  + !hbyte;
    assign write_enable = we;

    reg [7:0] temp_data  ;
    reg [4:0] state      ;
    reg [4:0] bit_counter;
    reg [5:0] spi_clk    ;
    reg       clk_out    ;
    reg       hbyte      ;

    wire [ 7:0] write_data_l;
    wire [ 7:0] write_data_h;
    wire        write_enable;
    wire [15:0] address     ;

    parameter CMD_READ  = 8'h03;
    parameter CMD_WRITE = 8'h02;
    parameter CMD_WREN  = 8'h06;
    parameter CMD_WRDI  = 8'h04;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            spi_clk <= 6'd0;
            clk_out <= 1'b0;
        end else begin
            if (spi_clk == 6'd7) begin
                spi_clk <= 6'd0;
                clk_out <= ~clk_out;
            end else begin
                spi_clk <= spi_clk + 1;
            end
        end
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            spi_cs      <= 1;
            spi_sck     <= 0;
            spi_mosi    <= 0;
            state       <= 0;
            bit_counter <= 0;
            hbyte       <= 0;
        end else begin
            case (state)
                0 : begin
                    done <= 0;
                    if (start && write_enable) begin
                        state    <= 6;
                        spi_mosi <= CMD_WREN[7];
                    end else if (start || hbyte) begin
                        state    <= 1;
                        spi_cs   <= 0;
                        spi_mosi <= 0;
                        spi_sck  <= 0;
                    end
                end
                1 : begin // Send read command
                    if (bit_counter < 8) begin
                        spi_mosi <= CMD_READ[7 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= address[15];
                        spi_sck     <= 0;
                        state       <= 2;
                    end
                end
                2 : begin // Send address (16 bits)
                    if (bit_counter < 16) begin
                        spi_mosi <= address[15 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= 0;
                        spi_sck     <= 0;
                        state       <= 3;
                    end
                end
                3 : begin // Wait
                    if (bit_counter < 8) begin
                        bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        state       <= 4;
                    end
                end
                4 : begin // Read data byte
                    if (bit_counter < 8) begin
                        spi_sck <= ~spi_sck;
                        if (~spi_sck) temp_data[7 - bit_counter] <= spi_miso;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        if(hbyte)
                            begin
                                data_out[15:8] <= temp_data;
                            end
                        else
                            begin
                                data_out[7:0] <= temp_data;
                            end
                        bit_counter <= 0;
                        spi_mosi    <= 0;
                        spi_sck     <= 0;
                        state       <= 5;
                        hbyte       <= ~hbyte;
                    end
                end
                5 : begin // End communication
                    spi_cs <= 1;
                    if(hbyte)
                        begin
                            state <= 0;
                        end
                    else
                        begin
                            state <= 16;
                        end
                end
                6 : begin // Send Write Enable (WREN) command
                    spi_cs <= 0;
                    if (bit_counter < 8) begin
                        spi_mosi <= CMD_WREN[7 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= 0;
                        spi_sck     <= 0;
                        state       <= 7;
                    end
                end
                7 : begin // End WREN command
                    spi_cs <= 1;
                    state  <= 8;
                end
                8 : begin // Wait
                    if (bit_counter < 8) begin
                        bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        state       <= 9;
                        spi_mosi    <= CMD_WRITE[7];
                    end
                end
                9 : begin // Send write command
                    spi_cs <= 0;
                    if (bit_counter < 8) begin
                        spi_mosi <= CMD_WRITE[7 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= address[15];
                        spi_sck     <= 0;
                        state       <= 10;
                    end
                end
                10 : begin // Send address (16 bits) for writing
                    if (bit_counter < 16) begin
                        spi_mosi <= address[15 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_sck     <= 0;
                        state       <= 11;
                        if(hbyte) begin
                            spi_mosi <= write_data_h[7];
                        end else begin
                            spi_mosi <= write_data_l[7];
                        end
                    end
                end
                11 : begin // Write data byte
                    if (bit_counter < 8) begin
                        if(hbyte) begin
                            spi_mosi <= write_data_h[7 - bit_counter];
                        end else begin
                            spi_mosi <= write_data_l[7 - bit_counter];
                        end
                        spi_sck <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= 0;
                        spi_sck     <= 0;
                        state       <= 12;
                        hbyte       <= ~hbyte;
                    end
                end
                12 : begin // End write communication
                    spi_cs <= 1;
                    state  <= 13;
                end
                13 : begin // Wait
                    if (bit_counter < 8) begin
                        bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        state       <= 14;
                        spi_mosi    <= CMD_WRDI[7];
                    end
                end
                14 : begin // Send Write Disable (WRDI) command
                    spi_cs <= 0;
                    if (bit_counter < 8) begin
                        spi_mosi <= CMD_WRDI[7 - bit_counter];
                        spi_sck  <= ~spi_sck;
                        if (!spi_sck) bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        spi_mosi    <= 0;
                        spi_sck     <= 0;
                        state       <= 15;
                    end
                end
                15 : begin // End WRDI command
                    spi_cs <= 1;
                    if(hbyte)
                        begin
                            state <= 6;
                        end
                    else
                        begin
                            state <= 16;
                        end
                end
                16 : begin // Wait
                    if (bit_counter < 8) begin
                        bit_counter <= bit_counter + 1;
                    end else begin
                        bit_counter <= 0;
                        state       <= 0;
                        done        <= 1;
                    end
                end
            endcase
        end
    end
endmodule


module UART_Credits (
    input  wire     clk  ,
    input  wire     rst_n,
    output      reg tx
);

    reg [ 1:0] state              = INIT       ;
    reg [31:0] clk_counter        = 0          ;
    reg [ 3:0] bit_counter        = 0          ;
    reg [ 3:0] char_counter       = 0          ;
    reg [ 7:0] tx_shift_reg       = 8'b11111111;
    reg [31:0] idle_counter       = 0          ;
    reg [ 7:0] MESSAGE     [0:10]              ;

    parameter CLK_FREQ   = 10000000; // 10 MHz
    parameter BAUD_RATE  = 115200  ; // 115200 baud
    parameter BIT_PERIOD = 87      ; // CLK_FREQ / BAUD_RATE
    parameter BIT_COUNT  = 10      ; // 1 start bit, 8 data bits, 1 stop bit
    parameter IDLE_COUNT = 8700    ; // Delay

    localparam [7:0] CHAR_P     = 8'd80 ;
    localparam [7:0] CHAR_h     = 8'd104;
    localparam [7:0] CHAR_i     = 8'd105;
    localparam [7:0] CHAR_l     = 8'd108;
    localparam [7:0] CHAR_i2    = 8'd105;
    localparam [7:0] CHAR_p     = 8'd112;
    localparam [7:0] CHAR_space = 8'd32 ;
    localparam [7:0] CHAR_M     = 8'd77 ;
    localparam [7:0] CHAR_o     = 8'd111;
    localparam [7:0] CHAR_h2    = 8'd104;
    localparam [7:0] CHAR_r     = 8'd114;

    localparam INIT = 0, IDLE = 1, START = 2, TRANSMIT = 3;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            clk_counter  <= 0;
            bit_counter  <= 0;
            char_counter <= 0;
            tx_shift_reg <= 8'b11111111;
            idle_counter <= 0;
            tx           <= 1'b1;
            state        <= INIT;
        end else begin
            case (state)
                INIT : begin
                    MESSAGE[0]  <= CHAR_P;
                    MESSAGE[1]  <= CHAR_h;
                    MESSAGE[2]  <= CHAR_i;
                    MESSAGE[3]  <= CHAR_l;
                    MESSAGE[4]  <= CHAR_i2;
                    MESSAGE[5]  <= CHAR_p;
                    MESSAGE[6]  <= CHAR_space;
                    MESSAGE[7]  <= CHAR_M;
                    MESSAGE[8]  <= CHAR_o;
                    MESSAGE[9]  <= CHAR_h2;
                    MESSAGE[10] <= CHAR_r;
                    state       <= START;
                end
                IDLE : begin
                    if (idle_counter < IDLE_COUNT) begin
                        idle_counter <= idle_counter + 1;
                    end else begin
                        idle_counter <= 0;
                        state        <= START;
                    end
                end
                START : begin
                    char_counter <= 0;
                    tx_shift_reg <= MESSAGE[0];
                    state        <= TRANSMIT;
                end
                TRANSMIT : begin
                    if (clk_counter < BIT_PERIOD) begin
                        clk_counter <= clk_counter + 1;
                    end else begin
                        clk_counter <= 0;
                        if (bit_counter < BIT_COUNT) begin
                            bit_counter <= bit_counter + 1;
                            case (bit_counter)
                                0 : tx <= 1'b0;
                                1 : tx <= tx_shift_reg[0];
                                2 : tx <= tx_shift_reg[1];
                                3 : tx <= tx_shift_reg[2];
                                4 : tx <= tx_shift_reg[3];
                                5 : tx <= tx_shift_reg[4];
                                6 : tx <= tx_shift_reg[5];
                                7 : tx <= tx_shift_reg[6];
                                8 : tx <= tx_shift_reg[7];
                                9 : tx <= 1'b1;
                            endcase
                        end else begin
                            bit_counter <= 0;
                            if (char_counter < 10) begin
                                char_counter <= char_counter + 1;
                                tx_shift_reg <= MESSAGE[char_counter + 1];
                            end else begin
                                char_counter <= 0;
                                state        <= IDLE;
                            end
                        end
                    end
                end
            endcase
        end
    end
endmodule


module UART_Transmitter (
    input  wire           clk     ,
    input  wire           rst_n   ,
    input  wire           tx_start,
    input  wire     [7:0] tx_data ,
    output      reg       tx      ,
    output      reg       tx_busy
);

    reg [15:0] baud_counter;
    reg [ 3:0] bit_counter ;
    reg [ 7:0] shift_reg   ;
    reg        transmitting;

    localparam CLK_FREQ   = 10000000; // 10 MHz
    localparam BAUD_RATE  = 115200  ; // 115200 baud
    localparam BIT_PERIOD = 87      ; // CLK_FREQ / BAUD_RATE

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            tx           <= 1'b1;
            tx_busy      <= 1'b0;
            transmitting <= 1'b0;
            baud_counter <= 0;
            bit_counter  <= 0;
            shift_reg    <= 0;
        end else begin
            if (tx_start && !transmitting) begin
                transmitting <= 1'b1;
                tx_busy      <= 1'b1;
                shift_reg    <= tx_data;
                bit_counter  <= 0;
                baud_counter <= 0;
                tx           <= 1'b0;
            end else if (transmitting) begin
                if (baud_counter < BIT_PERIOD - 1) begin
                    baud_counter <= baud_counter + 1;
                end else begin
                    baud_counter <= 0;
                    if (bit_counter < 8) begin
                        tx          <= shift_reg[0];
                        shift_reg   <= shift_reg >> 1;
                        bit_counter <= bit_counter + 1;
                    end else if (bit_counter == 8) begin
                        tx          <= 1'b1;
                        bit_counter <= bit_counter + 1;
                    end else begin
                        tx_busy      <= 1'b0;
                        transmitting <= 1'b0;
                        bit_counter  <= 0;
                    end
                end
            end
        end
    end
endmodule


Reference solution:
rtl/generated.v: 
	assign in_miso = ui_in[0];

	assign uio_out     = data;
	assign uio_oe      = 8'b11111111;
	assign uo_out[0]   = out_mosi;
	assign uo_out[1]   = out_sck;
	assign uo_out[2]   = out_cs;
	assign uo_out[3]   = tx;
	assign uo_out[4]   = ctx;
	assign uo_out[7:5] = 3'b111;

	assign char_out     = data_a[7:0];
	assign char_valid   = char_output_flag;
	assign result       = data_b - data_a;

	reg signed [15:0] ir_a, ir_b, ir_c;
	reg signed [15:0] data_a, data_b;
	reg        [ 5:0] state, next_state;
	reg        [ 7:0] data            ;
	reg        [15:0] pc              ;
	reg               char_output_flag;
	reg               halted_reg      ;
	reg signed [15:0] data_to_ram     ;
	reg               ram_we          ;
	reg        [15:0] ram_addr        ;
	reg               tx_start        ;
	reg               ramstart        ;

	wire               ramdone      ;
	wire        [ 7:0] char_out     ;
	wire               char_valid   ;
	wire        [15:0] data_from_ram;
	wire               tx_busy      ;
	wire               ctx          ;
	wire               tx           ;
	wire signed [15:0] result       ;
	wire               in_miso      ;
	wire               out_mosi     ;
	wire               out_sck      ;
	wire               out_cs       ;

	SPI_FRAM_Interface ram (
		.clk     (clk          ),
		.rst_n   (rst_n        ),
		.addr    (ram_addr     ),
		.spi_miso(in_miso      ),
		.spi_mosi(out_mosi     ),
		.spi_sck (out_sck      ),
		.spi_cs  (out_cs       ),
		.data_in (data_to_ram  ),
		.we      (ram_we       ),
		.start   (ramstart     ),
		.done    (ramdone      ),
		.data_out(data_from_ram)
	);

	UART_Credits CreditsTX (
		.clk  (clk  ),
		.rst_n(rst_n),
		.tx   (ctx  )
	);

	UART_Transmitter uart_tx (
		.clk     (clk     ),
		.rst_n   (rst_n   ),
		.tx_start(tx_start),
		.tx_data (char_out),
		.tx      (tx      ),
		.tx_busy (tx_busy )
	);

	localparam START	 = 6'd0,
		FETCH_A0  = 6'd1,
		FETCH_A1  = 6'd2,
		FETCH_A2  = 6'd3,
		FETCH_B0  = 6'd4,
		FETCH_B1  = 6'd5,
		FETCH_B2  = 6'd6,
		FETCH_C0  = 6'd7,
		FETCH_C1  = 6'd8,
		FETCH_C2  = 6'd9,
		DECODE_A0 = 6'd10,
		DECODE_A1 = 6'd11,
		DECODE_A2 = 6'd12,
		DECODE_B0 = 6'd13,
		DECODE_B1 = 6'd14,
		DECODE_B2 = 6'd15,
		WRITE_B0 = 6'd16,
		WRITE_B1 = 6'd17,
		WRITE_B2 = 6'd18,
		HALT     = 6'd19;



	always @(posedge clk or negedge rst_n) begin
		if (!rst_n)
			state <= START;
		else
			state <= next_state;
	end

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) begin
			pc               <= 15'd0;
			ir_a             <= 16'b0;
			ir_b             <= 16'b0;
			ir_c             <= 16'b0;
			data_a           <= 16'b0;
			data_b           <= 16'b0;
			char_output_flag <= 1'b0;
			halted_reg       <= 1'b0;
			data_to_ram      <= 16'b0;
			ram_addr         <= 15'b0;
			ram_we           <= 1'b0;
		end else begin
			case (state)

				START : begin
					ram_addr <= pc;
					ramstart <= 1'b1;
				end

				// Fetch A B C
				FETCH_A0 : begin
					ram_addr <= pc;
					ramstart <= 1'b1;
				end

				FETCH_A1 : begin
					ramstart <= 1'b0;
				end

				FETCH_A2 : begin
					ir_a <= data_from_ram;
				end

				FETCH_B0 : begin
					ram_addr <= pc + 1;
					ramstart <= 1'b1;
				end

				FETCH_B1 : begin
					ramstart <= 1'b0;
				end

				FETCH_B2 : begin
					ir_b <= data_from_ram;
				end

				FETCH_C0 : begin
					ram_addr <= pc + 2;
					ramstart <= 1'b1;
				end

				FETCH_C1 : begin
					ramstart <= 1'b0;
				end

				FETCH_C2 : begin
					ir_c <= data_from_ram;
				end

				// Decode A B
				DECODE_A0 : begin
					ram_addr <= ir_a;
					ramstart <= 1'b1;
				end

				DECODE_A1 : begin
					ramstart <= 1'b0;
				end

				DECODE_A2 : begin
					data_a <= data_from_ram;
				end

				DECODE_B0 : begin
					if(ir_b == -1) begin
						char_output_flag <= 1'b1;
						data             <= char_out;
						ram_addr         <= 16'b0;
						ramstart         <= 1'b1;
					end else begin
						ram_addr <= ir_b;
						ramstart <= 1'b1;
					end
					if(ir_c < 0) begin
						halted_reg <= 1'b1;
					end
				end

				DECODE_B1 : begin
					ramstart         <= 1'b0;
					char_output_flag <= 1'b0;
				end

				DECODE_B2 : begin
					if(ir_b == -1) begin
						data_b <= 16'b0;
					end else begin
						data_b <= data_from_ram;
					end
				end

				// Write B-A to address B
				WRITE_B0 : begin
					if(ir_b == -1) begin
						ram_addr <= 16'b0;
						ramstart <= 1'b1;
						ram_we   <= 1'b0;
					end else begin
						ram_addr    <= ir_b;
						ramstart    <= 1'b1;
						ram_we      <= 1'b1;
						data_to_ram <= result;
					end
				end

				WRITE_B1 : begin
					ramstart <= 1'b0;
				end

				WRITE_B2 : begin
					pc     <= (result > 0 || ir_b == -1) ? pc + 3 : ir_c;
					ram_we <= 1'b0;
				end

				HALT : begin
					halted_reg <= 1'b1;
				end

			endcase
		end
	end

	always @(*) begin
		if(halted_reg)
			next_state = HALT;
		else
			case (state)
				START     : next_state = FETCH_A0;
				FETCH_A0  : next_state = FETCH_A1;
				FETCH_A1  : next_state = ramdone ? FETCH_A2 : FETCH_A1;
				FETCH_A2  : next_state = FETCH_B0;
				FETCH_B0  : next_state = FETCH_B1;
				FETCH_B1  : next_state = ramdone ? FETCH_B2 : FETCH_B1;
				FETCH_B2  : next_state = FETCH_C0;
				FETCH_C0  : next_state = FETCH_C1;
				FETCH_C1  : next_state = ramdone ? FETCH_C2 : FETCH_C1;
				FETCH_C2  : next_state = DECODE_A0;
				DECODE_A0 : next_state = DECODE_A1;
				DECODE_A1 : next_state = ramdone ? DECODE_A2 : DECODE_A1;
				DECODE_A2 : next_state = DECODE_B0;
				DECODE_B0 : next_state = DECODE_B1;
				DECODE_B1 : next_state = ramdone ? DECODE_B2 : DECODE_B1;
				DECODE_B2 : next_state = !tx_busy ? WRITE_B0 : DECODE_B2;
				WRITE_B0  : next_state = WRITE_B1;
				WRITE_B1  : next_state = ramdone ? WRITE_B2 : WRITE_B1;
				WRITE_B2  : next_state = FETCH_A0;
				HALT      : next_state = HALT;
			endcase
	end

	always @(posedge clk or negedge rst_n) begin
		if (!rst_n) begin
			tx_start <= 1'b0;
		end else begin
			if (char_valid && !tx_busy) begin
				tx_start <= 1'b1;
			end else begin
				tx_start <= 1'b0;
			end
		end
	end