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

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

  // All output pins must be assigned. If not used, assign to 0.
  assign uo_out[7:4]  = 4'b0;  // Example: ou_out is the sum of ui_in and uio_in
  assign uio_out = 0;
  assign uio_oe  = 0;

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

  // ring_osc part
  top_TRNG TRNG_inst(
    .clk_sys(clk),
    .i_en(ena),
    .RX_Serial(ui_in[0]),
    .TX_Serial(uo_out[0]),
    .o_RO(uo_out[1]),
    .o_RG(uo_out[2]),
    .led(uo_out[3]));

endmodule


// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:44:20 PM
// Design Name: 
// Module Name: DCM_clk
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module DCM_clk(
	input  clk_in,
	output clk_50
    );
	
	// reg [1:0] cnt = 2'd0;
	reg clk_buf = 1'b0;
	
	// --------------------------------------------- process_DCM
	always @(posedge clk_in)
	begin
        clk_buf <= ~ clk_buf;
	end
	
	assign clk_50 = clk_buf;
endmodule


// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:45:00 PM
// Design Name: 
// Module Name: UART_controller
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module Main_controller(
	input i_Clk,
	output reg led,
	
	// connect to UART_interface
	input RX_DV,
	input [7:0] RX_Byte,	// data comme from UART_RX (received data from PC)	
		
	output reg TX_DV,	
	output reg [7:0] TX_Byte,	// data sent to UART_TX	(for sending to PC)
	input TX_Active,
	input TX_Done,
	
	// connect to TRNG
	input [31:0] data,
	output reg reset);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule





// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:38:31 PM
// Design Name: 
// Module Name: RG_based_TRNG
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

(* dont_touch = "yes"*)
module RG_based_TRNG#
	(
		parameter NO_INVs = 11      // Degree polynominal		
	)(
		
		input i_clk,
		input i_rst, 
		input i_en,
		output o_RO,
		output o_RG,
		output [31:0] o_data
	);
	
	(* dont_touch = "yes"*) wire [NO_INVs-1:0]w;
	(* dont_touch = "yes"*) wire o_RNG;
	
	// ring_osc part
	ring_osc #(NO_INVs) RO_part(
		.i_en(i_en),
		.o_w(w));
	
	// ring_generator part
	ring_generator RG_part(
		.i_clk(i_clk), 
		.i_rst(i_rst), 
		.i_w(w), 
		.o_pulse(o_RNG),
		.o_data(o_data));	
	
	/* output */
	assign o_RO = w[0];
	assign o_RG = o_RNG;
endmodule


// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:37:14 PM
// Design Name: 
// Module Name: ring_generator
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// x32 + x27 + x21 + x16 + x10 + x5 + 1
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

(* keep_hierarchy *)
module ring_generator(
		input i_clk,
		input i_rst,
		input [10:0] i_w,
		output o_pulse,
		output [31:0] o_data
	);
	
	(*ALLOW_COMBINATORIAL_LOOPS = "true"*)(* dont_touch = "yes"*) wire [31:0] i_r;
	(*ALLOW_COMBINATORIAL_LOOPS = "true"*)(* dont_touch = "yes"*) wire [31:0] o_r;
	
   genvar i;
	generate
		for(i = 0; i < 32; i = i+1) begin
			D_FF FF(.i_clk(i_clk), .i_rst(i_rst), .i_D(i_r[i]), .o_Q(o_r[i]));
		end
	endgenerate
   
   // top part of RG
	assign i_r[0]	= o_r[1] ^ i_w[0];
	assign i_r[1]	= o_r[2];
	assign i_r[2]	= o_r[3] ^ i_w[1];
	assign i_r[3]	= o_r[4];
	assign i_r[4]	= o_r[5] ^ i_w[2];
	assign i_r[5]	= o_r[6];
	assign i_r[6]	= o_r[7] ^ i_w[3];
	assign i_r[7]	= o_r[8];
	assign i_r[8]	= o_r[9] ^ i_w[4];
	assign i_r[9]	= o_r[10];
	assign i_r[10]	= o_r[11] ^ i_w[5];
	assign i_r[11] = o_r[12];
	assign i_r[12] = o_r[13] ^ i_w[6];
	assign i_r[13] = o_r[14];
	assign i_r[14] = o_r[15] ^ i_w[7];
	assign i_r[15] = o_r[16];
	
	// bottom part of RG
	assign i_r[16] = o_r[17];
	assign i_r[17] = o_r[18] ^ o_r[13];
	assign i_r[18] = o_r[19];
	assign i_r[19] = o_r[20];
	assign i_r[20] = o_r[21] ^ o_r[11];
	assign i_r[21] = o_r[22];
	assign i_r[22] = o_r[23];
	assign i_r[23] = o_r[24] ^ o_r[8];
	assign i_r[24] = o_r[25];
	assign i_r[25] = o_r[26] ^ o_r[5];
	assign i_r[26] = o_r[27];
	assign i_r[27] = o_r[28];
	assign i_r[28] = o_r[29] ^ o_r[2];
	assign i_r[29] = o_r[30];
	assign i_r[30] = o_r[31];
	assign i_r[31] = o_r[0];	
	
	assign o_pulse = o_r[0];
	assign o_data = o_r;
	
