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.

//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    17:21:26 11/13/2013 
// Design Name: 
// Module Name:    simon_datapath_shiftreg 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module simon_datapath_shiftreg(clk,reset,data_in,data_rdy,key_in,cipher_out,round_counter,bit_counter,valid);

   input clk,data_in,key_in,reset;
   input [1:0] data_rdy;
   input [6:0] round_counter;
   output 	   cipher_out;
   output [5:0] bit_counter;
   output 		valid;
   
   reg [55:0] 	shifter1;
   reg [63:0] 	shifter2;
   reg 			shift_in1,shift_in2;
   wire 		shift_out1,shift_out2;
   reg 			shifter_enable1,shifter_enable2;
   
   reg 			fifo_ff63,fifo_ff62,fifo_ff61,fifo_ff60,fifo_ff59,fifo_ff58,fifo_ff57,fifo_ff56;
   reg 			lut_ff63,lut_ff62,lut_ff61,lut_ff60,lut_ff59,lut_ff58,lut_ff57,lut_ff56;
   
   reg 			lut_ff_input,fifo_ff_input;
   reg 			lut_rol1,lut_rol2,lut_rol8;
   reg 			s1,s4,s5,s6,s7;
   reg [1:0] 	s3;
   reg [5:0] 	bit_counter;
   wire 		lut_out;
   reg 			valid;
   
   
   // synopsys sync_set_reset "reset"
   // Shift Register1 FIFO 56x1 Begin
   always @(posedge clk)
	 begin
		
		if(!reset)
		  shifter1 <= 56'd0;
		
		else if(shifter_enable1)
		  shifter1 <= {shift_in1, shifter1[55:1]};
	 end
   
   assign shift_out1 = shifter1[0];
   // Shift Register1 End
   
   // Shift Register2 FIFO 64x1 Begin
   // synopsys sync_set_reset "reset"
   always @(posedge clk)
	 begin
		if(!reset)
		  shifter2 <= 64'd0;
		else if(shifter_enable2)
		  shifter2 <= {shift_in2, shifter2[63:1]};
	 end
   
   assign shift_out2 = shifter2[0];
   // Shift Register1 End
   
   always@(posedge clk)
	 begin
		if(!reset)
		  begin
			 fifo_ff63 <= 0;
			 fifo_ff62 <= 0;
			 fifo_ff61 <= 0;
			 fifo_ff60 <= 0;
			 fifo_ff59 <= 0;
			 fifo_ff58 <= 0;
			 fifo_ff57 <= 0;
			 fifo_ff56 <= 0;
		  end
		
		else if(shifter_enable1)
		  begin
			 fifo_ff63 <= fifo_ff_input;
			 fifo_ff62 <= fifo_ff63;
			 fifo_ff61 <= fifo_ff62;
			 fifo_ff60 <= fifo_ff61;
			 fifo_ff59 <= fifo_ff60;
			 fifo_ff58 <= fifo_ff59;
			 fifo_ff57 <= fifo_ff58;
			 fifo_ff56 <= fifo_ff57;
		  end
	 end
   
   always@(posedge clk)
	 begin
		if(!reset)
		  begin
			 lut_ff63 <= 0;
			 lut_ff62 <= 0;
			 lut_ff61 <= 0;
			 lut_ff60 <= 0;
			 lut_ff59 <= 0;
			 lut_ff58 <= 0;
			 lut_ff57 <= 0;
			 lut_ff56 <= 0;
		  end
		
		else
		  begin
			 lut_ff63 <= lut_ff_input;
			 lut_ff62 <= lut_ff63;
			 lut_ff61 <= lut_ff62;
			 lut_ff60 <= lut_ff61;
			 lut_ff59 <= lut_ff60;
			 lut_ff58 <= lut_ff59;
			 lut_ff57 <= lut_ff58;
			 lut_ff56 <= lut_ff57;
		  end
	 end
   
   //FIFO 64x1 Input MUX
   always@(*)
	 begin
		shift_in2 = shift_out1;
	 end
   
   //FIFO 56x1 Input MUX
   always@(*)
	 begin
		if(s1==0)
		  shift_in1 = lut_ff56;
		else
		  shift_in1 = fifo_ff56;
	 end
   
   //FIFO FF Input MUX
   always@(*)
	 begin
		if(s3==0)
		  fifo_ff_input = data_in;
		else if(s3==1)
		  fifo_ff_input = shift_out1;
		else if(s3==2)
		  fifo_ff_input = lut_out;
		else
		  fifo_ff_input = 1'bx;
	 end
   
   //LUT FF Input MUX
   always@(*)
	 begin
		if(s5==0)
		  lut_ff_input = shift_out1;
		else
		  lut_ff_input = lut_out;
	 end
   
   //LUT Input MUX
   always@(*)
	 begin
		if(s7==0)
		  lut_rol1 = fifo_ff63;
		else
		  lut_rol1 = lut_ff63;
		
		if(s4==0)
		  lut_rol2 = fifo_ff62;
		else
		  lut_rol2 = lut_ff62;
		
		if(s6==0)
		  lut_rol8 = fifo_ff56;
		else
		  lut_rol8 = lut_ff56;
	 end
   
   //Selection MUX
   always@(*)
	 begin
		if((round_counter[0]==0 && bit_counter<8)||(round_counter[0]==1 && bit_counter>7)||(data_rdy==1))
		  s1 = 1;
		else 
		  s1 = 0;
		
		if(data_rdy==1)
		  s3 = 0;
		else if(round_counter[0]==0)
		  s3 = 1;
		else if(round_counter[0]==1)
		  s3 = 2;
		else 
		  s3 = 1'bx;
		
		if(round_counter[0]==0)
		  s6 = 0;
		else
		  s6 = 1;
		
		s4 = s6;
		s7 = s6;
		s5 = ~s6;
	 end
   
   //SHIFTER ENABLES
   always@(*)
	 begin
		if(data_rdy==1 || data_rdy==3)
		  shifter_enable2 = 1;
		else
		  shifter_enable2 = 0;
		
		if(data_rdy==1 || data_rdy==3)
		  shifter_enable1 = 1;
		else
		  shifter_enable1 = 0;
		
	 end
   
   // synopsys sync_set_reset "reset"
   always@(posedge clk)
	 begin
		if(!reset)
		  bit_counter <= 0;
		else if(data_rdy==0)
		  bit_counter <= 0;
		else if(data_rdy==3)
		  bit_counter <= bit_counter + 1;
		else 
		  bit_counter <= bit_counter;
	 end
   
   assign lut_out = (lut_rol1 & lut_rol8) ^ shift_out2 ^ lut_rol2 ^ key_in;
   
   assign cipher_out = shift_out2;
   
   always@(*)
	 begin
		if(round_counter==68 || round_counter==69)
		  valid = 1;
		else
		  valid = 0;
	 end

