module gate_top (
    clk,
    a,
    b,
    c,
    d,
    sel,
    core_out,
    feedthrough_in_ft0,
    feedthrough_out_ft0,
    feedthrough_in_ft1,
    feedthrough_out_ft1,
    feedthrough_in_ft2,
    feedthrough_out_ft2,
    feedthrough_in_ft3,
    feedthrough_out_ft3,
    feedthrough_in_ft4,
    feedthrough_out_ft4
);
    input clk;
    input a;
    input b;
    input c;
    input d;
    input sel;
    output core_out;
    input feedthrough_in_ft0;
    output feedthrough_out_ft0;
    input feedthrough_in_ft1;
    output feedthrough_out_ft1;
    input feedthrough_in_ft2;
    output feedthrough_out_ft2;
    input feedthrough_in_ft3;
    output feedthrough_out_ft3;
    input feedthrough_in_ft4;
    output feedthrough_out_ft4;

    wire n_core_and;
    wire n_core_or;
    wire n_core_xor;
    wire n_core_mux;
    wire n_core_nand;
    wire n_core_nor;
    wire n_core_d;
    wire n_ft0_0;
    wire n_ft0_1;
    wire n_ft1_0;
    wire n_ft1_1;
    wire n_ft2_0;
    wire n_ft2_1;
    wire n_ft3_0;
    wire n_ft3_1;
    wire n_ft3_2;
    wire n_ft3_3;
    wire n_ft4_0;
    wire n_ft4_1;
    wire n_ft4_2;

    AND2X1 u_core_and (
        .A(a),
        .B(b),
        .Y(n_core_and)
    );
    OR2X1 u_core_or (
        .A(c),
        .B(d),
        .Y(n_core_or)
    );
    XOR2X1 u_core_xor (
        .A(n_core_and),
        .B(n_core_or),
        .Y(n_core_xor)
    );
    MUX2X1 u_core_mux (
        .A(n_core_and),
        .B(n_core_or),
        .S(sel),
        .Y(n_core_mux)
    );
    NAND2X1 u_core_nand (
        .A(n_core_xor),
        .B(n_core_mux),
        .Y(n_core_nand)
    );
    NOR2X1 u_core_nor (
        .A(n_core_mux),
        .B(n_core_nand),
        .Y(n_core_nor)
    );
    AOI21X1 u_core_aoi (
        .A(n_core_nand),
        .B(n_core_nor),
        .C(a),
        .Y(n_core_d)
    );
    DFFX2 u_core_reg (
        .D(n_core_d),
        .CK(clk),
        .Q(core_out)
    );

    // feedthrough chain 'ft0': BUFX2 -> INVX1 -> BUFX1 (0 repeater flops)
    BUFX2 u_ft0_0_bufx2 (
        .A(feedthrough_in_ft0),
        .Y(n_ft0_0)
    );
    INVX1 u_ft0_1_invx1 (
        .A(n_ft0_0),
        .Y(n_ft0_1)
    );
    BUFX1 u_ft0_2_bufx1 (
        .A(n_ft0_1),
        .Y(feedthrough_out_ft0)
    );

    // feedthrough chain 'ft1': BUFX2 -> DFFX1 -> INVX1 (1 repeater flop)
    BUFX2 u_ft1_0_bufx2 (
        .A(feedthrough_in_ft1),
        .Y(n_ft1_0)
    );
    DFFX1 u_ft1_1_dffx1 (
        .D(n_ft1_0),
        .CK(clk),
        .Q(n_ft1_1)
    );
    INVX1 u_ft1_2_invx1 (
        .A(n_ft1_1),
        .Y(feedthrough_out_ft1)
    );

    // feedthrough chain 'ft2': DFFX1 -> BUFX2 -> DFFX1 (2 repeater flops)
    DFFX1 u_ft2_0_dffx1 (
        .D(feedthrough_in_ft2),
        .CK(clk),
        .Q(n_ft2_0)
    );
    BUFX2 u_ft2_1_bufx2 (
        .A(n_ft2_0),
        .Y(n_ft2_1)
    );
    DFFX1 u_ft2_2_dffx1 (
        .D(n_ft2_1),
        .CK(clk),
        .Q(feedthrough_out_ft2)
    );

    // feedthrough chain 'ft3': INVX1 -> DFFX1 -> BUFX1 -> DFFX1 -> INVX2 (2 repeater flops)
    INVX1 u_ft3_0_invx1 (
        .A(feedthrough_in_ft3),
        .Y(n_ft3_0)
    );
    DFFX1 u_ft3_1_dffx1 (
        .D(n_ft3_0),
        .CK(clk),
        .Q(n_ft3_1)
    );
    BUFX1 u_ft3_2_bufx1 (
        .A(n_ft3_1),
        .Y(n_ft3_2)
    );
    DFFX1 u_ft3_3_dffx1 (
        .D(n_ft3_2),
        .CK(clk),
        .Q(n_ft3_3)
    );
    INVX2 u_ft3_4_invx2 (
        .A(n_ft3_3),
        .Y(feedthrough_out_ft3)
    );

    // feedthrough chain 'ft4': INVX1 -> INVX1 -> INVX1 -> INVX1 (0 repeater flops)
    INVX1 u_ft4_0_invx1 (
        .A(feedthrough_in_ft4),
        .Y(n_ft4_0)
    );
    INVX1 u_ft4_1_invx1 (
        .A(n_ft4_0),
        .Y(n_ft4_1)
    );
    INVX1 u_ft4_2_invx1 (
        .A(n_ft4_1),
        .Y(n_ft4_2)
    );
    INVX1 u_ft4_3_invx1 (
        .A(n_ft4_2),
        .Y(feedthrough_out_ft4)
    );

endmodule
