This my verilog code for a multiplier which has two 33 bits input in which msb is for sign bit and else 32 bits are data bits. there are two outputs on of 64 bits which gives out absolute unsigned value and other 1 bit output which gives the sign of the output value. Write a proper UVM testbench code for functional verification and test for critical values and random values where the design may fail.

`timescale 1ns / 1ps
module multiplier(clk,rstn,x,y,mul_out,sign);
input [32:0] x,y;//Multiplicand: x; Multiplier: y
input clk,rstn; //Active low reset 
output [63:0] mul_out;
output sign;
// Pipeline Registers 
reg [32:0]L12[1:0]; //Input --> Partial Products 
reg [33:0]L23[16:0]; //Partial Products --> Shifting Operation
reg [65:0]L34[16:0]; //Shifting Operation--> Adding Unit
integer i;
wire [33:0]pp[16:0]; // Wire to connect partial products 
wire [65:0]spp[16:0]; // Wire to connect shifted partial products 
// Stage 1
always @(posedge clk)begin 
    if(rstn) begin 
        L12[0]<=x;
        L12[1]<=y;
    end  
end 
//Stage 2
always @(posedge clk)begin 
    if(rstn)begin
        for(i=0;i<17;i=i+1) begin
            L23[i]<=pp[i];
        end         
    end 
end 
//Stage 3
always @(posedge clk)begin 
    if(rstn)begin 
        for(i=0;i<17;i=i+1) begin
            L34[i]<=spp[i];
        end
    end 
end 
//Stage 1: Partial Products 
Partial_Products pp_inst(rstn,
                    L12[0], //x
                    L12[1], //y
                    pp[0], //Partial Products 
                    pp[1],
                    pp[2],
                    pp[3],
                    pp[4],
                    pp[5],
                    pp[6],
                    pp[7],
                    pp[8],
                    pp[9],
                    pp[10],
                    pp[11],
                    pp[12],
                    pp[13],
                    pp[14],
                    pp[15],
                    pp[16]);
                    
//Stage 2: Shifting Operation   
Shifting_Operation so(rstn,
                    L23[0], //Partial Products 
                    L23[1],
                    L23[2],
                    L23[3],
                    L23[4],
                    L23[5],
                    L23[6],
                    L23[7],
                    L23[8],
                    L23[9],
                    L23[10],
                    L23[11],
                    L23[12],
                    L23[13],
                    L23[14],
                    L23[15],
                    L23[16],
                    spp[0], //Shifted Partial Products 
                    spp[1],
                    spp[2],
                    spp[3],
                    spp[4],
                    spp[5],
                    spp[6],
                    spp[7],
                    spp[8],
                    spp[9],
                    spp[10],
                    spp[11],
                    spp[12],
                    spp[13],
                    spp[14],
                    spp[15],
                    spp[16]);
                    
//Stage 3: Adding Unit 
    
     Adding_Unit au(rstn,
                    L34[0], //Shifted Partial Products 
                    L34[1],
                    L34[2],
                    L34[3],
                    L34[4],
                    L34[5],
                    L34[6],
                    L34[7],
                    L34[8],
                    L34[9],
                    L34[10],
                    L34[11],
                    L34[12],
                    L34[13],
                    L34[14],
                    L34[15],
                    L34[16],
                    mul_out,
                    sign);
endmodule

`timescale 1ns / 1ps

module Partial_Products(rstn,x,y,pp0,pp1,pp2,pp3,pp4,pp5,pp6,pp7,pp8,pp9,pp10,pp11,pp12,pp13,pp14,pp15,pp16);
input rstn;
input [32:0]x,y;
output [33:0]pp0,pp1,pp2,pp3,pp4,pp5,pp6,pp7,pp8,pp9,pp10,pp11,pp12,pp13,pp14,pp15,pp16;
wire [33:0]inv_x; //For 2's complement of x
reg [2:0] ck [16:0]; //bit select]
integer i;
reg[33:0]pp_ps[16:0]; //Internal connections
reg[33:0]pp_ns[16:0]; //Internal connections  
assign inv_x={~x[32],~x}+1;
//Present state register 
always @(*)begin 
    if (rstn==0) begin //Active low reset 
        for(i=0;i<17;i=i+1)begin //n/2 partial products in radix-4
         pp_ps[i]=0;
        end
    end
    else begin 
        for(i=0;i<17;i=i+1)begin //n/2 partial products in radix-4
          pp_ps[i]=pp_ns[i];
        end
    end 
