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.

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 03/17/2025 09:32:11 PM
// Design Name: 
// Module Name: LIF_neuron
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

`default_nettype none

module tt_um_LIF_neuron(
input clk,
input rst_n,//HIGH to Reset
//input [15:0] v, //(1,6,9)
//input [15:0] i,
//output [15:0] vout,
//output spike,
//output done
input wire ena,
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)
    );

//localparam [15:0] E_REST = 16'b1100010000000000;  //-30 
//localparam [15:0] E_REST = 16'b1100010111111111;  //-29 
//localparam [15:0] E_TAU = 16'b0000000100110110;   //0.60546875
//localparam [15:0] E_TAU = 16'b0000000110001110;   //0.7788007830714049
//localparam [15:0] V_TH = 16'b0011110000000000;    //30
 
//localparam [15:0] E_REST = 16'd5;  
//localparam [15:0] E_TAU = 16'd5;   
//localparam [15:0] V_TH = 16'd5;    
wire [15:0] vout;
wire [7:0] i;
wire spike;

wire [16:0] v_e;
wire [16:0] e_i;
wire [31:0] vet;
wire [15:0] scl_vet;
wire [15:0] scl_ve;
wire [17:0] v_new;
wire [15:0] vout0;

reg sign_ve;

//reg [16:0] pip1_ei;
reg [16:0] pip2_ei,pip3_ei,pip4_ei,pip5_ei,pip6_ei,pip7_ei,pip8_ei,pip9_ei;
reg [16:0] pip2_ve;
//reg [16:0] pip1_ve;
//reg [16:0] pip9_ei;
reg [16:0] pip9_vet;
reg pip3_sve, pip4_sve,pip5_sve,pip6_sve,pip7_sve,pip8_sve,pip9_sve;

//reg [15:0] voutbuffer;
reg [15:0] buffer0,buffer1,buffer2,buffer3,buffer4,buffer5,buffer6,buffer7;
reg [15:0] vin;
wire [15:0] wi_vin;

// List all unused inputs to prevent warnings
wire _unused = ena;


///////////////Prarmeters & Inial Data Input/////////////////////
reg [15:0] E_REST;
reg [15:0] E_TAU;
reg [15:0] V_TH;
reg [15:0] v_ini;
reg [3:0] parcount;

/////////set up/////////////////
reg [3:0] cycle,ini_count;

reg ini;


////////////////STATE MACHINE//////////////////
reg par;
reg set;
reg inter;
reg [3:0] state;
reg ioctrl;
reg i_c;

assign uio_oe = ioctrl;

always@(posedge clk)begin
	if (rst_n == 0) begin
	state <= 0;
	E_REST <= 0;
	E_TAU <= 0;
	V_TH <= 0;
	parcount <= 0;
	cycle <= 0;
	inter <= 0;
	ini_count <= 0;
	ini <= 0;
	vin <= v_ini;
	i_c <=0;
	end
	
	case(state)
	4'd0: begin   //idle
		par <= 0;
		set <= 0;
		inter <= 0;
		ioctrl <= 0;//inout work as input
		state <= 4'd1;
		end

	4'd1: begin  //read parameters and Inial V input
		par <= 1;
		set <= 0;
		inter <= 0;
		ioctrl <= 0;//inout work as input
		end

	4'd2: begin  //LIF neuron model setup
		par <= 0;
		set <= 1;
		inter <= 0;
		ioctrl <= 0;//inout work as input
		end

	4'd3: begin  //LIF neuron model work
		par <= 0;
		set <= 0;
		inter <= 1;
		ioctrl <= 1;//inout work as output
		end
	endcase
	
	///////////////Prarmeters & Inial Data Input/////////////////////
	
	
	if (par) begin
		parcount <= parcount + 1;
		case(parcount)
		4'd0: E_REST <= {ui_in,uio_in}; //E_REST is setup 
		4'd1: E_TAU <= {ui_in,uio_in}; //E_TAU is setup 
		4'd2: V_TH <= {ui_in,uio_in}; //V_TH is setup
		//4'd3: v_ini = {ui_in,uio_in}; //v_ini is setup 
		endcase
	end

	if(parcount == 4'd2)begin
		state <= 4'd2;
	end
	
	////////////////////set up////////////////////////////////
	if (inter == 0 & ini == 0  & set == 1)begin
	v_ini <= {ui_in,uio_in};
	buffer0 <= v_ini;
	buffer1 <= buffer0;
	buffer2 <= buffer1;
	buffer3 <= buffer2;
	buffer4 <= buffer3;
	buffer5 <= buffer4;
	buffer6 <= buffer5;
	buffer7 <= buffer6;
	//buffer8 <= buffer7;
	cycle <= cycle + 1;
    end

	if(cycle == 8) begin
		cycle <= 0;
		ini <= 1;
		end
	
	if(ini & set == 1)begin
	i_c <= 1;
	vin <= buffer7;
	//buffer8 <= buffer7;
	buffer7 <= buffer6;
	buffer6 <= buffer5;
	buffer5 <= buffer4;
	buffer4 <= buffer3;
	buffer3 <= buffer2;
	buffer2 <= buffer1;
	buffer1 <= buffer0;
	buffer0 <= 0;
	ini_count <= ini_count + 1;
	end
	
	if(ini_count == 7)begin
	ini <= 0;
	//inter <= 1;
	ini_count <= 0;
	state <= 4'd3;
	end
	
	if(inter)begin
	//counter <= 0;
	//clk7 <= 0;
	cycle <= 0;
	ini_count <= 0;
	//buffer0 <= vout;
	//vin <= vout;
	end
	
	
end

assign wi_vin = (inter)? vout: vin;
assign i = (inter || i_c )? ui_in:0; // the I input is 8 bit and always > 0
assign uio_out = {vout[7:1],spike};
assign uo_out = {vout[15:8]};



///////////////pipline stage 0////////////////////
//always@(posedge clk)begin
//    if(rst)begin
    
//    pip1_ei <= 0;
//    pip1_ve <= 0;
    
//    end
//    else begin
    
//    pip1_ei <= e_i;
//    pip1_ve <= v_e;
       
//    end
//end

signed_adder_16bit adder0(.s_a({2'b0,i,6'b0}), .s_b(E_REST), .s_c(e_i)); //i (5,3) -> (1,6,9)
signed_substrator_16bit substrator0(.s_a(wi_vin), .s_b(E_REST), .s_c(v_e));
///////////////pipline stage 1////////////////////
always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip2_ei <= 0;
    sign_ve <= 0;
    
    end
    else begin
    
    pip2_ei <= e_i;
    pip2_ve <= v_e;
    sign_ve <= v_e[16];
   
    end
end

assign scl_ve = (pip2_ve[16] == 0)? pip2_ve[15:0]: (~pip2_ve[15:0] + 1);

folded_mul_16bit mul0(.clk(clk), .a(scl_ve), .b(E_TAU), .out(vet));

assign scl_vet = vet[23:8];//scal the vet to 33-16 {14,18} -> {7,9}

///////////////pipline stage 2////////////////////1


always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip3_ei <= 0;
    pip3_sve <= 0;
    
    end
    else begin
    pip3_ei <= pip2_ei;
    pip3_sve <= sign_ve;
    end
end



///////////////pipline stage 3////////////////////2

always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip4_ei <= 0;
    pip4_sve <= 0;
    
    end
    else begin
    pip4_ei <= pip3_ei;
    pip4_sve <= pip3_sve;
    end
end



///////////////pipline stage 4////////////////////3


always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip5_ei <= 0;
    pip5_sve <= 0;
    
    end
    else begin
    pip5_ei <= pip4_ei;
    pip5_sve <= pip4_sve;
    end
end


///////////////pipline stage 5////////////////////4


always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip6_ei <= 0;
    pip6_sve <= 0;
    
    end
    else begin
    pip6_ei <= pip5_ei;
    pip6_sve <= pip5_sve;
    end
end


///////////////pipline stage 6////////////////////5


always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip7_ei <= 0;
    pip7_sve <= 0;
    
    end
    else begin
    pip7_ei <= pip6_ei;
    pip7_sve <= pip6_sve;
    end
end



///////////////pipline stage 7////////////////////6


always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip8_ei <= 0;
    pip8_sve <= 0;
    
    end
    else begin
    pip8_ei <= pip7_ei;
    pip8_sve <= pip7_sve;
    end
end


///////////////pipline stage 8////////////////////
always@(posedge clk)begin
    if(rst_n == 0)begin
    
    pip9_ei <= 0;
    pip9_vet <= 0;
    pip9_sve <= 0;
    //voutbuffer <= 0;
    end
    else begin
    
    pip9_ei <= pip8_ei;
    pip9_sve <= pip8_sve;
        if (pip9_sve) pip9_vet <= {pip8_sve, (~scl_vet + 1'b1)};
        else pip9_vet <= {pip8_sve,scl_vet};    
    	  //if ((vout0[15]==0)&(vout0 >= 16'b0011110000000000)) voutbuffer <= E_REST;
        //else voutbuffer <= vout0;
    end
end
///////////////pipline stage 7////////////////////
signed_adder_17bit adder1(.s_a(pip9_vet), .s_b(pip9_ei), .s_c(v_new));
assign vout0 = {v_new[16],v_new[14:0]};
assign vout = ((vout0[15]==0)&(vout0 >= V_TH))? E_REST: vout0;
assign spike = ((vout0[15]==0)&(vout0 >= V_TH))? 1'b1: 1'b0;

//////////output buffer///////////////
//always@(posedge clk)begin
//    if(rst)begin
//    voutbuffer <= 0;
//    end
//    else if (inter) begin
//    voutbuffer <= 0;
//    end
//    else begin	
//    voutbuffer <= vout;
//    end
//end

endmodule



`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 05/06/2025 05:37:45 PM
// Design Name: 
// Module Name: adder_10bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder_10bit(
input [9:0] a,
input [9:0] b,
output [10:0] c
    );