endmodule

(* keep_hierarchy *)
module D_FF(
	input i_clk,
	input i_rst,
	input i_D,
	output reg o_Q
	);
	
	always @(posedge i_clk or posedge i_rst)
	begin
		if (i_rst)
			o_Q <= 1'b0;
		else
			o_Q <= i_D;
	end
   
endmodule


// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:35:59 PM
// Design Name: 
// Module Name: ring_osc
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////
(* keep_hierarchy *)
module ring_osc#
	(
		parameter NO_INVs = 5      // No of inverter stage
	)(
		input i_en,
		output [NO_INVs-1:0] o_w
	);

	(*ALLOW_COMBINATORIAL_LOOPS = "true"*)(* dont_touch = "yes"*) wire [NO_INVs-1:0]w;

	/* nand */
	primitive_nand nand1(w[NO_INVs-1], i_en, w[0]);
	
	/* number of inverters */
	genvar i;
	generate
		for(i = 0; i < NO_INVs-1; i = i+1) begin
			primitive_not not1(w[i], w[i+1]);
		end
	endgenerate
		
	/* output */
	assign o_w = w;
	
endmodule



//////////////////////////////////////////////////////////////////////////////////
(* keep_hierarchy *)
module primitive_not(
	input i_a,
	output o_b
	);
		
	// LUT6 #(
   //    .INIT(64'h0000000000000001)  // Specify LUT Contents
   // ) LUT6_inst (
   //    .O(o_b),   // LUT general output
   //    .I0(i_a), // LUT input
   //    .I1(0), // LUT input
   //    .I2(0), // LUT input
   //    .I3(0), // LUT input
   //    .I4(0), // LUT input
   //    .I5(0)  // LUT input
   // );

   // (* keep *) sky130_fd_sc_hd__inv_2   sky_inverter (
   //      .A  (i_a),
   //      .Y  (o_b)
   //  );

   assign o_b = ~i_a;

endmodule


//////////////////////////////////////////////////////////////////////////////////
(* keep_hierarchy *)
module primitive_nand(
	input i_a,
	input i_b,
	output o_c
	);
		
	// LUT6 #(
   //    .INIT(64'h0000000000000007)  // Specify LUT Contents
   // ) LUT6_inst (
   //    .O(o_c),   // LUT general output
   //    .I0(i_a), // LUT input
   //    .I1(i_b), // LUT input
   //    .I2(0), // LUT input
   //    .I3(0), // LUT input
   //    .I4(0), // LUT input
   //    .I5(0)  // LUT input
   // );

   // (* keep *) sky130_fd_sc_hd__nand2_2   sky_nand (
   //      .Y  (o_c),
   //      .A  (i_a),
   //      .B  (i_b)
   //  );

   assign o_c = !(i_a&i_b);

endmodule



// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:50:26 PM
// Design Name: 
// Module Name: top_TRNG
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=10020151
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top_TRNG#
	(
		parameter g_CLKS_PER_BIT = 435,
		parameter NO_INVs = 11
	)(
		input  clk_sys,
		input  i_en,
		input  RX_Serial,		// serial Data from PC
		output TX_Serial,		// serial Data to PC
		output o_RO,
		output o_RG,
		output led
	);
	
	// wire clk_50;
	
	// for TRNG
	wire reset;
	wire [31:0] data;
	
	// connect to UART_controller
	wire RX_DV;
	wire [7:0] RX_Byte;
		
	wire TX_DV;	
	wire [7:0] TX_Byte;
	wire TX_Active;
	wire TX_Done; 
	
	// DCM_clk U0_fixed(
	// 			.clk_in(clk_sys),
	// 			.clk_50(clk_50));
	
	RG_based_TRNG #(NO_INVs) U1_TRNG(
				.i_clk(clk_sys),
				.i_rst(reset),
				.i_en(i_en),
				.o_RO(o_RO),
				.o_RG(o_RG),
				.o_data(data));
	
	UART_interface #(g_CLKS_PER_BIT) U2_UART_interface(
				.i_clk(clk_sys),
				.i_RX_Serial(RX_Serial),
				.o_RX_DV(RX_DV),
				.o_RX_Byte(RX_Byte),
				
				.o_TX_Serial(TX_Serial),
				.i_TX_DV(TX_DV),
				.o_TX_Active(TX_Active),
				.o_TX_Done(TX_Done),
				.i_TX_Byte(TX_Byte));
				
	Main_controller U3_Main_controller(
				.i_Clk(clk_sys),
				.led(led),
				.reset(reset),
				.data(data),
				.RX_DV(RX_DV),
				.RX_Byte(RX_Byte),
				.TX_DV(TX_DV),
				.TX_Active(TX_Active),
				.TX_Done(TX_Done),
				.TX_Byte(TX_Byte));			