endmodule


//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    16:55:06 11/12/2013 
// Design Name: 
// Module Name:    simon_key_expansion_shiftreg 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module simon_key_expansion_shiftreg(clk,
									reset,
									data_in,
									key_out,
									data_rdy,
									bit_counter,
									round_counter);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule




//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:14:37 11/13/2013 
// Design Name: 
// Module Name:    top_module 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module simon_module(clk,reset,data_in,data_rdy,cipher_out,valid);
   
   input clk,data_in,reset;
   input [1:0] data_rdy;
   output reg  cipher_out;
   output 	   valid;
   
   wire 	   key;
   wire 	   cipher_data;
   wire [5:0]  bit_counter;
   wire [6:0]  round_counter;

   simon_datapath_shiftreg datapath(.clk(clk), 
									.reset(reset),
									.data_in(data_in), 
									.data_rdy(data_rdy), 
									.key_in(key), 
									.cipher_out(cipher_data), 
									.round_counter(round_counter), 
									.bit_counter(bit_counter),
									.valid(valid));
   
   // FIXED KEY IMPLEMENTATION TO KEY VALUE 00000000_00000000_00000000_00000000
   // THIS DESIGN FORCES ALL KEY BITS TO 0 UPON LOADING

   (*keep = "true" *)  wire zero;
   assign zero = 1'b0;
   
   simon_key_expansion_shiftreg key_exp(.clk(clk), 
										.reset(reset), 
										.data_in(zero),   // was: data_in 
										.data_rdy(data_rdy), 
										.key_out(key), 
										.bit_counter(bit_counter), 
										.round_counter(round_counter));

   assign cipher_out = cipher_data;
   