wire a0, b0, s0, a1, b1, s1;
wire [3:0] a2, a3;
wire [3:0] b2, b3;
wire [3:0] s2, s3;
wire cin0,cin1,cin2, cin3;
wire ct = 0;

    

assign a3 = a[9:6];
assign a2 = a[5:2];
assign a1 = a[1];
assign a0 = a[0];

assign b3 = b[9:6];
assign b2 = b[5:2];
assign b1 = b[1];
assign b0 = b[0];

half_adder adder0(.a(a0), .b(b0), .s(s0), .cout(cin0)); 
full_adder adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1)); 
adder_4bit adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));

assign c = {cin3,s3,s2,s1,s0};


endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 06/18/2024 11:33:48 AM
// Design Name: 
// Module Name: adder_16bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder_16bit(
input [15:0] a,
input [15:0] b,
output [16:0] c
    );

wire [3:0] a0, a1, a2, a3;
wire [3:0] b0, b1, b2, b3;
wire [3:0] s0, s1, s2, s3;
wire cin0,cin1,cin2,cin3;
wire ct = 0;

    
assign a3 = a[15:12];
assign a2 = a[11:8]; 
assign a1 = a[7:4];
assign a0 = a[3:0];

assign b3 = b[15:12];
assign b2 = b[11:8]; 
assign b1 = b[7:4];
assign b0 = b[3:0];

