Ejemplo n.º 1
0
    def __init__(self):
        self.site_to_cmt = dict(read_site_to_cmt())

        self.leaf_gclks = {}
        self.ioclks = {}
        self.rclks = {}
        self.selected_leaf_gclks = {}
        self.lut_maker = lut_maker.LutMaker()

        for cmt in set(self.site_to_cmt.values()):
            self.leaf_gclks[cmt] = []
            self.ioclks[cmt] = []
            self.rclks[cmt] = []
Ejemplo n.º 2
0
def run():
    luts = lut_maker.LutMaker()
    connects = io.StringIO()

    tile_params = []
    params = []
    sites = sorted(list(gen_sites()))
    for idx, ((tile, site),
              isone) in enumerate(zip(sites,
                                      util.gen_fuzz_states(len(sites)))):

        p = {}
        p['tile'] = tile
        p['site'] = site
        p['isone'] = isone
        params.append(p)
        tile_params.append((tile, p['isone'], site))

    write_params(tile_params)

    print('''
module top();
    ''')

    # Always output a LUT6 to make placer happy.
    print('''
     (* KEEP, DONT_TOUCH *)
     LUT6 dummy_lut();
     ''')

    # Need IDELAYCTRL for IDEALAYs
    print('''
     (* KEEP, DONT_TOUCH *)
     IDELAYCTRL();
     ''')

    for p in params:
        use_idelay(p, luts, connects)

    for l in luts.create_wires_and_luts():
        print(l)

    print(connects.getvalue())

    print("endmodule")