endmodule


/*
 * Copyright (c) 2024 Secure Embedded Systems
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module tt_um_simon_cipher (
						  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
						  );
   
   // UI_IN    7-6  data_rdy   0 = idle   
   //                          1 = load plaintext
   //                          2 = load key
   //                          3 = encrypt
   //          5-1  _unused
   //            0  data_in    serial data input
   //
   // UO_OUT     7  valid      1 = serial data out available
   //          6-1  _unused
   //            0  cipher_out serial data output
   //
   // UIO_OUT  7-0  _unused
   //
   // UIO_OE   7-0  _unused
     
   simon_module bitserial_cipher(.clk(clk),
								 .reset(rst_n),
								 .data_in(ui_in[0]),
								 .data_rdy(ui_in[7:6]),
								 .cipher_out(uo_out[0]),
								 .valid(uo_out[7])
								 );
   
   assign uo_out[6:1] = 6'b0;
   assign uio_out = 7'b0;
   assign uio_oe  = 7'b0;

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

endmodule


Reference solution:
rtl/generated.v: 
   input clk,reset;
   input data_in;
   input [1:0] data_rdy;
   input [5:0] bit_counter;
   output 	   key_out;
   output [6:0] round_counter;
   
   reg [59:0] 	shifter1;
   reg [63:0] 	shifter2;
   reg 			shift_in1,shift_in2;
   wire 		shift_out1,shift_out2;
   reg 			shifter_enable1,shifter_enable2;
   
   reg 			lut_ff_enable,fifo_ff_enable;
   wire 		lut_out;
   reg 			lut_in3;
   reg 			s2;
   reg [1:0] 	s1;
   reg [6:0] 	round_counter;
   reg 			z_value;
   
   reg 			fifo_ff0,fifo_ff1,fifo_ff2,fifo_ff3;
   
   
   reg 			lut_ff0,lut_ff1,lut_ff2,lut_ff3;
   reg 			c;

   //Constant value Z
   wire [0:67] 	Z;
   
   assign Z = 68'b10101111011100000011010010011000101000010001111110010110110011101011;
   
   // Shift Register1 FIFO 60x1 Begin
   // synopsys sync_set_reset "reset"
   always @(posedge clk)
	 begin
		if(!reset)
		  shifter1 <= 60'd0;
		
		else if(shifter_enable1)
		  shifter1 <= {shift_in1, shifter1[59:1]};	
	 end
   
   assign shift_out1 = shifter1[0];
   // Shift Register1 End
   
   // Shift Register2 FIFO 64x1 Begin
   // synopsys sync_set_reset "reset"
   always @(posedge clk)
	 begin
		if(!reset)
		  shifter2<= 63'd0;
		else if(shifter_enable2)
		  shifter2 <= {shift_in2, shifter2[63:1]};
	 end
   
   assign shift_out2 = shifter2[0];
   // Shift Register2 End
   
   // synopsys sync_set_reset "reset"
   always @(posedge clk)
	 begin
		if(!reset)
		  begin
			 fifo_ff3 <= 0;
			 fifo_ff2 <= 0;
			 fifo_ff1 <= 0;
			 fifo_ff0 <= 0;
		  end
		else if(fifo_ff_enable)
		  begin
			 fifo_ff3 <= shift_out1;
			 fifo_ff2 <= fifo_ff3;
			 fifo_ff1 <= fifo_ff2;
			 fifo_ff0 <= fifo_ff1;
		  end
		
	 end
   
   // synopsys sync_set_reset "reset"
   always@(posedge clk)
	 begin
		if(!reset)
		  begin
			 lut_ff3 <= 0;
			 lut_ff2 <= 0;
			 lut_ff1 <= 0;
			 lut_ff0 <= 0;
		  end
		else if(lut_ff_enable)
		  begin
			 lut_ff3 <= lut_out;
			 lut_ff2 <= lut_ff3;
			 lut_ff1 <= lut_ff2;
			 lut_ff0 <= lut_ff1;
		  end
		
	 end
   
   //FIFO 64x1 Input MUX
   always@(*)
	 begin
		if(data_rdy==2)
		  shift_in2 = fifo_ff0;
		else if(data_rdy==3 && (round_counter<1 || bit_counter>3))
		  shift_in2 = fifo_ff0;
		else if(data_rdy==3 && bit_counter<4 && round_counter>0) // NEW ADDED
		  shift_in2 = lut_ff0; // NEW ADDED
		else
		  shift_in2 = 1'bx;
	 end
   
   //LUT >>3 Input MUX
   always@(*)
	 begin
		if(s2==0)
		  lut_in3 = fifo_ff3;
		else
		  lut_in3 = lut_ff3;
	 end
   
   //FIFO 60x1 Input MUX
   always@(*)
	 begin
		if(s1==0)
		  shift_in1 = fifo_ff0;

		else if(s1==1 || data_rdy==2)
		  shift_in1 = data_in;

		else if(s1==2)
		  shift_in1 = lut_out;
		else if(s1==3)
		  shift_in1 = lut_ff0;
		else
		  shift_in1 = 1'b0;
	 end
   
   //S2 MUX
   always@(*)
	 begin
		if(bit_counter==0 && round_counter!=0)
		  s2 = 1;
		else
		  s2 = 0;
	 end
   
   //S1 MUX
   always@(*)
	 begin
		if(data_rdy==2)
		  s1 = 1;
		else if(data_rdy==3 && bit_counter<4 && round_counter==0)
		  s1 = 0;
		else if(data_rdy==3 && bit_counter<4 && round_counter>0)
		  s1 = 3;
		else
		  s1 = 2;
	 end
   
   //LUT FF ENABLE MUX
   always@(*)
	 begin
		if(data_rdy==3 && bit_counter<4)
		  lut_ff_enable = 1;
		else
		  lut_ff_enable = 0;
	 end
   
   //FIFO FF ENABLE MUX
   always@(*)
	 begin
		if(data_rdy==2 || data_rdy==3)
		  fifo_ff_enable = 1;
		else
		  fifo_ff_enable = 0;
	 end
   
   //SHIFTER ENABLES
   always@(*)
	 begin
		if(data_rdy==2 || data_rdy==3)
		  shifter_enable1 = 1;
		else
		  shifter_enable1 = 0;
		
		if(data_rdy==2 || data_rdy==3)
		  shifter_enable2 = 1;
		else
		  shifter_enable2 = 0;
		
	 end
   
   //Round Counter
   // synopsys sync_set_reset "reset"
   always@(posedge clk)
	 begin
		if(!reset)
		  round_counter <= 0;
		else if(data_rdy==3 && bit_counter==63)
		  round_counter <= round_counter + 1;
		else if(data_rdy==0)
		  round_counter <= 0;
		else
		  round_counter <= round_counter;
	 end
 
   
   always @(*)
	 begin
		if(bit_counter==0)
		  z_value = Z[round_counter];
		else
		  z_value = 0;
	 end
    
   always @(*)
	 begin
		if(bit_counter==0 || bit_counter==1)
		  c = 0;
		else 
		  c = 1;
	 end
   
   assign lut_out = shift_out2 ^ lut_in3 ^ shift_out1 ^ z_value ^ c;
   
   assign key_out = shift_out2;