end 
//Next state logic 
always @(x,y,inv_x) begin 
    ck[0]={y[1],y[0],1'b0}; //ck for k=0 (special case)
    ck[16]={y[32],y[32],y[31]}; //ck for k=16 (special case)
    for(i=1;i<16;i=i+1)begin // n/2 partial products in radix-4
        ck[i]={y[(2*i)+1],y[2*i],y[(2*i)-1]};
    end
    for(i=0;i<17;i=i+1) begin 
    case(ck[i])
        3'b000: pp_ns[i]<=0;
        3'b111: pp_ns[i]<=0;
        3'b001: pp_ns[i]<={x[32],x}; //M
        3'b010: pp_ns[i]<={x[32],x}; //M
        3'b011: pp_ns[i]<={x,1'b0}; //2M
        3'b100: pp_ns[i]<={inv_x[32:0],1'b0}; //-2M
        3'b101: pp_ns[i]<=inv_x; //-M
        3'b110: pp_ns[i]<=inv_x; //-M
        default: pp_ns[i]<=0; 
    endcase
    end
end  
//Assigning Output 
assign pp0=pp_ps[0];
assign pp1=pp_ps[1];
assign pp2=pp_ps[2];
assign pp3=pp_ps[3];
assign pp4=pp_ps[4];
assign pp5=pp_ps[5];
assign pp6=pp_ps[6];
assign pp7=pp_ps[7];
assign pp8=pp_ps[8];
assign pp9=pp_ps[9];
assign pp10=pp_ps[10];
assign pp11=pp_ps[11];
assign pp12=pp_ps[12];
assign pp13=pp_ps[13];
assign pp14=pp_ps[14];
assign pp15=pp_ps[15];
assign pp16=pp_ps[16];
endmodule

`timescale 1ns / 1ps

module Shifting_Operation(rstn,pp0,pp1,pp2,pp3,pp4,pp5,pp6,pp7,pp8,pp9,pp10,pp11,pp12,pp13,pp14,pp15,pp16,spp0,spp1,spp2,spp3,spp4,spp5,spp6,spp7,spp8,spp9,spp10,spp11,spp12,spp13,spp14,spp15,spp16);
input rstn;
input [33:0]pp0,pp1,pp2,pp3,pp4,pp5,pp6,pp7,pp8,pp9,pp10,pp11,pp12,pp13,pp14,pp15,pp16;
output [65:0]spp0,spp1,spp2,spp3,spp4,spp5,spp6,spp7,spp8,spp9,spp10,spp11,spp12,spp13,spp14,spp15,spp16;
reg [65:0]spp[16:0]; //Internal Connection 
integer i,j;
always @(*)begin 
    if (rstn==0) begin //Active low reset 
        for(i=0;i<17;i=i+1)begin //n/2 partial products in radix-4
            spp[i]=0;
        end
    end
    else begin 
        spp[0]<=$signed(pp0);
        spp[1]<=$signed(pp1);
        spp[2]<=$signed(pp2);
        spp[3]<=$signed(pp3);
        spp[4]<=$signed(pp4);
        spp[5]<=$signed(pp5);
        spp[6]<=$signed(pp6);
        spp[7]<=$signed(pp7);
        spp[8]<=$signed(pp8);
        spp[9]<=$signed(pp9);
        spp[10]<=$signed(pp10);
        spp[11]<=$signed(pp11);
        spp[12]<=$signed(pp12);
        spp[13]<=$signed(pp13);
        spp[14]<=$signed(pp14);
        spp[15]<=$signed(pp15);
        spp[16]<=$signed(pp16);

  for(i=0;i<17;i=i+1)begin
    for(j=0;j<i;j=j+1) begin 
            spp[i]={spp[i],2'b00}; //Shifting Operation 
     end
  end
    end 
    end 
    assign spp0=spp[0];
    assign spp1=spp[1];
    assign spp2=spp[2];
    assign spp3=spp[3];
    assign spp4=spp[4];
    assign spp5=spp[5];
    assign spp6=spp[6];
    assign spp7=spp[7];
    assign spp8=spp[8];
    assign spp9=spp[9];
    assign spp10=spp[10];
    assign spp11=spp[11];
    assign spp12=spp[12];
    assign spp13=spp[13];
    assign spp14=spp[14];
    assign spp15=spp[15];
    assign spp16=spp[16];

endmodule

`timescale 1ns / 1ps