endmodule


// `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/27/2024 01:46:56 PM
// Design Name: 
// Module Name: UART_interface
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 	This file contains the UART Transmitter and UART Receiver
//		When transmit is complete o_TX_Done will be
//		driven high for one clock cycle.
//
// 		When receive is complete, o_rx_dv will be
//		driven high for one clock cycle.
//
//		Set Generic g_CLKS_PER_BIT as follows:
//		g_CLKS_PER_BIT = (Frequency of i_Clk)/(Frequency of UART)
//		Example: 50 MHz Clock, 115200 baud UART
//		(50000000)/(115200) = 435

// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module UART_interface#
	(
		parameter g_CLKS_PER_BIT = 435
	)(
		input i_clk,
		
		input i_RX_Serial,			// serial Data from PC
		output o_RX_DV,				// successful receiver
		output [7:0] o_RX_Byte,		// data comme from UART_RX (received data from PC)
		
		input i_TX_DV,				// enable sending		
		input [7:0] i_TX_Byte,		// data sent to UART_TX	(for sending to PC)	
		output o_TX_Active,			// successful transmitter
		output o_TX_Serial,			// serial Data to PC
		output o_TX_Done			// successful transmitter
	);
	
	UART_RX #(g_CLKS_PER_BIT) RX_part (
				.i_clk(i_clk),
				.i_RX_Serial(i_RX_Serial),
				.o_RX_DV(o_RX_DV),
				.o_RX_Byte(o_RX_Byte));
	
	UART_TX #(g_CLKS_PER_BIT) TX_part (
				.i_clk(i_clk),
				.i_TX_DV(i_TX_DV),
				.i_TX_Byte(i_TX_Byte),
				.o_TX_Active(o_TX_Active),
				.o_TX_Serial(o_TX_Serial),
				.o_TX_Done(o_TX_Done));
				
endmodule


