module delaycell #(parameter Ntimes5ns = 20, parameter ctrlport_width = 5)
(
    input wire in,
    input wire enable_dlycontrol,
    input wire [ctrlport_width-1:0] dlycontrol,
    output wire out
);

    // Conversion from binary (dlycontrol) 
    // to inverted thermo-code (_bypass_)
    // with enable   
    wire [Ntimes5ns-1:0] _bypass_ = enable_dlycontrol ? {Ntimes5ns{1'b1}}<<dlycontrol : {Ntimes5ns{1'b1}};
    
    // Generate delaycell with bypass function
    //                                ___________               bypass[j]
    //              _____            |           |              |-------\
    // bypass[j]--o| AND |--sigb[j]--| Delay 5ns |----sigc[j]---|0 mux   |--sigd[j]--
    //  siga[j]-.--|_____|           |___________|   .--siga[j]-|1______/
    //           \__________________________________/
    //
    wire [Ntimes5ns-1:0] _siga_;
    wire [Ntimes5ns-1:0] _sigb_;
    wire [Ntimes5ns-1:0] _sigc_;
    wire [Ntimes5ns-1:0] _sigd_;
    genvar j;
    generate
       for(j=0;j<Ntimes5ns;j=j+1) begin
          sky130_fd_sc_hd__and2_1 and1 (.A(~_bypass_[j]),.B(_siga_[j]),.X(_sigb_[j]));
          sky130_mm_sc_hd_dlyPoly5ns delay_unit (.in(_sigb_[j]), .out(_sigc_[j]));
          sky130_fd_sc_hd__mux2_1 mux1 (.A0(_sigc_[j]),.A1(_siga_[j]),.S( _bypass_[j]),.X(_sigd_[j]));
          assign _siga_[j] = (j==0) ? in : _sigd_[j-1];
       end             
       assign out = _sigd_[Ntimes5ns-1];
    endgenerate
endmodule