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 Fabio Ramirez Stern
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none
// `include "controller.v"
// `include "rotary_decoder.v"
// `include "led_ring_driver.v"

module tt_um_faramire_rotary_ring_wrapper (
    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
);

  wire [11:0] led_mask_wire;
  wire [ 7:0] intensity_wire;

  wire rot_up_wire;
  wire rot_dn_wire;

  controller ctr1 (
    .clk(clk),
    .res_n(rst_n),
    .rot_up(rot_up_wire),
    .rot_dn(rot_dn_wire),
    .push(ui_in[2]),
    .intensity_in(ui_in[7:6]),

    .led_mask(led_mask_wire),
    .intensity_out(intensity_wire),
    .state_out(uo_out[5:1])
  );

  rotary_decoder rdec1 (
    .clk(clk),
    .res_n(rst_n),
    .rotary_clk(ui_in[0]),
    .rotary_dt(ui_in[1]),
    
    .rotation_up(rot_up_wire),
    .rotation_dn(rot_dn_wire)
  );

  led_ring_driver leddriv1 (
    .clk(clk),
    .res_n(rst_n),
    .led_mask(led_mask_wire),
    .colour(ui_in[5:3]),
    .intensity(intensity_wire),

    .led_dout(uo_out[0])
  );
  
  // All output pins must be assigned. If not used, assign to 0.
  assign uo_out[7:6] = 2'b0;
  assign uio_out = 8'b0;
  assign uio_oe  = 8'b0;

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

endmodule