//////////////////////////////////////////////////////////////////////////////////
module UART_RX#
	(
		parameter g_CLKS_PER_BIT = 435
	)(
		input i_clk,
		input i_RX_Serial,
		output o_RX_DV,
		output [7:0] o_RX_Byte
	);
	
	localparam [2:0]s_Idle	 		= 3'd0,
					s_RX_Start_Bit	= 3'd1,
					s_RX_Data_Bits	= 3'd2,
					s_RX_Stop_Bit	= 3'd3,
					s_Cleanup		= 3'd4;
	
	reg [2:0] r_SM_Main = 3'd0;
	
	reg r_RX_Data_R = 1'b1;
	reg r_RX_Data = 1'b1;
	
	reg [9:0] r_Clk_Count = 10'd0;
	reg [2:0] r_Bit_Index = 3'd0;	// 8 Bits Total
	reg [7:0] r_RX_Byte = 8'd0;
	reg r_RX_DV = 1'b0;
	
	// Purpose: Double-register the incoming data.
	// This allows it to be used in the UART RX Clock Domain.
	// (It removes problems caused by metastabiliy)
	
	// --------------------------------------------- p_SAMPLE
	always @(posedge i_clk)
	begin
		r_RX_Data_R <= i_RX_Serial;
		r_RX_Data   <= r_RX_Data_R;
	end
	
	// -------------------------------------------- process_state_Machine
	always @(posedge i_clk)
	begin
		case(r_SM_Main)
		//----------------------- s_Idle
		s_Idle:	
			begin
				r_RX_DV     <= 0;
				r_Clk_Count <= 0;
				r_Bit_Index <= 0;
				
				if (r_RX_Data == 0)	// Start bit detected
					r_SM_Main <= s_RX_Start_Bit;
				else
					r_SM_Main <= s_Idle;
			end
			
		//----------------------- s_RX_Start_Bit
		// Check middle of start bit to make sure it's still low
		s_RX_Start_Bit:	
			begin
				if (r_Clk_Count == (g_CLKS_PER_BIT-1)/2) begin
					if (r_RX_Data == 0) begin
						r_Clk_Count <= 0;  // reset counter since we found the middle
						r_SM_Main   <= s_RX_Data_Bits;
					end else
						r_SM_Main   <= s_Idle;
				
				end else begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_RX_Start_Bit;
				end
			end
			
		//----------------------- s_RX_Data_Bits
		// Wait g_CLKS_PER_BIT-1 clock cycles to sample serial data
		s_RX_Data_Bits:	
			begin
				if (r_Clk_Count < g_CLKS_PER_BIT-1) begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_RX_Data_Bits;
				end else begin
					r_Clk_Count <= 0;
					r_RX_Byte[r_Bit_Index] <= r_RX_Data;
				
					// Check if we have sent out all bits
					if (r_Bit_Index < 7) begin
						r_Bit_Index <= r_Bit_Index + 1;
						r_SM_Main   <= s_RX_Data_Bits;
					end else begin
						r_Bit_Index <= 0;
						r_SM_Main   <= s_RX_Stop_Bit;
					end
				end
			end
			
		//----------------------- s_RX_Stop_Bit
		// Receive Stop bit.  Stop bit = 1
		s_RX_Stop_Bit:	
			begin				
				// Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
				if (r_Clk_Count < g_CLKS_PER_BIT-1) begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_RX_Stop_Bit;
				end else begin
					r_RX_DV     <= 1;
					r_Clk_Count <= 0;
					r_SM_Main   <= s_Cleanup;
				end
			end
			
		//----------------------- s_Cleanup
		// Stay here 1 clock
		s_Cleanup:	
			begin
				r_RX_DV   <= 0;
				r_SM_Main <= s_Idle;
			end
			
		default:
			begin
				r_SM_Main <= s_Idle;
			end
		endcase
	end
	
	assign o_RX_DV   = r_RX_DV;
	assign o_RX_Byte = r_RX_Byte;
	
endmodule

//////////////////////////////////////////////////////////////////////////////////
module UART_TX#
	(
		parameter g_CLKS_PER_BIT = 435
	)(
		input i_clk,
		input i_TX_DV,
		input [7:0] i_TX_Byte,
		output reg o_TX_Active,
		output reg o_TX_Serial,
		output o_TX_Done
	);
	
	localparam [2:0]s_Idle	 		= 3'd0,
					s_TX_Start_Bit	= 3'd1,
					s_TX_Data_Bits	= 3'd2,
					s_TX_Stop_Bit	= 3'd3,
					s_Cleanup		= 3'd4;
	
	reg [2:0] r_SM_Main = 3'd0;
	
	reg [9:0] r_Clk_Count = 10'd0;
	reg [2:0] r_Bit_Index = 3'd0;
	reg [7:0] r_TX_Data = 8'd0;
	reg r_TX_Done = 1'b0;
	
	// process_state_Machine
	always @(posedge i_clk)
	begin
		case(r_SM_Main)
		//----------------------- s_Idle
		s_Idle:	
			begin
				o_TX_Active <= 0;
				o_TX_Serial <= 1;  // Drive Line High for Idle
				r_TX_Done   <= 0;
				r_Clk_Count <= 0;
				r_Bit_Index <= 0;
				
				if (i_TX_DV == 1) begin
					r_TX_Data <= i_TX_Byte;
					r_SM_Main <= s_TX_Start_Bit;
				end else
					r_SM_Main <= s_Idle;
			end
			
		//----------------------- s_TX_Start_Bit
		// Send out Start Bit. Start bit = 0
		s_TX_Start_Bit:	
			begin
				o_TX_Active <= 1;
				o_TX_Serial <= 0;
				
				// Wait g_CLKS_PER_BIT-1 clock cycles for start bit to finish
				if (r_Clk_Count < g_CLKS_PER_BIT-1) begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_TX_Start_Bit;
				end else begin
					r_Clk_Count <= 0;
					r_SM_Main   <= s_TX_Data_Bits;
				end
			end
			
		//----------------------- s_TX_Data_Bits
		// Wait g_CLKS_PER_BIT-1 clock cycles for data bits to finish 
		s_TX_Data_Bits:	
			begin
				o_TX_Serial <= r_TX_Data[r_Bit_Index];
				if (r_Clk_Count < g_CLKS_PER_BIT-1) begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_TX_Data_Bits;
				end else begin
					r_Clk_Count <= 0;
					
					// Check if we have sent out all bits
					if (r_Bit_Index < 7) begin
						r_Bit_Index <= r_Bit_Index + 1;
						r_SM_Main   <= s_TX_Data_Bits;
					end else begin
						r_Bit_Index <= 0;
						r_SM_Main   <= s_TX_Stop_Bit;
					end
				end
			end
			
		//----------------------- s_TX_Stop_Bit
		// Send out Stop bit.  Stop bit = 1 and time to IDLE
		s_TX_Stop_Bit:	
			begin
				o_TX_Serial <= 1;
				
				// Wait 2*g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
				if (r_Clk_Count < 2*g_CLKS_PER_BIT-1) begin
					r_Clk_Count <= r_Clk_Count + 1;
					r_SM_Main   <= s_TX_Stop_Bit;
				end else begin
					r_TX_Done   <= 1;
					r_Clk_Count <= 0;
					r_SM_Main   <= s_Cleanup;
				end
			end
			
		//----------------------- s_Cleanup
		// Stay here 1 clock
		s_Cleanup:	
			begin
				o_TX_Active <= 0;
				r_TX_Done   <= 1;
				r_SM_Main   <= s_Idle;
			end
			
		default:
			begin
				r_SM_Main <= s_Idle;
			end
		endcase
	end
	
	assign o_TX_Done = r_TX_Done;
	
