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.

/* 
 clk : clock for the internal counter and the state change process
 reset : when '1', reset the counter and return to state S0
 ovf : when '1', allows to go from state s0 to s1 (starts the state machine and sending data)
 selection_bits : output of the state machine, controls the multiplexer according to the output to send
 SL : controls the PISO_regiter. When '1' Load, '0' shift
 rst : reset all channel counters when the sending is over 
*/

module FSM(input clk, input reset, input wire ovf, output reg [3:0] selection_bits, output reg SL, output reg rst);

  reg counter_increment;
	reg [3:0] counter_register;
  
  localparam [4:0]
  s0 = 0,
  s1 = 1,
  s2 = 2,
  s3 = 3,
  s4 = 4,
  s5 = 5,
  s6 = 6,
  s7 = 7,
  s8 = 8,
  s9 = 9,
  s10 = 10,
  s11 = 11,
  s12 = 12,
  s13 = 13,
  s14 = 14,
  s15 = 15,
  s16 = 16,
  s17 = 17; 

	reg[4:0] state_reg, state_next;

 
// Internal counter process
  always @(posedge clk or posedge reset) begin

	if(reset==1) begin
		counter_register <= 4'b0;
	end

	else if (clk == 1) begin

		//The counter increment if the signal counter_increment is high
		if (counter_increment == 1) begin
			counter_register <= counter_register + 1;
		end
		//The counter reset when richs 11
		if(counter_register == 4'b1011) begin
      			counter_register <= 4'b0;
    		end
	end
  end


// State change process 
  always @(posedge clk or posedge reset) begin
  
	if(reset == 1) begin
		state_reg <= s0;
	end
    	
	else if (clk == 1) begin
		state_reg <= state_next;
	end
  end

// State Machine
  always @(*) begin
 
// default state_next and outputs
    state_next = state_reg; 
	rst = 0;
	SL = 0;
	counter_increment = 0;
	selection_bits = 4'b0000;

    case (state_reg)
        s0 : begin
		rst = 0;
		SL = 0;
		counter_increment = 0;
		selection_bits = 4'b0000;
		
          	if (ovf == 1) begin  
                	state_next = s1; 
            	end
            	else begin
                	state_next = s0; 
            	end
        end

        s1 : begin //RTC 
		
		selection_bits = 4'b0000;
		counter_increment = 1;
			
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
			
		end
		
          	if (counter_register == 4'b1011) begin  
                	state_next = s2; 
            	end
            	else begin // remain in current state
                	state_next = s1; 
            	end
        end

        s2 : begin //CH1 

		selection_bits = 4'b0001;
		counter_increment = 1;
			
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
		
          	if (counter_register == 4'b1011) begin  
                	state_next = s3; 
            	end
            	else begin // remain in current state
                	state_next = s2; 
            	end
        end
      s3 : begin //CH2 

		selection_bits = 4'b0010;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end

          	if (counter_register == 4'b1011) begin  
                	state_next = s4; 
            	end
            	else begin // remain in current state
                	state_next = s3; 
            	end
        end
      s4 : begin //CH3 
		
		selection_bits = 4'b0011;
		//SL = 0;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s5; 
            	end
            	else begin // remain in current state
                	state_next = s4; 
            	end
        end
      s5 : begin //CH4 
		selection_bits = 4'b0100;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s6; 
            	end
            	else begin // remain in current state
                	state_next = s5; 
            	end
        end

      s6 : begin //CH5 
		selection_bits = 4'b0101;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s7; 
            	end
            	else begin // remain in current state
                	state_next = s6; 
            	end
        end

      s7 : begin //CH6 

		selection_bits = 4'b0110;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end

		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s8; 
            	end
            	else begin // remain in current state
                	state_next = s7; 
            	end
        end

      s8 : begin //CH7 

		selection_bits = 4'b0111;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s9; 
            	end
            	else begin // remain in current state
                	state_next = s8; 
            	end
        end

      s9 : begin //CH8 
		selection_bits = 4'b1000;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s10; 
            	end
            	else begin // remain in current state
                	state_next = s9; 
            	end
        end

      s10 : begin //CH9 
		selection_bits = 4'b1001;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;

		end		

          	if (counter_register == 4'b1011) begin  
                	state_next = s11; 
            	end
            	else begin // remain in current state
                	state_next = s10; 
            	end
        end

      s11 : begin //CH10 
		selection_bits = 4'b1010;

		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end

		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s12; 
            	end
            	else begin // remain in current state
                	state_next = s11; 
            	end
        end

      s12 : begin //CH11 

		selection_bits = 4'b1011;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
	
          	if (counter_register == 4'b1011) begin  
                	state_next = s13; 
            	end
            	else begin // remain in current state
                	state_next = s12; 
            	end
        end

      s13 : begin //CH12 
		selection_bits = 4'b1100;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end

	
          	if (counter_register == 4'b1011) begin  
                	state_next = s14; 
            	end
            	else begin // remain in current state
                	state_next = s13; 
            	end
        end

      s14 : begin //CH13 
		selection_bits = 4'b1101;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end

	
          	if (counter_register == 4'b1011) begin  
                	state_next = s15; 
            	end
            	else begin // remain in current state
                	state_next = s14; 
            	end
        end

      s15 : begin //CH14 
		selection_bits = 4'b1110;
		//SL = 1;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
		
          	if (counter_register == 4'b1011) begin  
                	state_next = s16; 
            	end
            	else begin // remain in current state
                	state_next = s15; 
            	end
        end

      s16 : begin //CH15 
		selection_bits = 4'b1111;
		counter_increment = 1;
		if (counter_register == 4'b0000) begin
			SL = 1;
		end
		else begin
			SL = 0;
		end
		
          	if (counter_register == 4'b1011) begin  
                	state_next = s17; 
            	end
            	else begin // remain in current state
                	state_next = s16; 
            	end
        end

      s17 : begin 
		rst = 1;
		counter_increment = 0;
 		SL = 0;
               state_next = s0; 

        end

      default : begin
        state_next = s0;
      end
    endcase
end 
  
endmodule




/*
clk : clock for shif and load operations
parallel_in : output of the MUX, data to be send
SL : '1' => load, '0' => shift
serial_out : data serialization
*/

module PISO_register(
  input wire clk,
  input wire [11:0] parallel_in,
  input wire SL, 
  output reg serial_out
  
);
  
reg [10:0] register;
	
always @(posedge clk) begin
    if(SL==1) begin
	
	    register[10:0] <= parallel_in[11:1]; // Load 
	    serial_out <= parallel_in[0];  // Output the least significant bit
	       
    end
    else if (SL==0) begin
	
	serial_out <= register[0]; // Output the least significant bit
        register <= register >>> 1; //shift
	
    end
  end

endmodule


/*
purpose : count each emission when detect a rising edge
impulse : signal coming from analog design (resonance of one of the piezo sensors) 
reset : when ('1') reset the counter
enable : when ('0') allows the counter to increment
data : value of the counter (from 0 to 4095)
ovf : '1' when the counter overflows
*/

module channel_counter(input impulse, input reset, input enable, output reg [11:0] data, output reg ovf
                       );


  always @(posedge reset or posedge impulse) begin
	  
    if(reset == 1) begin
	data <= 12'b0;
	ovf <= 0;	
    end
    	else if(impulse == 1) begin
		if (enable == 0) begin
      			data <= data + 1;
		end
      		if(data == 4095) begin
			ovf <= 1;
		end
    		
	  end
  
  end
  
endmodule


module mux_16to1(input wire [11:0] data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, data13, data14, data15,
                input wire [3:0] select,
           output reg [11:0] data_out
          );
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule




/*
purspose : when the counter reaches 59:59 => send of the counter values
clk : RTC clock (1Hz for a send each hour)
reset : when '1' reset the counter
rst_ovf : when '1' force ovf signal to 0 (signal coming from FSM to report sending is over)
sec : second counter (from 0 to 59)
min : minutes counter (from 0 to 59)
ovf : hight when counter reaches 59:59
*/

module time_counter(input clk, input reset, input rst_ovf, output reg [5:0] sec,
               output reg [5:0] min, output reg ovf);

    
wire clear_ovf;
assign clear_ovf = rst_ovf || reset;

always @(posedge clk or posedge clear_ovf) begin

        if(clear_ovf == 1) begin
		ovf <= 0;
    	end
	else begin
		if(sec == 59 & min == 59) begin
			ovf <= 1;
		end
	end
end
	
  always @(posedge clk or posedge reset) begin
	  
    if(reset == 1) begin
	sec <= 6'b0;
	min <= 6'b0;
    end

    else begin
    sec <= sec + 1;
    if(sec == 59) begin
    sec <= 0;
      min <= min + 1;
    end
    if(sec == 59 & min == 59) begin
      sec <= 6'b0;
  	min <= 6'b0;
      
    end
  end
  end
  
  
endmodule


//`include "channel_counter.v"
//`include "FSM.v"
//`include "time_counter.v"
//`include "PISO_register.v"
//`include "mux_16to1.v"

/*
clk : clock for PISO_register and FSM
RTC : clock for time counter
ch1 to ch15 : cloks for channel counters
reset : when ('1') reset all components 
serial_out : main output, active periodically (when ovf_global is hight). serialization of counter values.
ovf_global : hight if one channel overflow or if the time_counter reaches 59:59
ovf_RTC_out : hight if the time_counter reaches 59:59
a0_out to a3_out : selection bits of the MUX (use for debuging) 
SL_out : Shift/load signal for PISO_register
*/

module top(input clk, ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, reset,RTC,
           output wire serial_out, ovf_global, ovf_RTC_out, a0_out, a1_out, a2_out, a3_out, SL_out
           );


  wire [3:0] selection_bits;
  wire [11:0] data [15:0]; //RTC_counter = data[0], ch1_counter = data[1] etc...
  wire ovf1, ovf2, ovf3, ovf4, ovf5,ovf6,ovf7,ovf8,ovf9,ovf10,ovf11,ovf12,ovf13,ovf14,ovf15,ovf_RTC;
  wire [11:0] mux_data_out;
  wire SL;
  wire out_rst; 
  wire  ovf_ch_out;

  assign ovf_RTC_out = ovf_RTC;
  assign ovf_ch_out = ovf1||ovf2||ovf3||ovf4||ovf5||ovf6||ovf7||ovf8||ovf9||ovf10||ovf11||ovf12||ovf13||ovf14||ovf15;
  assign {a3_out, a2_out , a1_out, a0_out} = selection_bits[3:0];
  assign SL_out = SL;
  
  assign ovf_global = ovf_ch_out||ovf_RTC;


  time_counter time_c(.clk(RTC), .reset(reset), .rst_ovf(out_rst),
                        .min(data[0][11:6]),.sec(data[0][5:0]),.ovf(ovf_RTC))/* synthesis syn_noprune=1 */;

  channel_counter ch1c(.impulse(ch1), .reset(reset||out_rst), .enable(ovf_global), 
                        .data(data[1]), .ovf(ovf1))/* synthesis syn_noprune=1 */;
  channel_counter ch2c(.impulse(ch2), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[2]), .ovf(ovf2))/* synthesis syn_noprune=1 */;
  channel_counter ch3c(.impulse(ch3), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[3]), .ovf(ovf3))/* synthesis syn_noprune=1 */;
  channel_counter ch4c(.impulse(ch4), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[4]), .ovf(ovf4))/* synthesis syn_noprune=1 */; 
  channel_counter ch5c(.impulse(ch5), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[5]), .ovf(ovf5))/* synthesis syn_noprune=1 */;
  channel_counter ch6c(.impulse(ch6), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[6]), .ovf(ovf6))/* synthesis syn_noprune=1 */;
  channel_counter ch7c(.impulse(ch7), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[7]), .ovf(ovf7))/* synthesis syn_noprune=1 */;
  channel_counter ch8c(.impulse(ch8), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[8]), .ovf(ovf8))/* synthesis syn_noprune=1 */;
  channel_counter ch9c(.impulse(ch9), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[9]), .ovf(ovf9))/* synthesis syn_noprune=1 */;
  channel_counter ch10c(.impulse(ch10), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[10]), .ovf(ovf10))/* synthesis syn_noprune=1 */;
  channel_counter ch11c(.impulse(ch11), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[11]), .ovf(ovf11))/* synthesis syn_noprune=1 */;
  channel_counter ch12c(.impulse(ch12), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[12]), .ovf(ovf12))/* synthesis syn_noprune=1 */;
  channel_counter ch13c(.impulse(ch13), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[13]), .ovf(ovf13))/* synthesis syn_noprune=1 */;
  channel_counter ch14c(.impulse(ch14), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[14]), .ovf(ovf14))/* synthesis syn_noprune=1 */;
  channel_counter ch15c(.impulse(ch15), .reset(reset||out_rst), .enable(ovf_global),
                        .data(data[15]), .ovf(ovf15))/* synthesis syn_noprune=1 */;


  