//MAIN ADDING UNIT 
module Adding_Unit(rstn,in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,in10,in11,in12,in13,in14,in15,in16,out,sign);
input rstn;
input [65:0]in0,in1,in2,in3,in4,in5,in6,in7,in8,in9,in10,in11,in12,in13,in14,in15,in16;
output [63:0]out;
output sign;
wire[65:0]out_ns; //Internal connections
reg[63:0]out_ps; //Internal connections 
wire[65:0]s[6:0];
integer i;
//Present state register 
always @(*) begin 
    if (rstn==0) begin //Active low reset 
         out_ps<=0;
    end
    else begin 
        if(out_ns[65]==0)begin 
            out_ps<=out_ns[63:0];
        end
        else if(out_ns[65]==1)begin 
            out_ps<=(~out_ns[63:0])+1;
        end 
    end 
end 
//Next state logic 
csa csa0(in16,in15,in14,s[0]);
csa csa1(in13,in12,in11,s[1]);
csa csa2(in10,in9,in8,s[2]);
csa csa3(in7,in6,in5,s[3]);
csa csa4(in4,in3,in2,s[4]);
csa csa5(s[0],s[1],s[2],s[5]);
csa csa6(s[5],s[3],s[4],s[6]);
csa csa7(s[6],in0,in1,out_ns);
//Assigning output 
assign out=out_ps;
assign sign=out_ns[65];
endmodule

// FULL ADDER MODULE 
module full_adder(in1,in2,cin,sum,cout);
input in1,in2,cin;
output sum,cout;
assign {cout,sum}=in1+in2+cin;
endmodule 