Ejemplo n.º 3
0
def run():
    tile_types = [
        'IBUF', 'OBUF', 'IOBUF_INTERMDISABLE', None, None, None, None, None
    ]

    i_idx = 0
    o_idx = 0
    io_idx = 0

    iostandards = [
        'LVCMOS12',
        'LVCMOS15',
        'LVCMOS18',
        'LVCMOS25',
        'LVCMOS33',
        'LVTTL',
        'SSTL135',
    ]

    diff_map = {
        "SSTL135": ["DIFF_SSTL135"],
    }

    IN_TERM_ALLOWED = [
        'SSTL15',
        'SSTL15_R',
        'SSTL18',
        'SSTL18_R',
        'SSTL135',
        'SSTL135_R',
        'HSTL_I'
        'HSTL_I_18'
        'HSTL_II',
        'HSTL_II_18',
    ]

    iostandard = random.choice(iostandards)

    if iostandard in ['LVTTL', 'LVCMOS18']:
        drives = [4, 8, 12, 16, 24]
    elif iostandard in ['LVCMOS12']:
        drives = [4, 8, 12]
    elif iostandard == 'SSTL135':
        drives = None
    else:
        drives = [4, 8, 12, 16]

    slews = ['FAST', 'SLOW']
    pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"]

    luts = lut_maker.LutMaker()

    connects = io.StringIO()

    tile_params = []
    params = {
        "tiles": [],
        'INTERNAL_VREF': {},
    }

    with open(os.path.join(os.getenv('FUZDIR'), 'build', 'iobanks.txt')) as f:
        iobanks = [int(l.strip().split(',')[1]) for l in f]

    params['iobanks'] = iobanks

    if iostandard in ['SSTL135']:
        for iobank in iobanks:
            params['INTERNAL_VREF'][iobank] = random.choice((
                .600,
                .675,
                .75,
                .90,
            ))

    any_idelay = False
    for tile, sites in gen_sites():
        site_bels = {}
        for site_type in sites:
            if site_type.endswith('M'):
                if iostandard in diff_map:
                    site_bels[site_type] = random.choice(
                        tile_types + ['IBUFDS', 'OBUFDS', 'OBUFTDS'])
                else:
                    site_bels[site_type] = random.choice(tile_types)
                is_m_diff = site_bels[site_type] is not None and site_bels[
                    site_type].endswith('DS')
            else:
                site_bels[site_type] = random.choice(tile_types)

        if is_m_diff:
            site_bels['IOB33S'] = None

        for site_type, site in sites.items():
            p = {}
            p['tile'] = tile
            p['site'] = site
            p['type'] = site_bels[site_type]

            if p['type'] is not None and p['type'].endswith('DS'):
                iostandard_site = random.choice(diff_map[iostandard])
                p['pair_site'] = sites['IOB33S']
            else:
                iostandard_site = iostandard

            p['IOSTANDARD'] = verilog.quote(iostandard_site)
            p['PULLTYPE'] = verilog.quote(random.choice(pulls))

            if p['type'] is None:
                p['pad_wire'] = None
            elif p['type'] == 'IBUF':
                p['pad_wire'] = 'di[{}]'.format(i_idx)
                p['IDELAY_ONLY'] = random.randint(0, 1)
                if not p['IDELAY_ONLY']:
                    p['owire'] = luts.get_next_input_net()
                else:
                    any_idelay = True
                    p['owire'] = 'idelay_{site}'.format(**p)

                p['DRIVE'] = None
                p['SLEW'] = None
                p['IBUF_LOW_PWR'] = random.randint(0, 1)

                if iostandard in IN_TERM_ALLOWED:
                    p['IN_TERM'] = random.choice((
                        'NONE',
                        'UNTUNED_SPLIT_40',
                        'UNTUNED_SPLIT_50',
                        'UNTUNED_SPLIT_60',
                    ))

                i_idx += 1
            elif p['type'] == 'IBUFDS':
                p['pad_wire'] = 'di[{}]'.format(i_idx)
                i_idx += 1
                p['bpad_wire'] = 'di[{}]'.format(i_idx)
                i_idx += 1

                p['IDELAY_ONLY'] = random.randint(0, 1)
                p['DIFF_TERM'] = random.randint(0, 1)
                if not p['IDELAY_ONLY']:
                    p['owire'] = luts.get_next_input_net()
                else:
                    any_idelay = True
                    p['owire'] = 'idelay_{site}'.format(**p)

                p['DRIVE'] = None
                p['SLEW'] = None
                p['IBUF_LOW_PWR'] = random.randint(0, 1)

            elif p['type'] == 'OBUF':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))

                o_idx += 1
            elif p['type'] == 'OBUFDS':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['bpad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
            elif p['type'] == 'OBUFTDS':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['bpad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['tristate_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
            elif p['type'] == 'IOBUF_INTERMDISABLE':
                p['pad_wire'] = 'dio[{}]'.format(io_idx)
                p['iwire'] = luts.get_next_output_net()
                p['owire'] = luts.get_next_input_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
                p['tristate_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['ibufdisable_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['intermdisable_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                io_idx += 1

            if 'DRIVE' in p:
                if p['DRIVE'] is not None:
                    p['DRIVE_STR'] = '.DRIVE({}),'.format(p['DRIVE'])
                else:
                    p['DRIVE_STR'] = ''

            if p['type'] is not None:
                tile_params.append((
                    tile,
                    site,
                    p['pad_wire'],
                    iostandard_site,
                    p['DRIVE'],
                    verilog.unquote(p['SLEW']) if p['SLEW'] else None,
                    verilog.unquote(p['PULLTYPE']),
                    p['IN_TERM'] if 'IN_TERM' in p else None,
                ))
            params['tiles'].append(p)

    write_params(tile_params)

    with open('iobank_vref.csv', 'w') as f:
        for iobank, vref in params['INTERNAL_VREF'].items():
            f.write('{},{}\n'.format(iobank, vref))

    print('''
`define N_DI {n_di}
`define N_DO {n_do}
`define N_DIO {n_dio}

module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
    '''.format(n_di=i_idx, n_do=o_idx, n_dio=io_idx))

    if any_idelay:
        print('''
        (* KEEP, DONT_TOUCH *)
        IDELAYCTRL();''')

    # Always output a LUT6 to make placer happy.
    print('''
        (* KEEP, DONT_TOUCH *)
        LUT6 dummy_lut();''')

    for p in params['tiles']:
        if p['type'] is None:
            continue
        elif p['type'] == 'IBUF':
            print('''
        wire idelay_{site};

        (* KEEP, DONT_TOUCH *)
        IBUF #(
            .IBUF_LOW_PWR({IBUF_LOW_PWR}),
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .I({pad_wire}),
            .O({owire})
            );'''.format(**p),
                  file=connects)
            if p['IDELAY_ONLY']:
                print("""
        (* KEEP, DONT_TOUCH *)
        IDELAYE2 idelay_site_{site} (
            .IDATAIN(idelay_{site})
            );""".format(**p),
                      file=connects)

        elif p['type'] == 'IBUFDS':
            print('''
        wire idelay_{site};

        (* KEEP, DONT_TOUCH *)
        IBUFDS #(
            .IBUF_LOW_PWR({IBUF_LOW_PWR}),
            .DIFF_TERM({DIFF_TERM}),
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .I({pad_wire}),
            .IB({bpad_wire}),
            .O({owire})
            );'''.format(**p),
                  file=connects)
            if p['IDELAY_ONLY']:
                print("""
        (* KEEP, DONT_TOUCH *)
        IDELAYE2 idelay_site_{site} (
            .IDATAIN(idelay_{site})
            );""".format(**p),
                      file=connects)

        elif p['type'] == 'OBUF':
            print('''
        (* KEEP, DONT_TOUCH *)
        OBUF #(
            .IOSTANDARD({IOSTANDARD}),
            {DRIVE_STR}
            .SLEW({SLEW})
        ) obuf_{site} (
            .O({pad_wire}),
            .I({iwire})
            );'''.format(**p),
                  file=connects)
        elif p['type'] == 'OBUFDS':
            print('''
        (* KEEP, DONT_TOUCH *)
        OBUFDS #(
            .IOSTANDARD({IOSTANDARD}),
            {DRIVE_STR}
            .SLEW({SLEW})
        ) obufds_{site} (
            .O({pad_wire}),
            .OB({bpad_wire}),
            .I({iwire})
            );'''.format(**p),
                  file=connects)
        elif p['type'] == 'OBUFTDS':
            print('''
        (* KEEP, DONT_TOUCH *)
        OBUFTDS #(
            .IOSTANDARD({IOSTANDARD}),
            {DRIVE_STR}
            .SLEW({SLEW})
        ) obufds_{site} (
            .O({pad_wire}),
            .OB({bpad_wire}),
            .T({tristate_wire}),
            .I({iwire})
            );'''.format(**p),
                  file=connects)
        elif p['type'] == 'IOBUF_INTERMDISABLE':
            print('''
        (* KEEP, DONT_TOUCH *)
        IOBUF_INTERMDISABLE #(
            .IOSTANDARD({IOSTANDARD}),
            {DRIVE_STR}
            .SLEW({SLEW})
        ) ibuf_{site} (
            .IO({pad_wire}),
            .I({iwire}),
            .O({owire}),
            .T({tristate_wire}),
            .IBUFDISABLE({ibufdisable_wire}),
            .INTERMDISABLE({intermdisable_wire})
            );'''.format(**p),
                  file=connects)

    for l in luts.create_wires_and_luts():
        print(l)

    print(connects.getvalue())

    print("endmodule")

    with open('params.json', 'w') as f:
        json.dump(params, f, indent=2)
Ejemplo n.º 4
0
def run():
    iostandards = [
        'LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'LVCMOS25', 'LVCMOS33', 'LVTTL'
    ]
    iostandard = random.choice(iostandards)

    if iostandard in ['LVTTL', 'LVCMOS18']:
        drives = [4, 8, 12, 16, 24]
    elif iostandard == 'LVCMOS12':
        drives = [4, 8, 12]
    else:
        drives = [4, 8, 12, 16]

    slews = ['FAST', 'SLOW']
    pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"]

    luts = lut_maker.LutMaker()

    connects = io.StringIO()

    tile_params = []
    params = []
    for idx, (tile, site) in enumerate(gen_sites()):
        if idx == 0:
            continue

        p = {}
        p['tile'] = tile
        p['site'] = site
        p['ilogic_loc'] = site.replace('IOB', 'ILOGIC')
        p['ologic_loc'] = site.replace('IOB', 'OLOGIC')
        p['idelay_loc'] = site.replace('IOB', 'IDELAY')
        p['IOSTANDARD'] = verilog.quote(iostandard)
        p['PULLTYPE'] = verilog.quote(random.choice(pulls))
        p['DRIVE'] = random.choice(drives)
        p['SLEW'] = verilog.quote(random.choice(slews))

        p['pad_wire'] = 'dio[{}]'.format(idx - 1)
        p['owire'] = 'do_buf[{}]'.format(idx - 1)
        p['iwire'] = 'di_buf[{}]'.format(idx - 1)
        p['twire'] = 't[{}]'.format(idx - 1)

        params.append(p)
        tile_params.append((tile, site, p['pad_wire'], iostandard, p['DRIVE'],
                            verilog.unquote(p['SLEW']) if p['SLEW'] else None,
                            verilog.unquote(p['PULLTYPE'])))

    write_params(tile_params)

    print('''
`define N_DI {n_di}

module top(input clk, inout wire [`N_DI-1:0] dio);
    wire [`N_DI-1:0] di_buf;
    wire [`N_DI-1:0] do_buf;
    wire [`N_DI-1:0] t;
    '''.format(n_di=idx))

    # Always output a LUT6 to make placer happy.
    print('''
        (* KEEP, DONT_TOUCH *)
        LUT6 dummy_lut();
        ''')

    any_idelay = False

    for p in params:
        print('''
        wire iddr_d_{site};

        (* KEEP, DONT_TOUCH, LOC = "{site}" *)
        IOBUF #(
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .IO({pad_wire}),
            .I({owire}),
            .O({iwire}),
            .T({twire})
            );
            '''.format(**p),
              file=connects)

        p['use_iserdese2'] = random.randint(0, 1)
        if p['use_iserdese2']:
            use_iserdese2(p, luts, connects)
        else:
            use_direct_and_iddr(p, luts, connects)

        if p['iddr_mux_config'] == 'idelay' or p['mux_config'] == 'idelay':
            any_idelay = True

    if any_idelay:
        print("""
    (* KEEP, DONT_TOUCH *)
    IDELAYCTRL();""")

    for l in luts.create_wires_and_luts():
        print(l)

    print(connects.getvalue())

    print("endmodule")

    with open('params.jl', 'w') as f:
        json.dump(params, f, indent=2)
Ejemplo n.º 5
0
def generate_netlist(params):
    DUTN = len(params)
    DIN_N = DUTN * 32
    DOUT_N = DUTN * 32

    string_output = io.StringIO()
    any_bscan = False
    any_icap = False
    usr_access_on = False
    capture_on = False
    startup_on = False
    frame_ecc_on = False
    dcireset_on = False
    luts = lut_maker.LutMaker()
    verilog.top_harness(DIN_N, DOUT_N)
    print('''
module roi(input clk, input [%d:0] din, output [%d:0] dout);''' %
          (DIN_N - 1, DOUT_N - 1))
    for loci, param in enumerate(params):
        ports = {
            'din': 'din[{} +: 8]'.format(8 * loci),
            'dout': 'dout[{} +: 8]'.format(8 * loci),
            'clk': 'clk'
        }
        if param["site_type"] in "BSCAN":
            ports = {
                'din':
                '{{din[{} +: 7],{}}}'.format(8 * loci + 1,
                                             luts.get_next_output_net()),
                'dout':
                '{{dout[{} +: 7],{}}}'.format(8 * loci + 1,
                                              luts.get_next_input_net()),
                'clk':
                'clk'
            }
            any_bscan = True
        elif param["site_type"] in ["ICAP"]:
            any_icap = True
        elif param["site_type"] in ["CAPTURE"]:
            capture_on = True
        elif param["site_type"] in ["STARTUP"]:
            startup_on = True
        elif param["site_type"] in ["FRAME_ECC"]:
            frame_ecc_on = True
        elif param["site_type"] in ["USR_ACCESS", "DCIRESET"]:
            if not param["params"]["ENABLED"]:
                continue
            if param["site_type"] in ["DCIRESET"]:
                dcireset_on = True
            else:
                usr_access_on = True
        else:
            continue
        verilog.instance(param["module"],
                         "inst_{}".format(param["site"]),
                         ports,
                         param["params"],
                         string_buffer=string_output)

    #Generate LUTs
    for l in luts.create_wires_and_luts():
        print(l)
    print(string_output.getvalue())

    print('''
endmodule

// ---------------------------------------------------------------------''')
    if any_icap:
        print('''
module mod_ICAP (input [7:0] din, output [7:0] dout, input clk);
    parameter ICAP_WIDTH = "X32";
    parameter LOC = "ICAP_X0Y0";

    wire [23:0] icap_out;
    (* KEEP, DONT_TOUCH, LOC=LOC *)
    ICAPE2 #(
    .ICAP_WIDTH(ICAP_WIDTH),
    .SIM_CFG_FILE_NAME("NONE")
    )
    ICAPE2_inst (
    .O({icap_out, dout}),
    .CLK(clk),
    .CSIB(),
    .I({24'd0, din}),
    .RDWRB()
    );
endmodule
''')

    if capture_on:
        print('''
module mod_CAPTURE (input [7:0] din, output [7:0] dout, input clk);
    parameter ONESHOT ="TRUE";
    parameter LOC = "ICAP_X0Y0";
    (* KEEP, DONT_TOUCH, LOC=LOC *)
    CAPTUREE2 #(
    .ONESHOT(ONESHOT) // Specifies the procedure for performing single readback per CAP trigger.
    )
    CAPTUREE2_inst (
    .CAP(1'b0),
    .CLK(clk)
    );
endmodule
''')

    if usr_access_on:
        print('''
module mod_USR_ACCESS (input [7:0] din, output [7:0] dout, input clk);
    parameter ENABLED = 1;
    parameter LOC = "USR_ACCESS_X0Y0";

    wire [23:0] usr_access_wire;

    (* KEEP, DONT_TOUCH, LOC=LOC *)
    USR_ACCESSE2 USR_ACCESSE2_inst (
    .CFGCLK(),
    .DATA({usr_access_wire, dout}),
    .DATAVALID()
    );
endmodule
''')

    if any_bscan:
        print('''
module mod_BSCAN (input [7:0] din, output [7:0] dout, input clk);
    parameter JTAG_CHAIN  = 1;
    parameter LOC = "BSCAN_X0Y0";

    (* KEEP, DONT_TOUCH, LOC=LOC *)
    BSCANE2 #(
    .JTAG_CHAIN(JTAG_CHAIN)
    )
    dut (
    .CAPTURE(),
    .DRCK(),
    .RESET(),
    .RUNTEST(),
    .SEL(),
    .SHIFT(),
    .TCK(),
    .TDI(dout[0]),
    .TMS(),
    .UPDATE(),
    .TDO(din[0])
    );
endmodule
''')

    if startup_on:
        print('''
module mod_STARTUP (input [7:0] din, output [7:0] dout, input clk);
    parameter LOC = "STARTUP_X0Y0";
    parameter PROG_USR = "******";

    (* KEEP, DONT_TOUCH, LOC=LOC *)
    STARTUPE2 #(
    .PROG_USR(PROG_USR), // Activate program event security feature. Requires encrypted bitstreams.
    .SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
    )
    STARTUPE2_inst (
    .CFGCLK(),
    .CFGMCLK(),
    .EOS(),
    .PREQ(dout[0]),
    .CLK(clk),
    .GSR(),
    .GTS(),
    .KEYCLEARB(),
    .PACK(),
    .USRCCLKO(),
    .USRCCLKTS(),
    .USRDONEO(),
    .USRDONETS()
    );
endmodule
''')

    if frame_ecc_on:
        print('''
module mod_FRAME_ECC (input [7:0] din, output [7:0] dout, input clk);
    parameter LOC = "FRAME_ECC_X0Y0";
    parameter FARSRC = "EFAR";

    wire [25:0] far_wire;
    assign dout[7:0] = far_wire[7:0];
    (* KEEP, DONT_TOUCH, LOC=LOC *)
    FRAME_ECCE2 #(
    .FARSRC(FARSRC),
    .FRAME_RBT_IN_FILENAME("NONE")
    )
    FRAME_ECCE2_inst (
    .CRCERROR(),
    .ECCERROR(),
    .ECCERRORSINGLE(),
    .FAR(far_wire),
    .SYNBIT(),
    .SYNDROME(),
    .SYNDROMEVALID(),
    .SYNWORD()
    );
endmodule
''')

    if dcireset_on:
        print('''
module mod_DCIRESET (input [7:0] din, output [7:0] dout, input clk);
    parameter LOC = "FRAME_ECC_X0Y0";
    parameter ENABLED = 1;

    (* KEEP, DONT_TOUCH, LOC=LOC *)
    DCIRESET DCIRESET_inst (
    .LOCKED(dout[0]),
    .RST(dout[1])
);
endmodule
''')
Ejemplo n.º 6
0
def run():
    tile_types = [
        'IBUF', 'OBUF', 'IOBUF_INTERMDISABLE', None, None, None, None, None
    ]

    i_idx = 0
    o_idx = 0
    io_idx = 0

    iostandards = [
        'LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'LVCMOS25', 'LVCMOS33', 'LVTTL'
    ]
    iostandard = random.choice(iostandards)

    if iostandard in ['LVTTL', 'LVCMOS18']:
        drives = [4, 8, 12, 16, 24]
    elif iostandard == 'LVCMOS12':
        drives = [4, 8, 12]
    else:
        drives = [4, 8, 12, 16]

    slews = ['FAST', 'SLOW']
    pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"]

    luts = lut_maker.LutMaker()

    connects = io.StringIO()

    tile_params = []
    params = []
    any_idelay = False
    for tile, site in gen_sites():
        p = {}
        p['tile'] = tile
        p['site'] = site
        p['type'] = random.choice(tile_types)
        p['IOSTANDARD'] = verilog.quote(iostandard)
        p['PULLTYPE'] = verilog.quote(random.choice(pulls))

        if p['type'] is None:
            p['pad_wire'] = None
        elif p['type'] == 'IBUF':
            p['pad_wire'] = 'di[{}]'.format(i_idx)
            p['IDELAY_ONLY'] = random.randint(0, 1)
            if not p['IDELAY_ONLY']:
                p['owire'] = luts.get_next_input_net()
            else:
                any_idelay = True
                p['owire'] = 'idelay_{site}'.format(**p)

            p['DRIVE'] = None
            p['SLEW'] = None
            p['IBUF_LOW_PWR'] = random.randint(0, 1)

            i_idx += 1
        elif p['type'] == 'OBUF':
            p['pad_wire'] = 'do[{}]'.format(o_idx)
            p['iwire'] = luts.get_next_output_net()
            p['DRIVE'] = random.choice(drives)
            p['SLEW'] = verilog.quote(random.choice(slews))

            o_idx += 1
        elif p['type'] == 'IOBUF_INTERMDISABLE':
            p['pad_wire'] = 'dio[{}]'.format(io_idx)
            p['iwire'] = luts.get_next_output_net()
            p['owire'] = luts.get_next_input_net()
            p['DRIVE'] = random.choice(drives)
            p['SLEW'] = verilog.quote(random.choice(slews))
            p['tristate_wire'] = random.choice(
                ('0', luts.get_next_output_net()))
            p['ibufdisable_wire'] = random.choice(
                ('0', luts.get_next_output_net()))
            p['intermdisable_wire'] = random.choice(
                ('0', luts.get_next_output_net()))
            io_idx += 1

        params.append(p)

        if p['type'] is not None:
            tile_params.append(
                (tile, site, p['pad_wire'], iostandard, p['DRIVE'],
                 verilog.unquote(p['SLEW']) if p['SLEW'] else None,
                 verilog.unquote(p['PULLTYPE'])))

    write_params(tile_params)

    print('''
`define N_DI {n_di}
`define N_DO {n_do}
`define N_DIO {n_dio}

module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
    '''.format(n_di=i_idx, n_do=o_idx, n_dio=io_idx))

    if any_idelay:
        print('''
        (* KEEP, DONT_TOUCH *)
        IDELAYCTRL();''')

    # Always output a LUT6 to make placer happy.
    print('''
        (* KEEP, DONT_TOUCH *)
        LUT6 dummy_lut();''')

    for p in params:
        if p['type'] is None:
            continue
        elif p['type'] == 'IBUF':
            print('''
        wire idelay_{site};

        (* KEEP, DONT_TOUCH *)
        IBUF #(
            .IBUF_LOW_PWR({IBUF_LOW_PWR}),
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .I({pad_wire}),
            .O({owire})
            );'''.format(**p),
                  file=connects)
            if p['IDELAY_ONLY']:
                print("""
        (* KEEP, DONT_TOUCH *)
        IDELAYE2 idelay_site_{site} (
            .IDATAIN(idelay_{site})
            );""".format(**p),
                      file=connects)

        elif p['type'] == 'OBUF':
            print('''
        (* KEEP, DONT_TOUCH *)
        OBUF #(
            .IOSTANDARD({IOSTANDARD}),
            .DRIVE({DRIVE}),
            .SLEW({SLEW})
        ) ibuf_{site} (
            .O({pad_wire}),
            .I({iwire})
            );'''.format(**p),
                  file=connects)
        elif p['type'] == 'IOBUF_INTERMDISABLE':
            print('''
        (* KEEP, DONT_TOUCH *)
        IOBUF_INTERMDISABLE #(
            .IOSTANDARD({IOSTANDARD}),
            .DRIVE({DRIVE}),
            .SLEW({SLEW})
        ) ibuf_{site} (
            .IO({pad_wire}),
            .I({iwire}),
            .O({owire}),
            .T({tristate_wire}),
            .IBUFDISABLE({ibufdisable_wire}),
            .INTERMDISABLE({intermdisable_wire})
            );'''.format(**p),
                  file=connects)

    for l in luts.create_wires_and_luts():
        print(l)

    print(connects.getvalue())

    print("endmodule")

    with open('params.jl', 'w') as f:
        json.dump(params, f, indent=2)