FSM FSM1(.clk(clk),.reset(reset),.ovf(ovf_global),.selection_bits(selection_bits),.SL(SL),.rst(out_rst))/* synthesis syn_noprune=1 */;
  
  mux_16to1 mux(.data0(data[0][11:0]),.data1(data[1][11:0]),.data2(data[2][11:0]),.data3(data[3][11:0]),.data4(data[4][11:0]),.data5(data[5][11:0]),
.data6(data[6][11:0]),.data7(data[7][11:0]),.data8(data[8][11:0]),.data9(data[9][11:0]),.data10(data[10][11:0]),.data11(data[11][11:0]),.data12(data[12][11:0]),
.data13(data[13][11:0]),.data14(data[14][11:0]),.data15(data[15][11:0]) ,.select(selection_bits[3:0]), .data_out(mux_data_out[11:0]));               

  
  PISO_register PISO_register1(.clk(clk),.parallel_in(mux_data_out[11:0]),.SL(SL),.serial_out(serial_out));

 
  

  
endmodule


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

/*`default_nettype none*/

module tt_um_Coline3003_top(
    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,      // will go high when the design is enabled
    input  wire       clk,      // clock
    input  wire       rst_n     // reset_n - low to reset
                              );

   wire reset;
   assign reset = ~rst_n;

    top top1(.reset(reset), 
	     .clk(clk), 
	     .RTC(ui_in[0]), 
	     .ch1(ui_in[1]), 
	     .ch2(ui_in[2]), 
	     .ch3(ui_in[3]), 
	     .ch4(ui_in[4]), 
	     .ch5(ui_in[5]),  
	     .ch6(ui_in[6]),
	     .ch7(ui_in[7]), 
	     .ch8(uio_in[0]), 
	     .ch9(uio_in[1]), 
	     .ch10(uio_in[2]), 
	     .ch11(uio_in[3]), 
	     .ch12(uio_in[4]), 
	     .ch13(uio_in[5]), 
	     .ch14(uio_in[6]), 
	     .ch15(uio_in[7]),
             .serial_out(uo_out[0]), 
	     .ovf_global(uo_out[1]), 
	     .ovf_RTC_out(uo_out[2]), 
	     .a0_out(uo_out[3]), 
	     .a1_out(uo_out[4]), 
             .a2_out(uo_out[5]), 
	     .a3_out(uo_out[6]), 
	     .SL_out(uo_out[7]));
	
    assign uio_out = 8'b0;
    assign uio_oe = 8'b0; //inputs enable

    // List all unused inputs to prevent warnings
    wire _unused = &{ena};
	
endmodule // top



Reference solution:
rtl/generated.v: 

  always @(*) begin
    casez (select)  
      4'b0000 : data_out = data0; 
      4'b0001 : data_out = data1; 
      4'b0010 : data_out = data2;
      4'b0011 : data_out = data3;
      4'b0100 : data_out = data4;
      4'b0101 : data_out = data5;
      4'b0110 : data_out = data6;
      4'b0111 : data_out = data7;
      4'b1000 : data_out = data8;
      4'b1001 : data_out = data9;
      4'b1010 : data_out = data10;
      4'b1011 : data_out = data11;
      4'b1100 : data_out = data12;
      4'b1101 : data_out = data13;
      4'b1110 : data_out = data14;
      4'b1111 : data_out = data15;
      default :  data_out = 12'b0;
     endcase  
   end