/*
 * Copyright (c) 2024 Fabio Ramirez Stern
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module controller (
  input  wire clk,    // clock (40 Mhz)
  input  wire res_n,  // active low reset
  input  wire rot_up,
  input  wire rot_dn,
  input  wire push,   // push button
  input  wire [1:0] intensity_in,

  output wire [11:0] led_mask,
  output reg  [ 7:0] intensity_out,
  output reg  [ 4:0] state_out
);

  // State
  reg inverted;
  reg [3:0] led_binary;

  reg [11:0] led_mask_i; // internal, without inversion
  assign led_mask = {12{inverted}} ^ led_mask_i;

  // Inversion
  always @(posedge clk) begin
    if (!res_n) begin
      inverted <= 0;
    end else begin
      if (push) begin
        inverted <= ~inverted;
      end
    end
  end

  // Intensity
  always @(posedge clk) begin
    if (!res_n) begin
      intensity_out <= 8'b0000_0001;
    end else begin
      case(intensity_in[1:0])
        2'b00: intensity_out <= 8'b0000_0001;
        2'b01: intensity_out <= 8'b0000_0010;
        2'b10: intensity_out <= 8'b0000_1000;
        2'b11: intensity_out <= 8'b0010_0000;
        default:;
      endcase
    end
  end
  
  // LED
  always @(posedge clk) begin
    if (!res_n) begin //reset
      led_mask_i <= 12'b0000_0000_0001;
      state_out  <= 5'b1_1111;
      led_binary <= 4'b0;
    end else begin

      // Counting
      if (rot_up) begin
        led_mask_i <= (led_mask_i << 1) | (led_mask_i >> 11); // shift with rotate
      end else if (rot_dn) begin
        led_mask_i <= (led_mask_i >> 1) | (led_mask_i >> 11);
      end

      case(led_mask_i)
        12'b0000_0000_0001: led_binary <= 4'b0000;
        12'b0000_0000_0010: led_binary <= 4'b0001;
        12'b0000_0000_0100: led_binary <= 4'b0010;
        12'b0000_0000_1000: led_binary <= 4'b0011;
        12'b0000_0001_0000: led_binary <= 4'b0100;
        12'b0000_0010_0000: led_binary <= 4'b0101;
        12'b0000_0100_0000: led_binary <= 4'b0110;
        12'b0000_1000_0000: led_binary <= 4'b0111;
        12'b0001_0000_0000: led_binary <= 4'b1000;
        12'b0010_0000_0000: led_binary <= 4'b1001;
        12'b0100_0000_0000: led_binary <= 4'b1010;
        12'b1000_0000_0000: led_binary <= 4'b1011;
        default:;
      endcase

      state_out <= {inverted, led_binary};

    end
  end

endmodule

/*
 * Copyright (c) 2024 Fabio Ramirez Stern
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module rotary_decoder (
  
  /*
  * Rotary Encoder Decoder
  * Takes the two outputs of a rotary coder and determines in which direction it was turned. Output as one hot encoding.
  * rotary_clk and rotary_dt can be swapped to change direction, their connection should be arbitrary.
  */

  input  wire clk,   // 40MHz clock
  input  wire res_n, // active low reset
  input  wire rotary_clk, // output labeled clk of the rotary encoder (active low)
  input  wire rotary_dt,  // output labeled dt  of the rotary encoder (active low)

  output reg rotation_up,  // goes high for one clock cycle if rotated upwards (clockwise)
  output reg rotation_dn   // goes high for one clock cycle if rotated downwards (counter clockwise)
);

  reg up_detected;
  reg dn_detected;
  reg [1:0] state;

  // FSM states
  localparam DETECTING = 2'b00;
  localparam OUTPUT    = 2'b01;
  localparam PAUSE     = 2'b10;
  localparam WAIT      = 2'b11;

  // Pause counter
  reg [14:0] pause_counter;

  always @(posedge clk) begin // process to monitor encoder
    
    if (!res_n) begin // reset
      rotation_up <= 0;
      rotation_dn <= 0;
      state <= DETECTING;
    end else begin

      case(state) // FSM

        DETECTING: begin
          if (!rotary_clk) begin // movement detected
            if (!rotary_dt) begin // rotary_dt already high => up movement
              up_detected <= 1;
              dn_detected <= 0;
              state <= OUTPUT;
            end else begin       // rotary_dt still low => down movement
              up_detected <= 0;
              dn_detected <= 1;
              state <= OUTPUT;
            end
          end
        end // DETECTING

        OUTPUT: begin // copy the detected state to the outputs and go to next state where they will be set to 0 again => on for one clock
          rotation_up <= up_detected;
          rotation_dn <= dn_detected;
          pause_counter <= 15'b0;
          state <= PAUSE;
        end //OUTPUT

        PAUSE: begin // pause for 1 ms to debounce (40k clock cycles)
          rotation_up <= 0;
          rotation_dn <= 0;
          if (pause_counter == 15'b100_1110_0001_1111) begin
            state <= WAIT;
          end else begin
            pause_counter <= pause_counter + 15'b1;
          end
        end // PAUSE

        WAIT: begin // wait until both inputs are high again, then transition to detecting again
          if (rotary_clk && rotary_dt) begin
            state <= DETECTING;
          end          
        end // WAIT

        default:;
      endcase

    end

  end
endmodule

/*
 * Copyright (c) 2024 Fabio Ramirez Stern
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module led_ring_driver (
  input  wire clk,     // clock (40 Mhz)
  input  wire res_n,   // active low reset
  input  wire [11:0] led_mask, // one hot mask of which LEDs to turn on and which to keep off
  input  wire [ 2:0] colour,   // GRB mask
  input  wire [ 7:0] intensity,  // intensity for LEDs that are 1

  output reg led_dout // digital output to LEDs
);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule



Reference solution:
rtl/generated.v: 
  reg skip_calc;

  // input latches
  reg [11:0] reg_led_mask;
  reg  [2:0] reg_colour;
  reg  [7:0] reg_intensity;

  // FSM states
  reg [1:0] state;
  localparam IDLE = 2'b00; // start
  localparam CALC = 2'b01; // calc next timings
  localparam OUTP = 2'b10; // send data to LEDs, retun to CALC
  localparam TRES = 2'b11; // wait 50us (minimum reset time)

  // timing counters
  reg  [5:0] tl_counter; // counter for low time (34/18 clk cycles)
  reg  [5:0] tl_max;
  reg  [5:0] th_counter; // counter for high time (16/32 clk cycles)
  reg  [5:0] th_max;
  reg [10:0] rs_counter; // counter for reset time (4000 clk cycles)
  reg  [3:0] led_pos;    // led position counter (0..11)
  reg  [1:0] grb_pos;    // green, red, blue counter (0..2)
  reg  [2:0] byte_pos;   // grb byte counter (0..7)


  always @(posedge clk) begin
    
    if (!res_n) begin
      led_dout <= 0;
      state <= IDLE;
    end else begin
    case(state)

      IDLE: begin //initiate all registers for transmission
        reg_led_mask  <= led_mask;
        reg_colour    <= colour;
        reg_intensity <= intensity;
        rs_counter <= 0;
        tl_counter <= 0;
        tl_counter <= 0;
        tl_counter <= 0;
        skip_calc <= 0;
        led_pos  <= 0;
        grb_pos  <= 0;
        byte_pos <= 0;
        state <= CALC;
      end // IDLE

      CALC: begin // calculate the timings needed to transmit the next bit, count through bytes of colour, the three colours and the 12 LEDs
        if(reg_led_mask[led_pos]) begin // if current LED should be on
          if(reg_colour[grb_pos] && reg_intensity[byte_pos]) begin // if current colour should be on and current intensity bit is 1
            tl_max <= 32;
            th_max <= 18;
          end else begin
            tl_max <= 16;
            tl_max <= 34;
          end

          if (byte_pos < 7) begin // advance to next bit
            byte_pos <= byte_pos + 1;
          end else begin // end of colour byte, advance to next colour byte
            if (grb_pos < 2) begin
              byte_pos <= 0;
              grb_pos <= grb_pos + 1;
            end else begin // end of LED colour word, advance to next LED
              if (led_pos < 11) begin
                byte_pos <= 0;
                grb_pos <= 0;
                led_pos <= led_pos + 1;
              end else begin // last bit of last colour of last LED, ie end of transmission, do not go back
                skip_calc <= 1;
              end
            end
          end
        end

        state <= OUTP;
      end // CALC

      OUTP: begin // output one bit according to the WS281B
        if (tl_counter < tl_max) begin // hold low, count cycles
          led_dout <= 0;
          tl_counter <= tl_counter + 6'b1;
        end else begin // hold high, count cycles
          if(th_counter < th_max) begin
            led_dout <= 1;
            th_counter <= th_counter + 6'b1;
          end else begin
            if(skip_calc) begin // end of transmission? don't go to CALC, advance to TRES
              state <= TRES;
            end else begin
              state <= CALC;
            end
          end
        end
      end // OUTP

      TRES: begin // wait for the minimum reset time (t_res), then advance to IDLE
        led_dout <= 0;
        if (rs_counter >= 11'b111_1101_0000) begin
          state <= IDLE;
        end else begin
          rs_counter <= rs_counter + 11'b1;
        end
      end // TRES

      default:;
    endcase
    end

  end