adder_4bit adder0(.a(a0), .b(b0), .cin(ct), .s(s0), .cout(cin0));
adder_4bit adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));
adder_4bit adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));

assign c = {cin3,s3,s2,s1,s0};


endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 06/18/2024 11:10:30 AM
// Design Name: 
// Module Name: adder_4bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder_4bit(
input [3:0] a,
input [3:0] b,
input cin,
output [3:0]s,
output cout
    );

wire [3:0] g;
wire [3:0] p;
wire [3:0] c;

assign g[0] = a[0] & b[0];
assign p[0] = a[0] | b[0];
assign c[0] = g[0] | (p[0] & cin);
assign s[0] = a[0] ^ b[0] ^ cin;

assign g[1] = a[1] & b[1];
assign p[1] = a[1] | b[1];
assign c[1] = g[1] | (p[1] & c[0]);
assign s[1] = a[1] ^ b[1] ^ c[0];

assign g[2] = a[2] & b[2];
assign p[2] = a[2] | b[2];
assign c[2] = g[2] | (p[2] & c[1]);
assign s[2] = a[2] ^ b[2] ^ c[1];

assign g[3] = a[3] & b[3];
assign p[3] = a[3] | b[3];
assign c[3] = g[3] | (p[3] & c[2]);
assign s[3] = a[3] ^ b[3] ^ c[2];

assign cout = c[3];


endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:10:29 PM
// Design Name: 
// Module Name: adder_8bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder_8bit(
input [7:0] a,
input [7:0] b,
output [8:0] c
    );