endmodule

Reference solution:
rtl/generated.v: 	
	localparam [2:0]s_Idle	 		= 3'd0,
					s_Read_command	= 3'd1,
					s_Init_TRNG		= 3'd2,
					s_Wait_TRNG		= 3'd3,
					s_TX_start		= 3'd4,
					s_TX_data		= 3'd5,
					s_cleanup		= 3'd6;
					
	localparam 	[7:0] cmd_Init = 8'h31;	
	
	reg [2:0] state = 3'd0;
	
	reg [31:0] tmp_reg = 32'd0;
		
	reg [2:0] cnt_bytes = 3'd0;
	reg [10:0] cnt_delay = 11'd0;

	
	// -------------------------------------------- process_state_Machine
	always @(posedge i_Clk)
	begin
		case(state)
		//----------------------- s_Idle
		s_Idle:	
			begin
				TX_DV <= 0;
				reset <= 0;
				led  <= 0;	
				if (RX_DV == 1) 
					state <= s_Read_command;
				else
					state <= s_Idle;
			end
			
		//----------------------- s_Read_command
		s_Read_command:	
			begin
				tmp_reg <= 3'd0;
				reset   <= 0;
				led  <= 1;	
				if (RX_DV == 1) begin
					if (RX_Byte == cmd_Init) begin
						state	<= s_Init_TRNG;
					end else
						state <= state;	
				end else
					state <= state;
			end
			
		//----------------------- s_Init_TRNG
		s_Init_TRNG:	
			begin
				reset <= 1;
				state <= s_Wait_TRNG;
			end
			
		//----------------------- s_Wait_TRNG
		// TRNG_Done, save desired data to tmp_reg
		s_Wait_TRNG:	
			begin				
				reset  <= 0;
				if (cnt_delay < 2047) begin
					cnt_delay <= cnt_delay + 1;
				end else begin		
					cnt_delay <= 0;
					tmp_reg <= data;
					state <= s_TX_start;																					
				end

										
			end
			
		//----------------------- s_TX_start
		// Transmit TRNG
		s_TX_start:	
			begin
				TX_DV   <= 1;			// indicates transmit byte
				state   <= s_TX_data;
				TX_Byte <= tmp_reg[7:0];
			end
		
		//----------------------- s_TX_data
		s_TX_data:	
			begin
				if (cnt_bytes < 4) begin
					if ( (TX_Active == 0) && (TX_Done == 1) ) begin
						TX_DV <= 1;
						cnt_bytes <= cnt_bytes + 1;
					end else begin
						TX_DV <= 0;
					end
					
					case(cnt_bytes)
						3'd1: TX_Byte <= tmp_reg[ 15:  8];
						3'd2: TX_Byte <= tmp_reg[ 23: 16];
						3'd3: TX_Byte <= tmp_reg[ 31: 24];
					endcase	
					
				end else begin
					state <= s_cleanup;
					TX_DV <= 0;
					cnt_bytes <= 0;
				end
			end
		
		//----------------------- s_cleanup
		s_cleanup:	
			begin
				state <= s_Read_command;
				reset <= 0;
				TX_DV <= 0;
			end
			
		default:
			begin
				state <= s_Idle;
			end
		endcase
	end