//CSA ADDER MODULE 
module csa(in1,in2,in3,sum_out);
input [65:0]in1,in2,in3;
output [65:0]sum_out;
wire [65:0]sum1;
wire [65:0]sum2;
full_adder fa0(in1[0],in2[0],in3[0],sum1[0],sum2[0]);
full_adder fa1(in1[1],in2[1],in3[1],sum1[1],sum2[1]);
full_adder fa2(in1[2],in2[2],in3[2],sum1[2],sum2[2]);
full_adder fa3(in1[3],in2[3],in3[3],sum1[3],sum2[3]);
full_adder fa4(in1[4],in2[4],in3[4],sum1[4],sum2[4]);
full_adder fa5(in1[5],in2[5],in3[5],sum1[5],sum2[5]);
full_adder fa6(in1[6],in2[6],in3[6],sum1[6],sum2[6]);
full_adder fa7(in1[7],in2[7],in3[7],sum1[7],sum2[7]);
full_adder fa8(in1[8],in2[8],in3[8],sum1[8],sum2[8]);
full_adder fa9(in1[9],in2[9],in3[9],sum1[9],sum2[9]);
full_adder fa10(in1[10],in2[10],in3[10],sum1[10],sum2[10]);
full_adder fa11(in1[11],in2[11],in3[11],sum1[11],sum2[11]);
full_adder fa12(in1[12],in2[12],in3[12],sum1[12],sum2[12]);
full_adder fa13(in1[13],in2[13],in3[13],sum1[13],sum2[13]);
full_adder fa14(in1[14],in2[14],in3[14],sum1[14],sum2[14]);
full_adder fa15(in1[15],in2[15],in3[15],sum1[15],sum2[15]);
full_adder fa16(in1[16],in2[16],in3[16],sum1[16],sum2[16]);
full_adder fa17(in1[17],in2[17],in3[17],sum1[17],sum2[17]);
full_adder fa18(in1[18],in2[18],in3[18],sum1[18],sum2[18]);
full_adder fa19(in1[19],in2[19],in3[19],sum1[19],sum2[19]);
full_adder fa20(in1[20],in2[20],in3[20],sum1[20],sum2[20]);
full_adder fa21(in1[21],in2[21],in3[21],sum1[21],sum2[21]);
full_adder fa22(in1[22],in2[22],in3[22],sum1[22],sum2[22]);
full_adder fa23(in1[23],in2[23],in3[23],sum1[23],sum2[23]);
full_adder fa24(in1[24],in2[24],in3[24],sum1[24],sum2[24]);
full_adder fa25(in1[25],in2[25],in3[25],sum1[25],sum2[25]);
full_adder fa26(in1[26],in2[26],in3[26],sum1[26],sum2[26]);
full_adder fa27(in1[27],in2[27],in3[27],sum1[27],sum2[27]);
full_adder fa28(in1[28],in2[28],in3[28],sum1[28],sum2[28]);
full_adder fa29(in1[29],in2[29],in3[29],sum1[29],sum2[29]);
full_adder fa30(in1[30],in2[30],in3[30],sum1[30],sum2[30]);
full_adder fa31(in1[31],in2[31],in3[31],sum1[31],sum2[31]);
full_adder fa32(in1[32],in2[32],in3[32],sum1[32],sum2[32]);
full_adder fa33(in1[33],in2[33],in3[33],sum1[33],sum2[33]);
full_adder fa34(in1[34],in2[34],in3[34],sum1[34],sum2[34]);
full_adder fa35(in1[35],in2[35],in3[35],sum1[35],sum2[35]);
full_adder fa36(in1[36],in2[36],in3[36],sum1[36],sum2[36]);
full_adder fa37(in1[37],in2[37],in3[37],sum1[37],sum2[37]);
full_adder fa38(in1[38],in2[38],in3[38],sum1[38],sum2[38]);
full_adder fa39(in1[39],in2[39],in3[39],sum1[39],sum2[39]);
full_adder fa40(in1[40],in2[40],in3[40],sum1[40],sum2[40]);
full_adder fa41(in1[41],in2[41],in3[41],sum1[41],sum2[41]);
full_adder fa42(in1[42],in2[42],in3[42],sum1[42],sum2[42]);
full_adder fa43(in1[43],in2[43],in3[43],sum1[43],sum2[43]);
full_adder fa44(in1[44],in2[44],in3[44],sum1[44],sum2[44]);
full_adder fa45(in1[45],in2[45],in3[45],sum1[45],sum2[45]);
full_adder fa46(in1[46],in2[46],in3[46],sum1[46],sum2[46]);
full_adder fa47(in1[47],in2[47],in3[47],sum1[47],sum2[47]);
full_adder fa48(in1[48],in2[48],in3[48],sum1[48],sum2[48]);
full_adder fa49(in1[49],in2[49],in3[49],sum1[49],sum2[49]);
full_adder fa50(in1[50],in2[50],in3[50],sum1[50],sum2[50]);
full_adder fa51(in1[51],in2[51],in3[51],sum1[51],sum2[51]);
full_adder fa52(in1[52],in2[52],in3[52],sum1[52],sum2[52]);
full_adder fa53(in1[53],in2[53],in3[53],sum1[53],sum2[53]);
full_adder fa54(in1[54],in2[54],in3[54],sum1[54],sum2[54]);
full_adder fa55(in1[55],in2[55],in3[55],sum1[55],sum2[55]);
full_adder fa56(in1[56],in2[56],in3[56],sum1[56],sum2[56]);
full_adder fa57(in1[57],in2[57],in3[57],sum1[57],sum2[57]);
full_adder fa58(in1[58],in2[58],in3[58],sum1[58],sum2[58]);
full_adder fa59(in1[59],in2[59],in3[59],sum1[59],sum2[59]);
full_adder fa60(in1[60],in2[60],in3[60],sum1[60],sum2[60]);
full_adder fa61(in1[61],in2[61],in3[61],sum1[61],sum2[61]);
full_adder fa62(in1[62],in2[62],in3[62],sum1[62],sum2[62]);
full_adder fa63(in1[63],in2[63],in3[63],sum1[63],sum2[63]);
full_adder fa64(in1[64],in2[64],in3[64],sum1[64],sum2[64]);
full_adder fa65(in1[65],in2[65],in3[65],sum1[65],sum2[65]);
assign sum_out=(sum1+(sum2<<1));
endmodule