wire [3:0] a0, a1;
wire [3:0] b0, b1;
wire [3:0] s0, s1;
wire cin0,cin1;
wire ct = 0;

assign a1 = a[7:4];
assign a0 = a[3:0];

assign b1 = b[7:4];
assign b0 = b[3:0];

adder_4bit adder0(.a(a0), .b(b0), .cin(ct), .s(s0), .cout(cin0));
adder_4bit adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));

assign c = {cin1,s1,s0};

endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:17:26 PM
// Design Name: 
// Module Name: adder_9bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module adder_9bit(
input [8:0] a,
input [8:0] b,
output [9:0] c
    );

wire a0, b0, s0;
wire [3:0] a1, a2;
wire [3:0] b1, b2;
wire [3:0] s1, s2;
wire cin0,cin1,cin2;
wire ct = 0;

    

assign a2 = a[8:5];
assign a1 = a[4:1];
assign a0 = a[0];

assign b2 = b[8:5];  
assign b1 = b[4:1];  
assign b0 = b[0];

half_adder adder0(.a(a0), .b(b0), .s(s0), .cout(cin0));    
adder_4bit adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));
adder_4bit adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));

assign c = {cin2,s2,s1,s0};


endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:15:40 PM
// Design Name: 
// Module Name: app_mul_8bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module app_mul_8bit(
input clk,
input [7:0] a,
input [7:0] b,
output [15:0] out
    );

parameter CONS = 9'b000010101;
parameter HALFCONS = 9'b000001010;

wire [4:0] k;
wire [3:0] k0;
wire [3:0] ka;
wire [3:0] kb;
wire [8:0] offset;
wire [7:0] ah;
wire [7:0] bh;
wire [7:0] ain;
wire [7:0] bin;
wire cin;
wire [9:0] cc;
wire [8:0] sum, sum0;
wire cout;
wire [16:0] out0;
wire [23:0] out1;

reg [8:0] pip_sum; //pipline reg
reg [3:0] pip_ka;
reg [3:0] pip_kb;

wire za,zb;

reg pip_z;
wire z;

    preprocess_8bit preprocess0(a,ain,ka,za);
    preprocess_8bit preprocess1(b,bin,kb,zb);

    assign ah = {ain[6:0],1'b0};
    assign bh = {bin[6:0],1'b0};
    
    adder_8bit adder0(ah, bh, sum);
    
    assign z = za || zb;

always@(posedge clk)begin //pipline cut
    pip_sum <= sum;
    pip_ka <= ka;
    pip_kb <= kb;
    pip_z <= z;
end

    assign offset = (pip_sum[8])? HALFCONS : CONS;
    //assign sum0 = (pip_sum[16])? pip_sum : {1'b1,pip_sum[15:0]};
    assign sum0 = {1'b1,pip_sum[7:0]};
    
    adder_9bit adder1(sum0, offset, cc);//9bit adder
    
    assign cin = (pip_sum[8])? 1'b0: 1'b1;
    //comparator_4bit comparator0(.a(pip_ka), .b(pip_kb), .c(k0));
    adder_4bit adder2(.a(pip_ka), .b(pip_kb), .cin(cin), .s(k0), .cout(cout));
    
    assign k = {cout, k0};
    
    assign out0 = (pip_z)? 17'b0: {cc,7'b0}>>k;
//    assign out0 = {14'b0,cc};
//    assign out1 = out0 << k;
    //assign out = out0[23:8];
    assign out = (out0[16] == 1)? 16'b1111111111111111:out0[15:0];

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:18:10 PM
// Design Name: 
// Module Name: app_mul_9bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module app_mul_9bit(
input clk,
input [8:0] a,
input [8:0] b,
output [17:0] out
    );

parameter CONS = 10'b0000101010;
parameter HALFCONS = 10'b0000010101;

wire [4:0] k;
wire [3:0] k0;
wire [3:0] ka;
wire [3:0] kb;
wire [9:0] offset;
wire [8:0] ah;
wire [8:0] bh;
wire [8:0] ain;
wire [8:0] bin;
wire cin;
wire [10:0] cc;
wire [9:0] sum, sum0;
wire cout;
wire [18:0] out0;
//wire [23:0] out1;

reg [9:0] pip_sum; //pipline reg
reg [3:0] pip_ka;
reg [3:0] pip_kb;

wire za,zb;

reg pip_z;
wire z;

    preprocess_9bit preprocess0(a,ain,ka,za);
    preprocess_9bit preprocess1(b,bin,kb,zb);

    assign ah = {ain[7:0],1'b0};
    assign bh = {bin[7:0],1'b0};
    
    adder_9bit adder0(ah, bh, sum);
    
    assign z = za || zb;

always@(posedge clk)begin //pipline cut
    pip_sum <= sum;
    pip_ka <= ka;
    pip_kb <= kb;
    pip_z <= z;
end

    assign offset = (pip_sum[9])? HALFCONS : CONS;
    //assign sum0 = (pip_sum[16])? pip_sum : {1'b1,pip_sum[15:0]};
    assign sum0 = {1'b1,pip_sum[8:0]};
    
    adder_10bit adder1(sum0, offset, cc);//10bit adder
    
    assign cin = (pip_sum[9])? 1'b0: 1'b1;
    //comparator_4bit comparator0(.a(pip_ka), .b(pip_kb), .c(k0));
    adder_4bit adder2(.a(pip_ka), .b(pip_kb), .cin(cin), .s(k0), .cout(cout));
    
    assign k = {cout, k0};
    
    assign out0 = (pip_z)? 19'b0: {cc,8'b0}>>k;
//    assign out0 = {14'b0,cc};
//    assign out1 = out0 << k;
    //assign out = out0[23:8];
    assign out = (out0[18] == 1)? 18'b111111111111111111:out0[17:0];

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:37:45 PM
// Design Name: 
// Module Name: folded_mul_16bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module folded_mul_16bit(
input clk,
    input [15:0] a,
    input [15:0] b,
    output [31:0] out
    );
wire [15:0] a_new;
wire [15:0] b_new;
wire [8:0] a_star;
wire [8:0] b_star;
wire [3:0] ka;
wire [3:0] kb;
wire [3:0] k0;
wire [4:0] k;
wire [16:0] gamma;
wire [17:0] gamma_18bit;
wire [17:0] y;
wire [15:0] alpha;
wire [15:0] beta;
wire [16:0] sum;
wire [17:0] x;
wire [15:0] x_star;
wire z1,z2;
wire z;

reg [7:0] ah, al;
reg [7:0] bh, bl;
reg [8:0] pip_astar, pip_bstar;
reg [15:0] pip_alpha0, pip_alpha1, pip_alpha2;
reg [15:0] pip_beta0, pip_beta1, pip_beta2, pip_beta3;
reg [17:0] pip_y, pip_gamma;
reg [15:0] pip_x;
reg [16:0] pip_sum;
reg [3:0] pip0_ka;
reg [3:0] pip0_kb;
reg [4:0] pip0_k, pip1_k, pip2_k, pip3_k, pip4_k;
reg pip0_z, pip1_z, pip2_z, pip3_z, pip4_z, pip5_z;

wire none;

    preprocess preprocess0(.data(a), .out(a_new), .kout(ka), .zout(z1)); //第一位为1
    preprocess preprocess1(.data(b), .out(b_new), .kout(kb), .zout(z2));
    
    assign z = z1 || z2;


always@(posedge clk)begin //pipline0
    ah <= a_new[15:8];
    al <= a_new[7:0];
    bh <= b_new[15:8];
    bl <= b_new[7:0];
    pip0_ka <= ka;
    pip0_kb <= kb;
    pip0_z <= z;
    end

        
    adder_8bit adder0(.a(ah), .b(al), .c(a_star));
    adder_8bit adder1(.a(bh), .b(bl), .c(b_star));
    adder_4bit adder4(.a(pip0_ka), .b(pip0_kb),.cin(1'b0),.s(k0), .cout(none));
    assign k = {none,k0};
    app_mul_8bit mul1(.clk(clk), .a(ah), .b(bh), .out(alpha));
    app_mul_8bit mul2(.clk(clk), .a(al), .b(bl), .out(beta));

always@(posedge clk)begin //pipline1
    pip_astar <= a_star;
    pip_bstar <= b_star;
    pip0_k <= k;
    pip1_z <= pip0_z;
    end

    app_mul_9bit mul0(.clk(clk), .a(pip_astar), .b(pip_bstar), .out(y)); //改变乘法器

always@(posedge clk)begin //pipline2
    pip_alpha0 <= alpha;
    pip_beta0 <= beta;
    pip1_k <= pip0_k;
    pip2_z <= pip1_z;
    end

    adder_16bit adder2(.a(pip_alpha0), .b(pip_beta0), .c(gamma));  
    assign gamma_18bit = {1'b0, gamma};

always@(posedge clk)begin //pipline3
    pip_y <= y;
    pip_gamma <= gamma_18bit;  
    pip_alpha1 <= pip_alpha0;
    pip_beta1 <= pip_beta0;
    pip2_k <= pip1_k;
    pip3_z <= pip2_z;
    end
    
    substrator_18bit substrator0(.a(pip_y), .b_o(pip_gamma), .c(x)); 
    assign x_star = {6'b0,x[17:8]};

always@(posedge clk)begin //pipline4
    pip_x <= x_star;  
    pip_alpha2 <= pip_alpha1;
    pip_beta2 <= pip_beta1;  
    pip3_k <= pip2_k;
    pip4_z <= pip3_z;
    end

    adder_16bit adder3(.a(pip_alpha2), .b(pip_x), .c(sum));

always@(posedge clk)begin //pipline5
    pip_sum <= sum;  
    pip_beta3 <= pip_beta2;    
    pip4_k <= pip3_k;
    pip5_z <= pip4_z;
    end

    assign out = (pip5_z)? 32'b0:{pip_sum, pip_beta3} >> pip4_k;
    
endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 06/18/2024 10:53:22 AM
// Design Name: 
// Module Name: full_adder
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module full_adder(
input a,
input b,
input cin,
output s,
output cout
    );

assign s = (a ^ b) ^ cin;
assign cout = (a & b) | (a & cin) | (b & cin);

endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 06/18/2024 10:53:22 AM
// Design Name: 
// Module Name: full_adder
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module half_adder(
input a,
input b,
output s,
output cout
    );

assign s = a ^ b;
assign cout = a & b;

endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 08:55:33 PM
// Design Name: 
// Module Name: preprocess
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module preprocess(
input [15:0] data,
output [15:0] out,
output [3:0] kout,
output zout
    );
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule




`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:16:39 PM
// Design Name: 
// Module Name: preprocess_8bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module preprocess_8bit(
input [7:0] data,
output [7:0] out,
output [3:0] kout,
output z
    );

reg [3:0] k1;
reg [7:0] dataout;
reg z1;

assign kout = k1;
assign out = dataout;
assign z = z1;


always@(*)begin
    if(data[7])begin
        k1 = 4'd0;
        z1 = 0; 
        end
    else if (data[7]^data[6])begin
        k1 = 4'd1;
        z1 = 0; 
        end          
    else if (data[6]^data[5])begin
        k1 = 4'd2;
        z1 = 0; 
        end              
    else if (data[5]^data[4])begin
        k1 = 4'd3;
        z1 = 0; 
        end                
    else if (data[4]^data[3])begin
        k1 = 4'd4;
        z1 = 0; 
        end                
    else if (data[3]^data[2])begin
        k1 = 4'd5;
        z1 = 0; 
        end     
    else if (data[2]^data[1])begin
        k1 = 4'd6;
        z1 = 0; 
        end   
    else if (data[1]^data[0])begin
        k1 = 4'd7;
        z1 = 0; 
        end
    else begin
        k1 = 0;
        z1 = 1;            
        end
    dataout = data << k1;
    
end

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:29:23 PM
// Design Name: 
// Module Name: preprocess_9bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module preprocess_9bit(
input [8:0] data,
output [8:0] out,
output [3:0] kout,
output z
    );

reg [3:0] k1;
reg [8:0] dataout;
reg z1;

assign kout = k1;
assign out = dataout;
assign z = z1;


always@(*)begin

    if(data[8])begin
        k1 = 4'd0;
        z1 = 0; 
        end
    else if (data[8]^data[7])begin
        k1 = 4'd1;
        z1 = 0; 
        end      
    else if (data[7]^data[6])begin
        k1 = 4'd2;
        z1 = 0; 
        end          
    else if (data[6]^data[5])begin
        k1 = 4'd3;
        z1 = 0; 
        end              
    else if (data[5]^data[4])begin
        k1 = 4'd4;
        z1 = 0; 
        end                
    else if (data[4]^data[3])begin
        k1 = 4'd5;
        z1 = 0; 
        end                
    else if (data[3]^data[2])begin
        k1 = 4'd6;
        z1 = 0; 
        end     
    else if (data[2]^data[1])begin
        k1 = 4'd7;
        z1 = 0; 
        end   
    else if (data[1]^data[0])begin
        k1 = 4'd8;
        z1 = 0; 
        end
   else begin
        k1 = 0;
        z1 = 1;            
        end
    dataout = data << k1;
    
end

endmodule

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 03/18/2025 06:55:04 PM
// Design Name: 
// Module Name: signed_adder_16bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module signed_adder_16bit(
    input [15:0] s_a,
    input [15:0] s_b,
    output [16:0] s_c
    );
 
wire [14:0] a, b;    
wire a0, b0, s0, a1, b1, s1, a2, b2, s2;
wire [3:0] a3, a4, a5;
wire [3:0] b3, b4, b5;
wire [3:0] s3, s4, s5;
wire cin0, cin1, cin2, cin3, cin4, cin5;


assign a = s_a[14:0];
assign b = s_b[14:0];

assign a5 = a[14:11];
assign a4 = a[10:7];    
assign a3 = a[6:3];
assign a2 = a[2]; 
assign a1 = a[1];
assign a0 = a[0];

assign b5 = b[14:11];
assign b4 = b[10:7];    
assign b3 = b[6:3];
assign b2 = b[2]; 
assign b1 = b[1];
assign b0 = b[0];

half_adder adder0(.a(a0), .b(b0), .s(s0), .cout(cin0));  
full_adder adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));  
full_adder adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));  
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));
adder_4bit adder4(.a(a4), .b(b4), .cin(cin3), .s(s4), .cout(cin4));
adder_4bit adder5(.a(a5), .b(b5), .cin(cin4), .s(s5), .cout(cin5));

assign s_c = (s_a[15] ^ s_b[15])? {~cin5,~cin5,s5,s4,s3,s2,s1,s0} : {s_a[15],cin5,s5,s4,s3,s2,s1,s0};
//正负两个数的溢出情况只存在正数数值大，负数数值小的情况，因此溢出值直接赋0即可,而符号相同时直接溢出就是正确值

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 03/19/2025 09:40:41 AM
// Design Name: 
// Module Name: signed_adder_17bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module signed_adder_17bit(
    input [16:0] s_a,
    input [16:0] s_b,
    output [17:0] s_c
    );
    
    
wire [31:0] a, b;
wire [3:0] a0, a1, a2, a3;
wire [3:0] b0, b1, b2, b3;
wire [3:0] s0, s1, s2, s3;
wire cin0, cin1, cin2, cin3;
wire ct = 0;

assign a = s_a[15:0];
assign b = s_b[15:0];
 
assign a3 = a[15:12];
assign a2 = a[11:8]; 
assign a1 = a[7:4];
assign a0 = a[3:0];

assign b3 = b[15:12];
assign b2 = b[11:8]; 
assign b1 = b[7:4];
assign b0 = b[3:0];

adder_4bit adder0(.a(a0), .b(b0), .cin(ct), .s(s0), .cout(cin0));
adder_4bit adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));
adder_4bit adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));


assign s_c = (s_a[16] ^ s_b[16])? {~cin3,~cin3,s3,s2,s1,s0} : {s_a[16],cin3,s3,s2,s1,s0};
//正负两个数的溢出情况只存在正数数值大，负数数值小的情况，因此溢出值直接赋0即可,而符号相同时直接溢出就是正确值

endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 03/18/2025 07:04:59 PM
// Design Name: 
// Module Name: signed_substrator_16bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module signed_substrator_16bit(
    input [15:0] s_a,
    input [15:0] s_b,
    output [16:0] s_c
    );
    
wire [14:0] a, b;    
wire a0, b0, s0, a1, b1, s1, a2, b2, s2;
wire [3:0] a3, a4, a5;
wire [3:0] b3, b4, b5;
wire [3:0] s3, s4, s5;
wire cin0, cin1, cin2, cin3, cin4, cin5;
wire ct = 1;


assign a = s_a[14:0];
assign b = ~s_b[14:0];

assign a5 = a[14:11];
assign a4 = a[10:7];    
assign a3 = a[6:3];
assign a2 = a[2]; 
assign a1 = a[1];
assign a0 = a[0];

assign b5 = b[14:11];
assign b4 = b[10:7];    
assign b3 = b[6:3];
assign b2 = b[2]; 
assign b1 = b[1];
assign b0 = b[0];

full_adder adder0(.a(a0), .b(b0), .cin(ct), .s(s0), .cout(cin0));  
full_adder adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));  
full_adder adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));  
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));
adder_4bit adder4(.a(a4), .b(b4), .cin(cin3), .s(s4), .cout(cin4));
adder_4bit adder5(.a(a5), .b(b5), .cin(cin4), .s(s5), .cout(cin5));

assign s_c = (s_a[15] ^ ~s_b[15])? {~cin5,~cin5,s5,s4,s3,s2,s1,s0} : {s_a[15],cin5,s5,s4,s3,s2,s1,s0};
//正负两个数的溢出情况只存在正数数值大，负数数值小的情况，因此溢出值直接赋0即可,而符号相同时直接溢出就是正确值
    
    
    
    
    
    
endmodule


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 04/21/2025 09:12:38 PM
// Design Name: 
// Module Name: substrator_18bit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module substrator_18bit(
input [17:0] a,
input [17:0] b_o,
output [17:0] c
    );
    
wire [17:0] b;
assign b = ~ b_o;

wire a0, b0, s0;
wire a1, b1, s1;
    
wire [3:0] a2, a3, a4, a5;
wire [3:0] b2, b3, b4, b5;
wire [3:0] s2, s3, s4, s5;
wire cin0, cin1, cin2, cin3, cin4, cin5;
wire ct = 1;


assign a5 = a[17:14];
assign a4 = a[13:10];    
assign a3 = a[9:6];
assign a2 = a[5:2]; 
assign a1 = a[1];
assign a0 = a[0];


assign b5 = b[17:14];
assign b4 = b[13:10];    
assign b3 = b[9:6];
assign b2 = b[5:2]; 
assign b1 = b[1];
assign b0 = b[0];

full_adder adder0(.a(a0), .b(b0), .cin(ct), .s(s0), .cout(cin0));
full_adder adder1(.a(a1), .b(b1), .cin(cin0), .s(s1), .cout(cin1));
adder_4bit adder2(.a(a2), .b(b2), .cin(cin1), .s(s2), .cout(cin2));
adder_4bit adder3(.a(a3), .b(b3), .cin(cin2), .s(s3), .cout(cin3));
adder_4bit adder4(.a(a4), .b(b4), .cin(cin3), .s(s4), .cout(cin4));
adder_4bit adder5(.a(a5), .b(b5), .cin(cin4), .s(s5), .cout(cin5));


assign c = {s5,s4,s3,s2,s1,s0};

endmodule

Reference solution:
rtl/generated.v: 
reg [3:0] k1;
reg [15:0] dataout;
reg z;
assign kout = k1;
assign out = dataout;
assign zout = z;


always@(*)begin
    if(data[15])begin
        k1 = 4'd0;
        z = 0;
        end
    else if (data[15]^data[14])begin
        k1 = 4'd1;
        z = 0;
        end          
    else if (data[14]^data[13])begin
        k1 = 4'd2;
        z = 0;
        end              
    else if (data[13]^data[12])begin
        k1 = 4'd3;
        z = 0;
        end                
    else if (data[12]^data[11])begin
        k1 = 4'd4;
        z = 0;
        end                
    else if (data[11]^data[10])begin
        k1 = 4'd5;
        z = 0;
        end     
    else if (data[10]^data[9])begin
        k1 = 4'd6;
        z = 0;
        end   
    else if (data[9]^data[8])begin
        k1 = 4'd7;
        z = 0;
        end            
    else if (data[8]^data[7])begin 
        k1 = 4'd8;
        z = 0;
        end          
    else if (data[7]^data[6])begin
        k1 = 4'd9;
        z = 0;
        end             
    else if (data[6]^data[5])begin 
        k1 = 4'd10;
        z = 0;
        end            
    else if (data[5]^data[4])begin
        k1 = 4'd11;
        z = 0;
        end            
    else if (data[4]^data[3])begin
        k1 = 4'd12;
        z = 0;
        end             
    else if (data[3]^data[2])begin
        k1 = 4'd13;
        z = 0;
        end              
    else if (data[2]^data[1])begin
        k1 = 4'd14;
        z = 0;
        end              
    else if (data[1]^data[0])begin
        k1 = 4'd15;
        z = 0;
        end
    else begin
        k1 = 4'd0;
        z = 1;
    end


    dataout = data << k1;
    
end