fuzzers: iob18-sing/ilogic/iserdes + hclk-cmt-ck-in; strip_transplant util

Locally-developed virtex7 fuzzers whose results are already in the
database — checked in as the preferred (source) form of those DB
features, alongside the eth-arp open-flow validation work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dr Jonathan Richard Robert Kimmitt 2026-07-14 06:48:27 +01:00
parent a5edd0d816
commit 53b33056c1
32 changed files with 38766 additions and 0 deletions

View File

@ -0,0 +1,40 @@
# Copyright (C) 2017-2022 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
#
# SING-row IOB18 basic-config fuzzer (DRIVE/SLEW/PULLTYPE/STEPDOWN) for the
# single IOB18 site in each *_SING tile. Replaces the hand-copied (and
# mis-addressed) LIOB18_SING entries with real measurements.
#
# Unlike regular IOB18 (where L+R share the 'iob18' segbits db and segmaker
# emits a normalised IOB18. prefix), SING tiles have SEPARATE liob18_sing /
# riob18_sing dbs, so segmaker emits LIOB18_SING. / RIOB18_SING. and the two
# sides must be solved independently. process_rdb.py still re-emits the
# IOB18. prefix, which the per-side mergedb cases rewrite to LIOB18_SING. /
# RIOB18_SING.
N := 30
include ../fuzzer.mk
database: build/segbits_liob18_sing.db build/segbits_riob18_sing.db
# Per-side: segmatch -> drop unresolved (<.. candidates>, which process_rdb
# cannot parse) -> process_rdb enum-merge -> dbfixup.
build/segbits_liob18_sing.db: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -o build/raw_l.rdb $$(find -name 'segdata_liob18_sing.txt')
python3 process_rdb.py build/raw_l.rdb > build/proc_l.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in build/proc_l.rdb --seg-fn-out $@
build/segbits_riob18_sing.db: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -o build/raw_r.rdb $$(find -name 'segdata_riob18_sing.txt')
python3 process_rdb.py build/raw_r.rdb > build/proc_r.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in build/proc_r.rdb --seg-fn-out $@
pushdb:
${XRAY_MERGEDB} liob18_sing build/segbits_liob18_sing.db
${XRAY_MERGEDB} riob18_sing build/segbits_riob18_sing.db
.PHONY: database pushdb

View File

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2022 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
"""
Fallback for SING IOB DRIVE/STEPDOWN: the *_SING tiles have only ~28 IOB18
sites on the whole device, too few for segmatch to isolate the multi-bit DRIVE
enum (the OUT bit stays <N candidates>). The SING IOB18 is the *same* IOB18
primitive as the regular LIOB18/RIOB18 tiles, and the SING fuzz that DID
resolve (IN/SLEW/PULLTYPE, and the DRIVE candidate bits 38_32/38_34/39_23/39_55)
matches the regular tile bit-for-bit. So derive the unresolved SING features
from the REAL virtex7 LIOB18/RIOB18 measurements (origin 030-iob18) rather than
leave them hand-copied/absent.
Emits, on stdout, the requested feature group(s) for the *_SING tile type,
copied from the same feature on the regular tile. Intended to be appended to
the per-side SING db before pushdb, for ONLY the features the SING fuzz could
not solve (default: DRIVE and STEPDOWN).
"""
import argparse
def load(fn):
d = {}
for line in open(fn):
line = line.strip()
if not line:
continue
tag, _, bits = line.partition(' ')
d[tag] = bits
return d
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--src-db', required=True, help='segbits_liob18.db (real)')
ap.add_argument('--src-prefix', default='LIOB18')
ap.add_argument('--dst-prefix', default='LIOB18_SING')
ap.add_argument(
'--groups', nargs='+', default=['DRIVE', 'STEPDOWN'],
help='feature groups to derive (substring match after the site)')
args = ap.parse_args()
src = load(args.src_db)
for tag, bits in sorted(src.items()):
if not tag.startswith(args.src_prefix + '.'):
continue
# tag = PREFIX.IOB_Yn.<iostds>.<group>[.<enum>]
rest = tag[len(args.src_prefix) + 1:]
parts = rest.split('.')
if len(parts) < 3:
continue
group = parts[2]
if group not in args.groups:
continue
print('{}.{} {}'.format(args.dst_prefix, rest, bits))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,94 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2022 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
"""
SING-row sibling of 030-iob18. Tags the basic IOB18 config (IN_USE / OUT / IN /
IN_ONLY / IN_DIFF / PULLTYPE / DRIVE / SLEW / STEPDOWN) for the single IOB18
site in each *_SING tile, per the OBUF / IBUF / unused type chosen in top.py.
Reuses 030-iob18's drive_opts / enum-zero convention so the merged feature
names (after process_rdb.py) match nextpnr, e.g.
LVCMOS15_LVCMOS18.DRIVE.I12_I16_I2_I4_I6_I8. Single-ended only.
"""
from prjxray.segmaker import Segmaker
from prjxray import segmaker
from prjxray import verilog
import json
LVCMOS = ['LVCMOS12', 'LVCMOS15', 'LVCMOS18']
def bitfilter(frame, word):
# SING tile frames differ from regular LIOB18; let segmatch find them.
return True
def mk_drive_opt(iostandard, drive):
if drive is None:
drive = '_FIXED'
return '{}.DRIVE.I{}'.format(iostandard, drive)
def main():
print("Loading tags")
segmk = Segmaker("design.bits")
with open('params.jl', 'r') as f:
design = json.load(f)
for d in design:
site = d['site']
iostandard = verilog.unquote(d['IOSTANDARD'])
typ = d['type'] # 'OBUF', 'IBUF', or None (unused)
in_use = 1 if typ is not None else 0
is_out = 1 if typ == 'OBUF' else 0
is_in = 1 if typ == 'IBUF' else 0
segmk.add_site_tag(site, 'INOUT', 0)
segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), in_use)
segmk.add_site_tag(site, '{}.OUT'.format(iostandard), is_out)
segmk.add_site_tag(site, '{}.IN'.format(iostandard), is_in)
segmk.add_site_tag(site, '{}.IN_ONLY'.format(iostandard), is_in)
segmk.add_site_tag(site, '{}.IN_DIFF'.format(iostandard), 0)
# PULLTYPE applies whenever the IOB is in use.
if in_use:
segmaker.add_site_group_zero(
segmk, site, "PULLTYPE.",
("NONE", "KEEPER", "PULLDOWN", "PULLUP"), "PULLDOWN",
verilog.unquote(d['PULLTYPE']))
# DRIVE / SLEW / STEPDOWN only meaningful for output buffers.
if typ == 'OBUF':
drive_opts = set()
for opt in LVCMOS:
for drive_opt in ("2", "4", "6", "8", "12", "16"):
if drive_opt in ["12", "16"] and opt == "LVCMOS12":
continue
drive_opts.add(mk_drive_opt(opt, drive_opt))
segmaker.add_site_group_zero(
segmk, site, '', drive_opts, mk_drive_opt('LVCMOS25', '12'),
mk_drive_opt(iostandard, d['DRIVE']))
if d['SLEW']:
for opt in ["SLOW", "FAST"]:
segmk.add_site_tag(
site, iostandard + ".SLEW." + opt,
opt == verilog.unquote(d['SLEW']))
segmk.add_site_tag(site, '{}.STEPDOWN'.format(iostandard), 1)
segmk.compile(bitfilter=bitfilter)
segmk.write(allow_empty=True)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,107 @@
# Copyright (C) 2017-2022 The Project X-Ray Authors
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
source "$::env(XRAY_DIR)/utils/utils.tcl"
proc make_io_pin_sites {} {
# get all possible IOB pins
foreach pad [get_package_pins -filter "IS_GENERAL_PURPOSE == 1"] {
set site [get_sites -of_objects $pad]
if {[llength $site] == 0} {
continue
}
if [string match IOB18* [get_property SITE_TYPE $site]] {
dict append io_pin_sites $site $pad
}
}
return $io_pin_sites
}
proc load_pin_lines {} {
# IOB_X0Y103 clk input
# IOB_X0Y129 do[0] output
set fp [open "params.csv" r]
gets $fp line
set pin_lines {}
for {gets $fp line} {$line != ""} {gets $fp line} {
lappend pin_lines [split $line ","]
}
close $fp
return $pin_lines
}
proc loc_pins {} {
set pin_lines [load_pin_lines]
set io_pin_sites [make_io_pin_sites]
puts "Looping"
for {set idx 0} {$idx < [llength $pin_lines]} {incr idx} {
set line [lindex $pin_lines $idx]
puts "$line"
set site_str [lindex $line 1]
set pin_str [lindex $line 2]
set iostandard [lindex $line 3]
set drive [lindex $line 4]
set slew [lindex $line 5]
set pulltype [lindex $line 6]
# Have: site
# Want: pin for site
set site [get_sites $site_str]
set pad_bel [get_bels -of_objects $site -filter {TYPE =~ PAD && NAME =~ IOB_*}]
# set port [get_ports -of_objects $site]
set port [get_ports $pin_str]
set tile [get_tiles -of_objects $site]
set pin [dict get $io_pin_sites $site]
set props {}
#lappend props PACKAGE_PIN $pin
lappend props IOSTANDARD $iostandard
lappend props PULLTYPE $pulltype
if {$drive != "None"} {
lappend props DRIVE $drive
}
if {$slew != "None"} {
lappend props SLEW $slew
}
puts $props
set_property -dict "$props" $port
}
}
proc run {} {
create_project -force -part $::env(XRAY_PART) design design
read_verilog top.v
synth_design -top top
loc_pins
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-144}]
write_checkpoint -force design_pre_place.dcp
place_design
route_design
write_checkpoint -force design.dcp
write_bitstream -force design.bit
}
run

View File

@ -0,0 +1,17 @@
LVCMOS = ['LVCMOS12', 'LVCMOS15', 'LVCMOS18']
# TODO: add support for digitally controlled impedance (_DCI) and termination (_T)
SSTL = ['SSTL15', #'SSTL15_DCI', 'SSTL15_T_DCI'
'SSTL135', #'SSTL135_DCI', 'SSTL135_T_DCI'
'SSTL12', #'SSTL12_DCI', 'SSTL12_T_DCI'
]
# TODO: add support for digitally controlled impedance (_DCI) and termination (_T)
DIFF_SSTL15 = ['DIFF_SSTL15', ] # 'DIFF_SSTL15_DCI', 'DIFF_SSTL15_T_DCI']
DIFF_SSTL135 = ['DIFF_SSTL135', ] # 'DIFF_SSTL135_DCI', 'DIFF_SSTL135_T_DCI']
DIFF_SSTL12 = ['DIFF_SSTL12', ] # 'DIFF_SSTL12_DCI', 'DIFF_SSTL12_T_DCI']
DIFF_SSTL = DIFF_SSTL15 + DIFF_SSTL135 + DIFF_SSTL12
LVDS = ['LVDS']
DIFF = DIFF_SSTL + LVDS

View File

@ -0,0 +1,23 @@
tile,site,pin,iostandard,drive,slew,pulltype
LIOB18_SING_X81Y1,IOB_X0Y0,di[0],LVCMOS15,6,FAST,PULLUP
LIOB18_SING_X81Y103,IOB_X0Y99,di[1],LVCMOS15,2,SLOW,KEEPER
LIOB18_SING_X81Y155,IOB_X0Y149,di[2],LVCMOS15,2,SLOW,PULLDOWN
LIOB18_SING_X81Y157,IOB_X0Y150,do[0],LVCMOS15,4,FAST,PULLDOWN
LIOB18_SING_X81Y209,IOB_X0Y200,do[1],LVCMOS15,16,SLOW,PULLUP
LIOB18_SING_X81Y259,IOB_X0Y249,do[2],LVCMOS15,4,SLOW,PULLDOWN
LIOB18_SING_X81Y261,IOB_X0Y250,di[3],LVCMOS15,16,FAST,KEEPER
LIOB18_SING_X81Y311,IOB_X0Y299,di[4],LVCMOS15,6,SLOW,KEEPER
LIOB18_SING_X81Y313,IOB_X0Y300,di[5],LVCMOS15,12,FAST,NONE
LIOB18_SING_X81Y363,IOB_X0Y349,di[6],LVCMOS15,16,FAST,PULLUP
LIOB18_SING_X81Y51,IOB_X0Y49,di[7],LVCMOS15,12,FAST,PULLUP
RIOB18_SING_X312Y1,IOB_X1Y0,di[8],LVCMOS15,12,FAST,NONE
RIOB18_SING_X312Y103,IOB_X1Y99,di[9],LVCMOS15,2,SLOW,PULLUP
RIOB18_SING_X312Y157,IOB_X1Y150,di[10],LVCMOS15,8,FAST,PULLDOWN
RIOB18_SING_X312Y207,IOB_X1Y199,do[3],LVCMOS15,16,FAST,NONE
RIOB18_SING_X312Y259,IOB_X1Y249,di[11],LVCMOS15,12,SLOW,PULLUP
RIOB18_SING_X312Y261,IOB_X1Y250,di[12],LVCMOS15,2,SLOW,NONE
RIOB18_SING_X312Y311,IOB_X1Y299,di[13],LVCMOS15,2,FAST,NONE
RIOB18_SING_X312Y313,IOB_X1Y300,di[14],LVCMOS15,16,FAST,PULLDOWN
RIOB18_SING_X312Y363,IOB_X1Y349,di[15],LVCMOS15,6,SLOW,NONE
RIOB18_SING_X312Y51,IOB_X1Y49,di[16],LVCMOS15,4,SLOW,KEEPER
RIOB18_SING_X312Y53,IOB_X1Y50,do[4],LVCMOS15,16,FAST,NONE
1 tile site pin iostandard drive slew pulltype
2 LIOB18_SING_X81Y1 IOB_X0Y0 di[0] LVCMOS15 6 FAST PULLUP
3 LIOB18_SING_X81Y103 IOB_X0Y99 di[1] LVCMOS15 2 SLOW KEEPER
4 LIOB18_SING_X81Y155 IOB_X0Y149 di[2] LVCMOS15 2 SLOW PULLDOWN
5 LIOB18_SING_X81Y157 IOB_X0Y150 do[0] LVCMOS15 4 FAST PULLDOWN
6 LIOB18_SING_X81Y209 IOB_X0Y200 do[1] LVCMOS15 16 SLOW PULLUP
7 LIOB18_SING_X81Y259 IOB_X0Y249 do[2] LVCMOS15 4 SLOW PULLDOWN
8 LIOB18_SING_X81Y261 IOB_X0Y250 di[3] LVCMOS15 16 FAST KEEPER
9 LIOB18_SING_X81Y311 IOB_X0Y299 di[4] LVCMOS15 6 SLOW KEEPER
10 LIOB18_SING_X81Y313 IOB_X0Y300 di[5] LVCMOS15 12 FAST NONE
11 LIOB18_SING_X81Y363 IOB_X0Y349 di[6] LVCMOS15 16 FAST PULLUP
12 LIOB18_SING_X81Y51 IOB_X0Y49 di[7] LVCMOS15 12 FAST PULLUP
13 RIOB18_SING_X312Y1 IOB_X1Y0 di[8] LVCMOS15 12 FAST NONE
14 RIOB18_SING_X312Y103 IOB_X1Y99 di[9] LVCMOS15 2 SLOW PULLUP
15 RIOB18_SING_X312Y157 IOB_X1Y150 di[10] LVCMOS15 8 FAST PULLDOWN
16 RIOB18_SING_X312Y207 IOB_X1Y199 do[3] LVCMOS15 16 FAST NONE
17 RIOB18_SING_X312Y259 IOB_X1Y249 di[11] LVCMOS15 12 SLOW PULLUP
18 RIOB18_SING_X312Y261 IOB_X1Y250 di[12] LVCMOS15 2 SLOW NONE
19 RIOB18_SING_X312Y311 IOB_X1Y299 di[13] LVCMOS15 2 FAST NONE
20 RIOB18_SING_X312Y313 IOB_X1Y300 di[14] LVCMOS15 16 FAST PULLDOWN
21 RIOB18_SING_X312Y363 IOB_X1Y349 di[15] LVCMOS15 6 SLOW NONE
22 RIOB18_SING_X312Y51 IOB_X1Y49 di[16] LVCMOS15 4 SLOW KEEPER
23 RIOB18_SING_X312Y53 IOB_X1Y50 do[4] LVCMOS15 16 FAST NONE

View File

@ -0,0 +1,282 @@
[
{
"tile": "LIOB18_SING_X81Y1",
"site": "IOB_X0Y0",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 6,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "di[0]"
},
{
"tile": "LIOB18_SING_X81Y103",
"site": "IOB_X0Y99",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 2,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"KEEPER\"",
"pin": "di[1]"
},
{
"tile": "LIOB18_SING_X81Y105",
"site": "IOB_X0Y100",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"KEEPER\"",
"pin": null
},
{
"tile": "LIOB18_SING_X81Y155",
"site": "IOB_X0Y149",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 2,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLDOWN\"",
"pin": "di[2]"
},
{
"tile": "LIOB18_SING_X81Y157",
"site": "IOB_X0Y150",
"type": "OBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 4,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLDOWN\"",
"pin": "do[0]"
},
{
"tile": "LIOB18_SING_X81Y207",
"site": "IOB_X0Y199",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"NONE\"",
"pin": null
},
{
"tile": "LIOB18_SING_X81Y209",
"site": "IOB_X0Y200",
"type": "OBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "do[1]"
},
{
"tile": "LIOB18_SING_X81Y259",
"site": "IOB_X0Y249",
"type": "OBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 4,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLDOWN\"",
"pin": "do[2]"
},
{
"tile": "LIOB18_SING_X81Y261",
"site": "IOB_X0Y250",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"KEEPER\"",
"pin": "di[3]"
},
{
"tile": "LIOB18_SING_X81Y311",
"site": "IOB_X0Y299",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 6,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"KEEPER\"",
"pin": "di[4]"
},
{
"tile": "LIOB18_SING_X81Y313",
"site": "IOB_X0Y300",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"NONE\"",
"pin": "di[5]"
},
{
"tile": "LIOB18_SING_X81Y363",
"site": "IOB_X0Y349",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "di[6]"
},
{
"tile": "LIOB18_SING_X81Y51",
"site": "IOB_X0Y49",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "di[7]"
},
{
"tile": "LIOB18_SING_X81Y53",
"site": "IOB_X0Y50",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"NONE\"",
"pin": null
},
{
"tile": "RIOB18_SING_X312Y1",
"site": "IOB_X1Y0",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"NONE\"",
"pin": "di[8]"
},
{
"tile": "RIOB18_SING_X312Y103",
"site": "IOB_X1Y99",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 2,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "di[9]"
},
{
"tile": "RIOB18_SING_X312Y105",
"site": "IOB_X1Y100",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"KEEPER\"",
"pin": null
},
{
"tile": "RIOB18_SING_X312Y155",
"site": "IOB_X1Y149",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"KEEPER\"",
"pin": null
},
{
"tile": "RIOB18_SING_X312Y157",
"site": "IOB_X1Y150",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 8,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLDOWN\"",
"pin": "di[10]"
},
{
"tile": "RIOB18_SING_X312Y207",
"site": "IOB_X1Y199",
"type": "OBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"NONE\"",
"pin": "do[3]"
},
{
"tile": "RIOB18_SING_X312Y209",
"site": "IOB_X1Y200",
"type": null,
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 4,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLUP\"",
"pin": null
},
{
"tile": "RIOB18_SING_X312Y259",
"site": "IOB_X1Y249",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 12,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"PULLUP\"",
"pin": "di[11]"
},
{
"tile": "RIOB18_SING_X312Y261",
"site": "IOB_X1Y250",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 2,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"NONE\"",
"pin": "di[12]"
},
{
"tile": "RIOB18_SING_X312Y311",
"site": "IOB_X1Y299",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 2,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"NONE\"",
"pin": "di[13]"
},
{
"tile": "RIOB18_SING_X312Y313",
"site": "IOB_X1Y300",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"PULLDOWN\"",
"pin": "di[14]"
},
{
"tile": "RIOB18_SING_X312Y363",
"site": "IOB_X1Y349",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 6,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"NONE\"",
"pin": "di[15]"
},
{
"tile": "RIOB18_SING_X312Y51",
"site": "IOB_X1Y49",
"type": "IBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 4,
"SLEW": "\"SLOW\"",
"PULLTYPE": "\"KEEPER\"",
"pin": "di[16]"
},
{
"tile": "RIOB18_SING_X312Y53",
"site": "IOB_X1Y50",
"type": "OBUF",
"IOSTANDARD": "\"LVCMOS15\"",
"DRIVE": 16,
"SLEW": "\"FAST\"",
"PULLTYPE": "\"NONE\"",
"pin": "do[4]"
}
]

View File

@ -0,0 +1,266 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2022 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
""" IOB bits are more complicated than can be easily expressed to segmaker.
There are couple cases that need to be handled here:
- There are some bits that are always set for IN-only ports, but are cleared
selectively for OUT and INOUT ports.
- There are bits per each IOSTANDARD, in addition to drive patterns. These
can be merged to provide unique "(IOSTANDARD, DRIVE)" bit sets.
"""
import argparse
import os
def get_name(l):
parts = l.strip().split(' ')
return parts[0]
def get_site(l):
return get_name(l).split('.')[1]
def parse_bits(l):
parts = l.strip().split(' ')
# Any segmatch marker (<0 candidates>, <5 candidates>, <const0>, <const1>)
# means "no solved bits"; treat uniformly as empty so a site that has some
# unresolved DRIVE/SLEW entries still keeps the group (avoids KeyError) and
# the resolved siblings drive the enum-merge.
if parts[1].startswith('<'):
return frozenset()
else:
return frozenset(parts[1:])
def filter_negbits(site, feature, bits):
lvds_bits = frozenset(['!38_24', "!38_48", "!39_33", '!39_47', '!39_49'])
if "IOB_Y0" in feature and not "LVDS" in feature:
bits = bits.difference(lvds_bits)
if feature.endswith("IOB_Y0.LVCMOS12_LVCMOS15_LVCMOS18.IN"):
bits = bits.difference(frozenset(['!39_01']))
if feature.endswith("IOB_Y1.LVCMOS12_LVCMOS15_LVCMOS18.IN"):
bits = bits.difference(frozenset(['!38_126']))
return bits
def process_features_sets(iostandard_lines):
sites = {}
for iostd_type, iostd_list in iostandard_lines.items():
for iostd_line in iostd_list:
feature = get_name(iostd_line)
feature_parts = feature.split('.')
site = get_site(iostd_line)
iostandard = feature_parts[2]
bits = parse_bits(iostd_line)
key = (site, iostd_type)
if key not in sites:
sites[key] = {}
group = feature_parts[3]
if group not in sites[key]:
sites[key][group] = {}
if group in ['DRIVE', 'SLEW']:
enum = feature_parts[4]
sites[key][group][(iostandard, enum)] = bits
elif group in ['IN', 'IN_DIFF', 'IN_ONLY', 'IN_USE', 'OUT',
'STEPDOWN', 'ZIBUF_LOW_PWR']:
sites[key][group][(iostandard, None)] = bits
else:
assert False, group
for site in sites:
for iostandard, enum in sites[site]['DRIVE']:
sites[site]['DRIVE'][(iostandard, enum)] |= sites[site]['OUT'][(
iostandard, None)]
for iostandard, enum in sites[site]['IN']:
sites[site]['IN_ONLY'][(iostandard, enum)] -= sites[site]['IN'][(
iostandard, enum)]
common_bits = {}
for site, iostd_type in sites:
for group in sites[(site, iostd_type)]:
if (site, group) not in common_bits:
common_bits[(site, group)] = set()
for bits in sites[(site, iostd_type)][group].values():
common_bits[(site, group)] |= bits
slew_in_drives = {}
for site, iostd_type in sites:
common_bits[(site, 'IN')] |= common_bits[(site, 'IN_DIFF')]
common_bits[(site, 'IN_DIFF')] |= common_bits[(site, 'IN')]
# Only DIFF IOSTANDARDS such as LVDS or TMDS do not have DRIVE or SLEW features
if iostd_type == "NORMAL":
key = (site, iostd_type)
common_bits[(site, 'DRIVE')] -= common_bits[(site, 'SLEW')]
common_bits[(site, 'IN_ONLY')] |= common_bits[(site, 'DRIVE')]
for iostandard, enum in sites[key]['DRIVE']:
slew_in_drive = common_bits[
(site, 'SLEW')] & sites[key]['DRIVE'][(iostandard, enum)]
if slew_in_drive:
if (key, iostandard) not in slew_in_drives:
slew_in_drives[(key, iostandard)] = set()
slew_in_drives[(key, iostandard)] |= slew_in_drive
sites[key]['DRIVE'][(iostandard, enum)] -= slew_in_drive
for site, iostandard in slew_in_drives:
for _, enum in sites[site]['SLEW']:
sites[site]['SLEW'][(iostandard,
enum)] |= slew_in_drives[(site, iostandard)]
for site in sites:
for iostandard, enum in sites[site]['DRIVE']:
sites[site]['DRIVE'][(iostandard, enum)] |= sites[site]['IN_USE'][(
iostandard, None)]
for iostandard, enum in sites[site]['IN']:
_, iostd_type = site
if iostd_type == "ONLY_DIFF":
sites[site]['IN_DIFF'][(iostandard, enum)] = \
sites[site]['IN'][(iostandard, enum)]
elif sites[site]['IN_DIFF'][(iostandard, enum)]:
sites[site]['IN_DIFF'][(iostandard, enum)] |= \
sites[site]['IN'][(iostandard, enum)]
for site, iostd_type in sites:
if iostd_type == "NORMAL":
del sites[(site, iostd_type)]['OUT']
allow_zero = ['SLEW']
common_groups = dict()
for site, iostd_type in sites:
if site not in common_groups:
common_groups[site] = dict()
key = (site, iostd_type)
for group in sites[key]:
if iostd_type == "ONLY_DIFF" and group == "IN":
continue
# Merge features that are identical.
#
# For example:
#
# IOB18.IOB_Y1.LVCMOS15.IN 38_42 39_41
# IOB18.IOB_Y1.LVCMOS18.IN 38_42 39_41
#
# Must be grouped.
for (iostandard, enum), bits in sites[key][group].items():
if (bits, group) not in common_groups[site]:
common_groups[site][(bits, group)] = {
'IOSTANDARDS': set(),
'enums': set(),
}
common_groups[site][(bits,
group)]['IOSTANDARDS'].add(iostandard)
if enum is not None:
common_groups[site][(bits, group)]['enums'].add(enum)
# On Virtex-7 some Y1 IN groups differ from their Y0 counterparts by a
# single bit (e.g. LVCMOS* sets 39_01 while SSTL* does not), so the
# name-harmonisation below must not fold two distinct-bit groups onto one
# feature name -- doing so emits duplicate db lines that break dbfixup.
# Require identical bits before adopting a visited name for virtex7; other
# families never produce two-group Y1 IN splits, so they are unaffected.
require_same_bits = os.environ.get('XRAY_DATABASE') == 'virtex7'
visited_iostandards = list()
for site, groups in common_groups.items():
for (bits, group), v in groups.items():
iostandards = v['IOSTANDARDS']
enums = v['enums']
# It happens that some features appear only in one of the IOB sites and not
# in the other. This makes it hard to assign the correct features to the correct
# site in the P&R toolchain.
#
# The following code makes sure that the same set of iostandards
# (even if not really present at a site location) appears for each site
for visited_iostandard, visited_group, visited_enums, visited_bits in visited_iostandards:
same_enum = enums == visited_enums
same_group = group == visited_group
compatible_iostd = any(
x in iostandards for x in visited_iostandard)
take_visited_iostd = len(visited_iostandard) > len(iostandards)
same_bits = bits == visited_bits
if same_enum and same_group and compatible_iostd and take_visited_iostd \
and (same_bits or not require_same_bits):
iostandards = visited_iostandard
break
visited_iostandards.append((iostandards, group, enums, bits))
iostandards_string = '_'.join(sorted(iostandards))
if enums:
feature = 'IOB18.{site}.{iostandards}.{group}.{enums}'.format(
site=site,
iostandards=iostandards_string,
group=group,
enums='_'.join(sorted(enums)),
)
else:
feature = 'IOB18.{site}.{iostandards}.{group}'.format(
site=site,
iostandards=iostandards_string,
group=group,
)
if not bits and group not in allow_zero:
continue
neg_bits = frozenset(
'!{}'.format(b) for b in (common_bits[(site, group)] - bits))
neg_bits = filter_negbits(site, feature, neg_bits)
print('{} {}'.format(feature, ' '.join(sorted(bits | neg_bits))))
def main():
parser = argparse.ArgumentParser(
description="Convert IOB rdb into good rdb."
"")
parser.add_argument('input_rdb')
args = parser.parse_args()
iostandard_lines = {
"NORMAL": list(),
"ONLY_DIFF": list(),
}
with open(args.input_rdb) as f:
for l in f:
if ('.SSTL' in l or '.LVCMOS' in l
or '.LVTTL' in l) and 'IOB_' in l:
iostandard_lines["NORMAL"].append(l)
elif ('.TMDS' in l or 'LVDS' in l):
iostandard_lines["ONLY_DIFF"].append(l)
else:
print(l.strip())
process_features_sets(iostandard_lines)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,126 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2022 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
"""
SING-row IOB18 basic-config fuzzer design. For each IOB18 site that lives in a
*_SING tile, randomly instantiate OBUF / IBUF / nothing. The mix of driven,
input-only and unused sites gives segmaker the 0-reference it needs to resolve
the OUT / DRIVE / IN_USE bits (an all-output design leaves them const-1).
DRIVE / SLEW / PULLTYPE are applied to the ports by generate.tcl's loc_pins
from params.csv; the per-site type is recorded in params.jl for generate.py.
"""
import json
import os
import random
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray import verilog
from prjxray.db import Database
# HP banks: low-voltage standards only.
IOSTANDARDS = ['LVCMOS12', 'LVCMOS15', 'LVCMOS18']
PULLS = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"]
SLEWS = ['FAST', 'SLOW']
# OBUF (drive out), IBUF (input only) and unused, weighted toward variety.
TYPES = ['OBUF', 'OBUF', 'IBUF', 'IBUF', None, None]
def drives_for(iostandard):
if iostandard == 'LVCMOS12':
return [2, 4, 6, 8]
return [2, 4, 6, 8, 12, 16]
def gen_sites():
db = Database(util.get_db_root(), util.get_part())
grid = db.grid()
for tile_name in sorted(grid.tiles()):
gridinfo = grid.gridinfo_at_loc(grid.loc_of_tilename(tile_name))
if not gridinfo.tile_type.endswith("_SING"):
continue
for site_name, site_type in gridinfo.sites.items():
if site_type == 'IOB18':
yield tile_name, site_name
def main():
# One IOSTANDARD per specimen: all SING IOBs share it so a bank never sees
# conflicting VCCO (DRC BIVC-1). Variety across the N specimens gives
# process_rdb the LVCMOS12/15/18 set it merges into the DRIVE enum names.
iostandard = random.choice(IOSTANDARDS)
params = []
for tile, site in gen_sites():
params.append(
{
'tile': tile,
'site': site,
'type': random.choice(TYPES),
'IOSTANDARD': verilog.quote(iostandard),
'DRIVE': random.choice(drives_for(iostandard)),
'SLEW': verilog.quote(random.choice(SLEWS)),
'PULLTYPE': verilog.quote(random.choice(PULLS)),
})
# params.csv for generate.tcl's loc_pins (tile,site,pin,iostd,drive,slew,pull)
lines = ['tile,site,pin,iostandard,drive,slew,pulltype']
n_in = n_out = 0
for p in params:
if p['type'] == 'OBUF':
p['pin'] = 'do[{}]'.format(n_out)
n_out += 1
elif p['type'] == 'IBUF':
p['pin'] = 'di[{}]'.format(n_in)
n_in += 1
else:
p['pin'] = None
continue
lines.append(
','.join(
map(
str, (
p['tile'], p['site'], p['pin'],
verilog.unquote(p['IOSTANDARD']), p['DRIVE'],
verilog.unquote(p['SLEW']),
verilog.unquote(p['PULLTYPE'])))))
open('params.csv', 'w').write('\n'.join(lines) + '\n')
with open('params.jl', 'w') as f:
json.dump(params, f, indent=2)
# Verilog: one OBUF / IBUF per used site, LOC'd; unused sites get nothing.
# OBUFs are driven by a DONT_TOUCH LUT source (no external clock port, which
# would be an unplaceable terminal); DRIVE/SLEW/PULLTYPE come from loc_pins.
print('module top(output wire [{no}:0] do, input wire [{ni}:0] di);'.format(
no=max(n_out - 1, 0), ni=max(n_in - 1, 0)))
print(' wire src;')
print(' (* KEEP, DONT_TOUCH *) '
'LUT6 #(.INIT(64\'hAAAAAAAAAAAAAAAA)) srclut '
'(.O(src), .I0(1\'b0), .I1(1\'b0), .I2(1\'b0), '
'.I3(1\'b0), .I4(1\'b0), .I5(1\'b0));')
for idx, p in enumerate(params):
if p['type'] == 'OBUF':
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
OBUF obuf_{idx} (.I(src), .O({pin}));'''.format(
site=p['site'], idx=idx, pin=p['pin']))
elif p['type'] == 'IBUF':
print(
'''
wire ib_{idx};
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
IBUF ibuf_{idx} (.I({pin}), .O(ib_{idx}));'''.format(
site=p['site'], idx=idx, pin=p['pin']))
print('endmodule')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,42 @@
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
#
# IOB18 (HP-bank) ILOGIC fuzzer for Virtex-7. The kintex7 035-iob-ilogic
# fuzzer targets IOB33/HR sites that do not exist on this part, so its LIOI/
# RIOI results were transplanted. This variant places ISERDESE2/IDDR on real
# IOB18 sites on BOTH the L and R columns and measures the ILOGIC config bits
# (incl. ZINV_D) directly.
N := 30
include ../fuzzer.mk
database: build/segbits_iob18_ilogic.db
build/segbits_iob18_ilogic.rdb: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -c 6 -o build/segbits_iob18_ilogic.rdb2 $$(find -name segdata_*.txt)
# ISERDES features belong to 035b-iob18-iserdes; DYN_* are solved there too.
grep -v ".ISERDES." build/segbits_iob18_ilogic.rdb2 | grep -v "DYN_" >$@
build/segbits_iob18_ilogic.db: build/segbits_iob18_ilogic.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --groups tag_groups.txt --seg-fn-in $^ --seg-fn-out $@
${XRAY_MASKMERGE} build/mask_iob18_ilogic.db $$(find -name segdata_*.txt)
pushdb:
${XRAY_MERGEDB} lioi build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} lioi_tbytesrc build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} lioi_tbyteterm build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} rioi build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} rioi_tbytesrc build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} rioi_tbyteterm build/segbits_iob18_ilogic.db
${XRAY_MERGEDB} mask_lioi build/mask_iob18_ilogic.db
${XRAY_MERGEDB} mask_lioi_tbytesrc build/mask_iob18_ilogic.db
${XRAY_MERGEDB} mask_lioi_tbyteterm build/mask_iob18_ilogic.db
${XRAY_MERGEDB} mask_rioi build/mask_iob18_ilogic.db
${XRAY_MERGEDB} mask_rioi_tbytesrc build/mask_iob18_ilogic.db
${XRAY_MERGEDB} mask_rioi_tbyteterm build/mask_iob18_ilogic.db
.PHONY: database pushdb

View File

View File

@ -0,0 +1,259 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
from prjxray.segmaker import Segmaker
from prjxray import verilog
import json
# Set to true to enable additional tags useful for tracing bit toggles.
DEBUG_FUZZER = False
def bitfilter(frame, word):
if frame < 25 or frame > 31:
return False
return True
def handle_data_width(segmk, d):
if 'DATA_WIDTH' not in d:
return
site = d['ilogic_loc']
# It appears several widths end up with the same bitstream pattern.
# This groups those widths together for documentation.
widths = [
[2],
[3],
[4, 6],
[5, 7],
[8],
[10],
[14],
]
width_map = {}
for ws in widths:
for w in ws:
width_map[w] = 'W{}'.format('_'.join(map(str, ws)))
zero_opt = 2
W_OPT_ZERO = width_map[zero_opt]
if d['DATA_WIDTH'] == zero_opt:
segmk.add_site_tag(site, 'ISERDES.DATA_WIDTH.{}'.format(W_OPT_ZERO), 1)
for opt in width_map.values():
if opt == W_OPT_ZERO:
continue
segmk.add_site_tag(site, 'ISERDES.DATA_WIDTH.{}'.format(opt), 0)
else:
w_opt = width_map[d['DATA_WIDTH']]
if w_opt != W_OPT_ZERO:
segmk.add_site_tag(
site, 'ISERDES.DATA_WIDTH.{}'.format(W_OPT_ZERO), 0)
segmk.add_site_tag(site, 'ISERDES.DATA_WIDTH.{}'.format(w_opt), 1)
def handle_data_rate(segmk, d):
if 'DATA_WIDTH' not in d:
return
site = d['ilogic_loc']
for opt in ['SDR', 'DDR']:
segmk.add_site_tag(
site, 'ISERDES.DATA_RATE.{}'.format(opt),
verilog.unquote(d['DATA_RATE']) == opt)
def main():
print("Loading tags")
segmk = Segmaker("design.bits")
with open('params.jl', 'r') as f:
design = json.load(f)
for d in design:
site = d['ilogic_loc']
handle_data_width(segmk, d)
handle_data_rate(segmk, d)
segmk.add_site_tag(site, 'ISERDES.IN_USE', d['use_iserdese2'])
if 'NUM_CE' in d:
segmk.add_site_tag(site, 'ISERDES.NUM_CE.N2', d['NUM_CE'] == 2)
segmk.add_site_tag(
site, 'IDDR_OR_ISERDES.IN_USE', d['use_iserdese2']
or d['iddr_mux_config'] != 'none')
if 'INTERFACE_TYPE' in d:
for opt in (
'MEMORY',
'MEMORY_DDR3',
'MEMORY_QDR',
'NETWORKING',
'OVERSAMPLE',
):
segmk.add_site_tag(
site, 'ISERDES.INTERFACE_TYPE.{}'.format(opt),
opt == verilog.unquote(d['INTERFACE_TYPE']))
segmk.add_site_tag(
site, 'ISERDES.INTERFACE_TYPE.Z_{}'.format(opt),
opt != verilog.unquote(d['INTERFACE_TYPE']))
segmk.add_site_tag(
site, 'ISERDES.INTERFACE_TYPE.NOT_MEMORY',
'MEMORY' not in verilog.unquote(d['INTERFACE_TYPE']))
if d['iddr_mux_config'] != 'none':
segmk.add_site_tag(site, 'IFF.ZINIT_Q1', not d['INIT_Q1'])
segmk.add_site_tag(site, 'IFF.ZINIT_Q2', not d['INIT_Q2'])
if 'DYN_CLKDIV_INV_EN' in d:
segmk.add_site_tag(
site, 'DYN_CLKDIV_INV_EN',
verilog.unquote(d['DYN_CLKDIV_INV_EN']) == 'TRUE')
if 'DYN_CLK_INV_EN' in d:
segmk.add_site_tag(
site, 'DYN_CLK_INV_EN',
verilog.unquote(d['DYN_CLK_INV_EN']) == 'TRUE')
if 'INIT_Q3' in d:
segmk.add_site_tag(site, 'IFF.ZINIT_Q3', not d['INIT_Q3'])
segmk.add_site_tag(site, 'IFF.ZINIT_Q4', not d['INIT_Q4'])
segmk.add_site_tag(
site, 'IFF.ZSRVAL_Q1', not d['SRVAL_Q1'])
segmk.add_site_tag(
site, 'IFF.ZSRVAL_Q2', not d['SRVAL_Q2'])
segmk.add_site_tag(
site, 'IFF.ZSRVAL_Q3', not d['SRVAL_Q3'])
segmk.add_site_tag(
site, 'IFF.ZSRVAL_Q4', not d['SRVAL_Q4'])
if 'IS_CLK_INVERTED' in d and not d['DISABLE_CLOCKS']:
if verilog.unquote(d['INTERFACE_TYPE']) == 'MEMORY_DDR3':
segmk.add_site_tag(
site, 'IFF.INV_CLK', d['IS_CLK_INVERTED'])
segmk.add_site_tag(
site, 'IFF.INV_CLKB', d['IS_CLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLK', not d['IS_CLK_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLKB', not d['IS_CLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_XOR',
d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_NXOR',
not (d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED']))
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_OR', d['IS_CLK_INVERTED']
or d['IS_CLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_NOR', not (
d['IS_CLK_INVERTED'] or d['IS_CLKB_INVERTED']))
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_AND', d['IS_CLK_INVERTED']
and d['IS_CLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLK_NAND', not (
d['IS_CLK_INVERTED']
and d['IS_CLKB_INVERTED']))
if 'IS_OCLK_INVERTED' in d and not d['DISABLE_CLOCKS']:
segmk.add_site_tag(
site, 'IFF.INV_OCLK', d['IS_OCLK_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_OCLK', not d['IS_OCLK_INVERTED'])
segmk.add_site_tag(
site, 'IFF.INV_OCLKB', d['IS_OCLKB_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_OCLKB', not d['IS_OCLKB_INVERTED'])
if 'IS_CLKDIV_INVERTED' in d and not d['DISABLE_CLOCKS'] and \
verilog.unquote(d['INTERFACE_TYPE']) == 'MEMORY':
segmk.add_site_tag(
site, 'IFF.INV_CLKDIV', d['IS_CLKDIV_INVERTED'])
segmk.add_site_tag(
site, 'IFF.ZINV_CLKDIV', not d['IS_CLKDIV_INVERTED'])
if 'IS_C_INVERTED' in d:
segmk.add_site_tag(
site, 'IFF.ZINV_C', not d['IS_C_INVERTED'])
segmk.add_site_tag(site, 'ZINV_D', not d['IS_D_INVERTED'])
if 'SRTYPE' in d:
for opt in ['ASYNC', 'SYNC']:
segmk.add_site_tag(
site, 'IFF.SRTYPE.{}'.format(opt),
verilog.unquote(d['SRTYPE']) == opt)
if 'DDR_CLK_EDGE' in d:
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE',
'SAME_EDGE_PIPELINED']:
segmk.add_site_tag(
site, 'IFF.DDR_CLK_EDGE.{}'.format(opt),
verilog.unquote(d['DDR_CLK_EDGE']) == opt)
if d['iddr_mux_config'] == 'direct':
segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 0)
segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 1)
segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0)
elif d['iddr_mux_config'] == 'idelay':
segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 1)
segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 0)
segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0)
elif d['iddr_mux_config'] == 'none':
segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 0)
segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 0)
segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0)
else:
assert False, d['mux_config']
if d['mux_config'] == 'direct':
segmk.add_site_tag(site, 'IDELMUXE3.P0', 0)
segmk.add_site_tag(site, 'IDELMUXE3.P1', 1)
segmk.add_site_tag(site, 'IDELMUXE3.P2', 0)
elif d['mux_config'] == 'idelay':
segmk.add_site_tag(site, 'IDELMUXE3.P0', 1)
segmk.add_site_tag(site, 'IDELMUXE3.P1', 0)
segmk.add_site_tag(site, 'IDELMUXE3.P2', 0)
elif d['mux_config'] == 'none':
segmk.add_site_tag(site, 'IDELMUXE3.P0', 0)
segmk.add_site_tag(site, 'IDELMUXE3.P1', 0)
segmk.add_site_tag(site, 'IDELMUXE3.P2', 0)
else:
assert False, d['mux_config']
if DEBUG_FUZZER:
for k in d:
segmk.add_site_tag(
site, 'param_' + k + '_' + str(d[k]).replace(
' ', '').replace('\n', ''), 1)
segmk.compile(bitfilter=bitfilter)
segmk.write(allow_empty=True)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,39 @@
# Copyright (C) 2017-2022 The Project X-Ray Authors
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
create_project -force -part $::env(XRAY_PART) design design
read_verilog top.v
synth_design -top top
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_param tcl.collectionResultDisplayLimit 0
set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}]
set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-81}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-84}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-85}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-87}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-85}]
set_property IS_ENABLED 0 [get_drc_checks {AVAL-28}]
# ISERDES/ILOGIC fuzzer deliberately builds "invalid" clocking and D-inversion
# mux configs to observe their bits; suppress the DRCs that would block bitgen.
set_property IS_ENABLED 0 [get_drc_checks {REQP-105}]
set_property IS_ENABLED 0 [get_drc_checks {PDRC-26}]
set_property IS_ENABLED 0 [get_drc_checks {PDRC-158}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1580}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1581}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1582}]
place_design
route_design
write_checkpoint -force design.dcp
write_bitstream -force design.bit

View File

@ -0,0 +1,672 @@
tile,site,pin,iostandard,drive,slew
LIOB18_X81Y10,IOB_X0Y10,dio[0],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y101,IOB_X0Y97,dio[1],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y101,IOB_X0Y98,dio[2],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y106,IOB_X0Y101,dio[3],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y106,IOB_X0Y102,dio[4],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y108,IOB_X0Y103,dio[5],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y108,IOB_X0Y104,dio[6],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y110,IOB_X0Y105,dio[7],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y110,IOB_X0Y106,dio[8],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y112,IOB_X0Y107,dio[9],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y112,IOB_X0Y108,dio[10],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y114,IOB_X0Y109,dio[11],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y114,IOB_X0Y110,dio[12],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y116,IOB_X0Y111,dio[13],LVCMOS18,8,FAST,NONE
LIOB18_X81Y116,IOB_X0Y112,dio[14],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y118,IOB_X0Y113,dio[15],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y118,IOB_X0Y114,dio[16],LVCMOS18,6,FAST,NONE
LIOB18_X81Y12,IOB_X0Y11,dio[17],LVCMOS18,6,FAST,NONE
LIOB18_X81Y12,IOB_X0Y12,dio[18],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y120,IOB_X0Y115,dio[19],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y120,IOB_X0Y116,dio[20],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y122,IOB_X0Y117,dio[21],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y122,IOB_X0Y118,dio[22],LVCMOS18,2,FAST,NONE
LIOB18_X81Y124,IOB_X0Y119,dio[23],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y124,IOB_X0Y120,dio[24],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y126,IOB_X0Y121,dio[25],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y126,IOB_X0Y122,dio[26],LVCMOS18,2,SLOW,PULLUP
LIOB18_X81Y128,IOB_X0Y123,dio[27],LVCMOS18,2,FAST,NONE
LIOB18_X81Y128,IOB_X0Y124,dio[28],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y131,IOB_X0Y125,dio[29],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y131,IOB_X0Y126,dio[30],LVCMOS18,2,SLOW,PULLUP
LIOB18_X81Y133,IOB_X0Y127,dio[31],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y133,IOB_X0Y128,dio[32],LVCMOS18,16,FAST,NONE
LIOB18_X81Y135,IOB_X0Y129,dio[33],LVCMOS18,4,FAST,NONE
LIOB18_X81Y135,IOB_X0Y130,dio[34],LVCMOS18,4,FAST,NONE
LIOB18_X81Y137,IOB_X0Y131,dio[35],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y137,IOB_X0Y132,dio[36],LVCMOS18,4,FAST,NONE
LIOB18_X81Y139,IOB_X0Y133,dio[37],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y139,IOB_X0Y134,dio[38],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y14,IOB_X0Y13,dio[39],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y14,IOB_X0Y14,dio[40],LVCMOS18,4,FAST,KEEPER
LIOB18_X81Y141,IOB_X0Y135,dio[41],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y141,IOB_X0Y136,dio[42],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y143,IOB_X0Y137,dio[43],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y143,IOB_X0Y138,dio[44],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y145,IOB_X0Y139,dio[45],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y145,IOB_X0Y140,dio[46],LVCMOS18,2,FAST,NONE
LIOB18_X81Y147,IOB_X0Y141,dio[47],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y147,IOB_X0Y142,dio[48],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y149,IOB_X0Y143,dio[49],LVCMOS18,16,FAST,PULLDOWN
LIOB18_X81Y149,IOB_X0Y144,dio[50],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y151,IOB_X0Y145,dio[51],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y151,IOB_X0Y146,dio[52],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y153,IOB_X0Y147,dio[53],LVCMOS18,4,FAST,KEEPER
LIOB18_X81Y153,IOB_X0Y148,dio[54],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y158,IOB_X0Y151,dio[55],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y158,IOB_X0Y152,dio[56],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y16,IOB_X0Y15,dio[57],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y16,IOB_X0Y16,dio[58],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y160,IOB_X0Y153,dio[59],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y160,IOB_X0Y154,dio[60],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y162,IOB_X0Y155,dio[61],LVCMOS18,4,FAST,NONE
LIOB18_X81Y162,IOB_X0Y156,dio[62],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y164,IOB_X0Y157,dio[63],LVCMOS18,4,FAST,NONE
LIOB18_X81Y164,IOB_X0Y158,dio[64],LVCMOS18,2,FAST,PULLDOWN
LIOB18_X81Y166,IOB_X0Y159,dio[65],LVCMOS18,4,FAST,NONE
LIOB18_X81Y166,IOB_X0Y160,dio[66],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y168,IOB_X0Y161,dio[67],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y168,IOB_X0Y162,dio[68],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y170,IOB_X0Y163,dio[69],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y170,IOB_X0Y164,dio[70],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y172,IOB_X0Y165,dio[71],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y172,IOB_X0Y166,dio[72],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y174,IOB_X0Y167,dio[73],LVCMOS18,8,FAST,PULLDOWN
LIOB18_X81Y174,IOB_X0Y168,dio[74],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y176,IOB_X0Y169,dio[75],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y176,IOB_X0Y170,dio[76],LVCMOS18,4,FAST,NONE
LIOB18_X81Y178,IOB_X0Y171,dio[77],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y178,IOB_X0Y172,dio[78],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y18,IOB_X0Y17,dio[79],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y18,IOB_X0Y18,dio[80],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y180,IOB_X0Y173,dio[81],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y180,IOB_X0Y174,dio[82],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y183,IOB_X0Y175,dio[83],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y183,IOB_X0Y176,dio[84],LVCMOS18,8,FAST,PULLDOWN
LIOB18_X81Y185,IOB_X0Y177,dio[85],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y185,IOB_X0Y178,dio[86],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y187,IOB_X0Y179,dio[87],LVCMOS18,8,FAST,NONE
LIOB18_X81Y187,IOB_X0Y180,dio[88],LVCMOS18,16,SLOW,KEEPER
LIOB18_X81Y189,IOB_X0Y181,dio[89],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y189,IOB_X0Y182,dio[90],LVCMOS18,6,FAST,NONE
LIOB18_X81Y191,IOB_X0Y183,dio[91],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y191,IOB_X0Y184,dio[92],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y193,IOB_X0Y185,dio[93],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y193,IOB_X0Y186,dio[94],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y195,IOB_X0Y187,dio[95],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y195,IOB_X0Y188,dio[96],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y197,IOB_X0Y189,dio[97],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y197,IOB_X0Y190,dio[98],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y199,IOB_X0Y191,dio[99],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y199,IOB_X0Y192,dio[100],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y2,IOB_X0Y1,dio[101],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y2,IOB_X0Y2,dio[102],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y20,IOB_X0Y19,dio[103],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y20,IOB_X0Y20,dio[104],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y201,IOB_X0Y193,dio[105],LVCMOS18,6,FAST,NONE
LIOB18_X81Y201,IOB_X0Y194,dio[106],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y203,IOB_X0Y195,dio[107],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y203,IOB_X0Y196,dio[108],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y205,IOB_X0Y197,dio[109],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y205,IOB_X0Y198,dio[110],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y210,IOB_X0Y201,dio[111],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y210,IOB_X0Y202,dio[112],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y212,IOB_X0Y203,dio[113],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y212,IOB_X0Y204,dio[114],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y214,IOB_X0Y205,dio[115],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y214,IOB_X0Y206,dio[116],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y216,IOB_X0Y207,dio[117],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y216,IOB_X0Y208,dio[118],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y218,IOB_X0Y209,dio[119],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y218,IOB_X0Y210,dio[120],LVCMOS18,4,SLOW,PULLUP
LIOB18_X81Y22,IOB_X0Y21,dio[121],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y22,IOB_X0Y22,dio[122],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y220,IOB_X0Y211,dio[123],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y220,IOB_X0Y212,dio[124],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y222,IOB_X0Y213,dio[125],LVCMOS18,12,FAST,PULLDOWN
LIOB18_X81Y222,IOB_X0Y214,dio[126],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y224,IOB_X0Y215,dio[127],LVCMOS18,4,SLOW,PULLUP
LIOB18_X81Y224,IOB_X0Y216,dio[128],LVCMOS18,6,FAST,NONE
LIOB18_X81Y226,IOB_X0Y217,dio[129],LVCMOS18,8,FAST,PULLDOWN
LIOB18_X81Y226,IOB_X0Y218,dio[130],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y228,IOB_X0Y219,dio[131],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y228,IOB_X0Y220,dio[132],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y230,IOB_X0Y221,dio[133],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y230,IOB_X0Y222,dio[134],LVCMOS18,16,FAST,PULLDOWN
LIOB18_X81Y232,IOB_X0Y223,dio[135],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y232,IOB_X0Y224,dio[136],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y235,IOB_X0Y225,dio[137],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y235,IOB_X0Y226,dio[138],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y237,IOB_X0Y227,dio[139],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y237,IOB_X0Y228,dio[140],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y239,IOB_X0Y229,dio[141],LVCMOS18,12,FAST,PULLDOWN
LIOB18_X81Y239,IOB_X0Y230,dio[142],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y24,IOB_X0Y23,dio[143],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y24,IOB_X0Y24,dio[144],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y241,IOB_X0Y231,dio[145],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y241,IOB_X0Y232,dio[146],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y243,IOB_X0Y233,dio[147],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y243,IOB_X0Y234,dio[148],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y245,IOB_X0Y235,dio[149],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y245,IOB_X0Y236,dio[150],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y247,IOB_X0Y237,dio[151],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y247,IOB_X0Y238,dio[152],LVCMOS18,2,FAST,PULLDOWN
LIOB18_X81Y249,IOB_X0Y239,dio[153],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y249,IOB_X0Y240,dio[154],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y251,IOB_X0Y241,dio[155],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y251,IOB_X0Y242,dio[156],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y253,IOB_X0Y243,dio[157],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y253,IOB_X0Y244,dio[158],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y255,IOB_X0Y245,dio[159],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y255,IOB_X0Y246,dio[160],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y257,IOB_X0Y247,dio[161],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y257,IOB_X0Y248,dio[162],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y262,IOB_X0Y251,dio[163],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y262,IOB_X0Y252,dio[164],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y264,IOB_X0Y253,dio[165],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y264,IOB_X0Y254,dio[166],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y266,IOB_X0Y255,dio[167],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y266,IOB_X0Y256,dio[168],LVCMOS18,4,SLOW,PULLUP
LIOB18_X81Y268,IOB_X0Y257,dio[169],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y268,IOB_X0Y258,dio[170],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y27,IOB_X0Y25,dio[171],LVCMOS18,8,FAST,NONE
LIOB18_X81Y27,IOB_X0Y26,dio[172],LVCMOS18,8,FAST,NONE
LIOB18_X81Y270,IOB_X0Y259,dio[173],LVCMOS18,12,FAST,NONE
LIOB18_X81Y270,IOB_X0Y260,dio[174],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y272,IOB_X0Y261,dio[175],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y272,IOB_X0Y262,dio[176],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y274,IOB_X0Y263,dio[177],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y274,IOB_X0Y264,dio[178],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y276,IOB_X0Y265,dio[179],LVCMOS18,2,FAST,KEEPER
LIOB18_X81Y276,IOB_X0Y266,dio[180],LVCMOS18,6,FAST,NONE
LIOB18_X81Y278,IOB_X0Y267,dio[181],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y278,IOB_X0Y268,dio[182],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y280,IOB_X0Y269,dio[183],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y280,IOB_X0Y270,dio[184],LVCMOS18,12,FAST,PULLDOWN
LIOB18_X81Y282,IOB_X0Y271,dio[185],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y282,IOB_X0Y272,dio[186],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y284,IOB_X0Y273,dio[187],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y284,IOB_X0Y274,dio[188],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y287,IOB_X0Y275,dio[189],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y287,IOB_X0Y276,dio[190],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y289,IOB_X0Y277,dio[191],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y289,IOB_X0Y278,dio[192],LVCMOS18,2,FAST,PULLDOWN
LIOB18_X81Y29,IOB_X0Y27,dio[193],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y29,IOB_X0Y28,dio[194],LVCMOS18,16,FAST,NONE
LIOB18_X81Y291,IOB_X0Y279,dio[195],LVCMOS18,2,FAST,NONE
LIOB18_X81Y291,IOB_X0Y280,dio[196],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y293,IOB_X0Y281,dio[197],LVCMOS18,8,FAST,NONE
LIOB18_X81Y293,IOB_X0Y282,dio[198],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y295,IOB_X0Y283,dio[199],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y295,IOB_X0Y284,dio[200],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y297,IOB_X0Y285,dio[201],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y297,IOB_X0Y286,dio[202],LVCMOS18,2,FAST,NONE
LIOB18_X81Y299,IOB_X0Y287,dio[203],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y299,IOB_X0Y288,dio[204],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y301,IOB_X0Y289,dio[205],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y301,IOB_X0Y290,dio[206],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y303,IOB_X0Y291,dio[207],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y303,IOB_X0Y292,dio[208],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y305,IOB_X0Y293,dio[209],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y305,IOB_X0Y294,dio[210],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y307,IOB_X0Y295,dio[211],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y307,IOB_X0Y296,dio[212],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y309,IOB_X0Y297,dio[213],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y309,IOB_X0Y298,dio[214],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y31,IOB_X0Y29,dio[215],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y31,IOB_X0Y30,dio[216],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y314,IOB_X0Y301,dio[217],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y314,IOB_X0Y302,dio[218],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y316,IOB_X0Y303,dio[219],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y316,IOB_X0Y304,dio[220],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y318,IOB_X0Y305,dio[221],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y318,IOB_X0Y306,dio[222],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y320,IOB_X0Y307,dio[223],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y320,IOB_X0Y308,dio[224],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y322,IOB_X0Y309,dio[225],LVCMOS18,12,FAST,NONE
LIOB18_X81Y322,IOB_X0Y310,dio[226],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y324,IOB_X0Y311,dio[227],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y324,IOB_X0Y312,dio[228],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y326,IOB_X0Y313,dio[229],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y326,IOB_X0Y314,dio[230],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y328,IOB_X0Y315,dio[231],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y328,IOB_X0Y316,dio[232],LVCMOS18,6,FAST,NONE
LIOB18_X81Y33,IOB_X0Y31,dio[233],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y33,IOB_X0Y32,dio[234],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y330,IOB_X0Y317,dio[235],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y330,IOB_X0Y318,dio[236],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y332,IOB_X0Y319,dio[237],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y332,IOB_X0Y320,dio[238],LVCMOS18,16,FAST,PULLDOWN
LIOB18_X81Y334,IOB_X0Y321,dio[239],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y334,IOB_X0Y322,dio[240],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y336,IOB_X0Y323,dio[241],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y336,IOB_X0Y324,dio[242],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y339,IOB_X0Y325,dio[243],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y339,IOB_X0Y326,dio[244],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y341,IOB_X0Y327,dio[245],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y341,IOB_X0Y328,dio[246],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y343,IOB_X0Y329,dio[247],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y343,IOB_X0Y330,dio[248],LVCMOS18,2,FAST,NONE
LIOB18_X81Y345,IOB_X0Y331,dio[249],LVCMOS18,16,FAST,NONE
LIOB18_X81Y345,IOB_X0Y332,dio[250],LVCMOS18,12,FAST,NONE
LIOB18_X81Y347,IOB_X0Y333,dio[251],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y347,IOB_X0Y334,dio[252],LVCMOS18,4,FAST,NONE
LIOB18_X81Y349,IOB_X0Y335,dio[253],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y349,IOB_X0Y336,dio[254],LVCMOS18,16,SLOW,KEEPER
LIOB18_X81Y35,IOB_X0Y33,dio[255],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y35,IOB_X0Y34,dio[256],LVCMOS18,12,FAST,PULLDOWN
LIOB18_X81Y351,IOB_X0Y337,dio[257],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y351,IOB_X0Y338,dio[258],LVCMOS18,12,FAST,NONE
LIOB18_X81Y353,IOB_X0Y339,dio[259],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y353,IOB_X0Y340,dio[260],LVCMOS18,16,FAST,NONE
LIOB18_X81Y355,IOB_X0Y341,dio[261],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y355,IOB_X0Y342,dio[262],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y357,IOB_X0Y343,dio[263],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y357,IOB_X0Y344,dio[264],LVCMOS18,6,SLOW,PULLDOWN
LIOB18_X81Y359,IOB_X0Y345,dio[265],LVCMOS18,12,SLOW,PULLDOWN
LIOB18_X81Y359,IOB_X0Y346,dio[266],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y361,IOB_X0Y347,dio[267],LVCMOS18,12,FAST,PULLDOWN
LIOB18_X81Y361,IOB_X0Y348,dio[268],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y37,IOB_X0Y35,dio[269],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y37,IOB_X0Y36,dio[270],LVCMOS18,2,FAST,NONE
LIOB18_X81Y39,IOB_X0Y37,dio[271],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y39,IOB_X0Y38,dio[272],LVCMOS18,16,FAST,KEEPER
LIOB18_X81Y4,IOB_X0Y3,dio[273],LVCMOS18,16,SLOW,KEEPER
LIOB18_X81Y4,IOB_X0Y4,dio[274],LVCMOS18,8,FAST,PULLUP
LIOB18_X81Y41,IOB_X0Y39,dio[275],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y41,IOB_X0Y40,dio[276],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y43,IOB_X0Y41,dio[277],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y43,IOB_X0Y42,dio[278],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y45,IOB_X0Y43,dio[279],LVCMOS18,16,SLOW,KEEPER
LIOB18_X81Y45,IOB_X0Y44,dio[280],LVCMOS18,16,SLOW,NONE
LIOB18_X81Y47,IOB_X0Y45,dio[281],LVCMOS18,4,FAST,KEEPER
LIOB18_X81Y47,IOB_X0Y46,dio[282],LVCMOS18,4,FAST,NONE
LIOB18_X81Y49,IOB_X0Y47,dio[283],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y49,IOB_X0Y48,dio[284],LVCMOS18,8,FAST,KEEPER
LIOB18_X81Y54,IOB_X0Y51,dio[285],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y54,IOB_X0Y52,dio[286],LVCMOS18,2,SLOW,PULLDOWN
LIOB18_X81Y56,IOB_X0Y53,dio[287],LVCMOS18,16,FAST,NONE
LIOB18_X81Y56,IOB_X0Y54,dio[288],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y58,IOB_X0Y55,dio[289],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y58,IOB_X0Y56,dio[290],LVCMOS18,8,FAST,PULLDOWN
LIOB18_X81Y6,IOB_X0Y5,dio[291],LVCMOS18,8,SLOW,KEEPER
LIOB18_X81Y6,IOB_X0Y6,dio[292],LVCMOS18,6,SLOW,PULLUP
LIOB18_X81Y60,IOB_X0Y57,dio[293],LVCMOS18,16,FAST,PULLDOWN
LIOB18_X81Y60,IOB_X0Y58,dio[294],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y62,IOB_X0Y59,dio[295],LVCMOS18,6,FAST,KEEPER
LIOB18_X81Y62,IOB_X0Y60,dio[296],LVCMOS18,6,FAST,PULLDOWN
LIOB18_X81Y64,IOB_X0Y61,dio[297],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y64,IOB_X0Y62,dio[298],LVCMOS18,2,SLOW,NONE
LIOB18_X81Y66,IOB_X0Y63,dio[299],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y66,IOB_X0Y64,dio[300],LVCMOS18,16,SLOW,PULLUP
LIOB18_X81Y68,IOB_X0Y65,dio[301],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y68,IOB_X0Y66,dio[302],LVCMOS18,4,FAST,KEEPER
LIOB18_X81Y70,IOB_X0Y67,dio[303],LVCMOS18,2,FAST,PULLUP
LIOB18_X81Y70,IOB_X0Y68,dio[304],LVCMOS18,4,SLOW,NONE
LIOB18_X81Y72,IOB_X0Y69,dio[305],LVCMOS18,4,SLOW,KEEPER
LIOB18_X81Y72,IOB_X0Y70,dio[306],LVCMOS18,8,SLOW,PULLDOWN
LIOB18_X81Y74,IOB_X0Y71,dio[307],LVCMOS18,2,FAST,PULLDOWN
LIOB18_X81Y74,IOB_X0Y72,dio[308],LVCMOS18,6,SLOW,NONE
LIOB18_X81Y76,IOB_X0Y73,dio[309],LVCMOS18,8,SLOW,NONE
LIOB18_X81Y76,IOB_X0Y74,dio[310],LVCMOS18,12,FAST,KEEPER
LIOB18_X81Y79,IOB_X0Y75,dio[311],LVCMOS18,2,SLOW,KEEPER
LIOB18_X81Y79,IOB_X0Y76,dio[312],LVCMOS18,12,SLOW,NONE
LIOB18_X81Y8,IOB_X0Y7,dio[313],LVCMOS18,4,SLOW,PULLDOWN
LIOB18_X81Y8,IOB_X0Y8,dio[314],LVCMOS18,12,FAST,NONE
LIOB18_X81Y81,IOB_X0Y77,dio[315],LVCMOS18,12,SLOW,KEEPER
LIOB18_X81Y81,IOB_X0Y78,dio[316],LVCMOS18,2,FAST,NONE
LIOB18_X81Y83,IOB_X0Y79,dio[317],LVCMOS18,16,FAST,NONE
LIOB18_X81Y83,IOB_X0Y80,dio[318],LVCMOS18,16,SLOW,PULLDOWN
LIOB18_X81Y85,IOB_X0Y81,dio[319],LVCMOS18,4,SLOW,PULLDOWN
LIOB18_X81Y85,IOB_X0Y82,dio[320],LVCMOS18,4,FAST,PULLDOWN
LIOB18_X81Y87,IOB_X0Y83,dio[321],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y87,IOB_X0Y84,dio[322],LVCMOS18,6,FAST,NONE
LIOB18_X81Y89,IOB_X0Y85,dio[323],LVCMOS18,16,FAST,PULLDOWN
LIOB18_X81Y89,IOB_X0Y86,dio[324],LVCMOS18,16,SLOW,KEEPER
LIOB18_X81Y91,IOB_X0Y87,dio[325],LVCMOS18,6,SLOW,KEEPER
LIOB18_X81Y91,IOB_X0Y88,dio[326],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y93,IOB_X0Y89,dio[327],LVCMOS18,8,SLOW,PULLUP
LIOB18_X81Y93,IOB_X0Y90,dio[328],LVCMOS18,16,FAST,NONE
LIOB18_X81Y95,IOB_X0Y91,dio[329],LVCMOS18,12,FAST,PULLUP
LIOB18_X81Y95,IOB_X0Y92,dio[330],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y97,IOB_X0Y93,dio[331],LVCMOS18,16,FAST,PULLUP
LIOB18_X81Y97,IOB_X0Y94,dio[332],LVCMOS18,12,SLOW,PULLUP
LIOB18_X81Y99,IOB_X0Y95,dio[333],LVCMOS18,6,FAST,PULLUP
LIOB18_X81Y99,IOB_X0Y96,dio[334],LVCMOS18,4,FAST,NONE
RIOB18_X312Y10,IOB_X1Y9,dio[335],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y10,IOB_X1Y10,dio[336],LVCMOS18,2,FAST,PULLUP
RIOB18_X312Y101,IOB_X1Y97,dio[337],LVCMOS18,4,FAST,PULLUP
RIOB18_X312Y101,IOB_X1Y98,dio[338],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y106,IOB_X1Y101,dio[339],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y106,IOB_X1Y102,dio[340],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y108,IOB_X1Y103,dio[341],LVCMOS18,8,FAST,NONE
RIOB18_X312Y108,IOB_X1Y104,dio[342],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y110,IOB_X1Y105,dio[343],LVCMOS18,6,FAST,PULLUP
RIOB18_X312Y110,IOB_X1Y106,dio[344],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y112,IOB_X1Y107,dio[345],LVCMOS18,2,FAST,NONE
RIOB18_X312Y112,IOB_X1Y108,dio[346],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y114,IOB_X1Y109,dio[347],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y114,IOB_X1Y110,dio[348],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y116,IOB_X1Y111,dio[349],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y116,IOB_X1Y112,dio[350],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y118,IOB_X1Y113,dio[351],LVCMOS18,8,SLOW,PULLUP
RIOB18_X312Y118,IOB_X1Y114,dio[352],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y12,IOB_X1Y11,dio[353],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y12,IOB_X1Y12,dio[354],LVCMOS18,4,SLOW,PULLUP
RIOB18_X312Y120,IOB_X1Y115,dio[355],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y120,IOB_X1Y116,dio[356],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y122,IOB_X1Y117,dio[357],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y122,IOB_X1Y118,dio[358],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y124,IOB_X1Y119,dio[359],LVCMOS18,6,FAST,NONE
RIOB18_X312Y124,IOB_X1Y120,dio[360],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y126,IOB_X1Y121,dio[361],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y126,IOB_X1Y122,dio[362],LVCMOS18,12,FAST,KEEPER
RIOB18_X312Y128,IOB_X1Y123,dio[363],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y128,IOB_X1Y124,dio[364],LVCMOS18,6,FAST,NONE
RIOB18_X312Y131,IOB_X1Y125,dio[365],LVCMOS18,4,FAST,PULLUP
RIOB18_X312Y131,IOB_X1Y126,dio[366],LVCMOS18,6,FAST,NONE
RIOB18_X312Y133,IOB_X1Y127,dio[367],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y133,IOB_X1Y128,dio[368],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y135,IOB_X1Y129,dio[369],LVCMOS18,12,SLOW,KEEPER
RIOB18_X312Y135,IOB_X1Y130,dio[370],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y137,IOB_X1Y131,dio[371],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y137,IOB_X1Y132,dio[372],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y139,IOB_X1Y133,dio[373],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y139,IOB_X1Y134,dio[374],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y14,IOB_X1Y13,dio[375],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y14,IOB_X1Y14,dio[376],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y141,IOB_X1Y135,dio[377],LVCMOS18,16,FAST,KEEPER
RIOB18_X312Y141,IOB_X1Y136,dio[378],LVCMOS18,2,FAST,NONE
RIOB18_X312Y143,IOB_X1Y137,dio[379],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y143,IOB_X1Y138,dio[380],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y145,IOB_X1Y139,dio[381],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y145,IOB_X1Y140,dio[382],LVCMOS18,8,FAST,NONE
RIOB18_X312Y147,IOB_X1Y141,dio[383],LVCMOS18,4,FAST,NONE
RIOB18_X312Y147,IOB_X1Y142,dio[384],LVCMOS18,4,FAST,NONE
RIOB18_X312Y149,IOB_X1Y143,dio[385],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y149,IOB_X1Y144,dio[386],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y151,IOB_X1Y145,dio[387],LVCMOS18,12,SLOW,PULLDOWN
RIOB18_X312Y151,IOB_X1Y146,dio[388],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y153,IOB_X1Y147,dio[389],LVCMOS18,12,FAST,PULLDOWN
RIOB18_X312Y153,IOB_X1Y148,dio[390],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y158,IOB_X1Y151,dio[391],LVCMOS18,4,SLOW,KEEPER
RIOB18_X312Y158,IOB_X1Y152,dio[392],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y16,IOB_X1Y15,dio[393],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y16,IOB_X1Y16,dio[394],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y160,IOB_X1Y153,dio[395],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y160,IOB_X1Y154,dio[396],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y162,IOB_X1Y155,dio[397],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y162,IOB_X1Y156,dio[398],LVCMOS18,8,SLOW,PULLUP
RIOB18_X312Y164,IOB_X1Y157,dio[399],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y164,IOB_X1Y158,dio[400],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y166,IOB_X1Y159,dio[401],LVCMOS18,8,FAST,NONE
RIOB18_X312Y166,IOB_X1Y160,dio[402],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y168,IOB_X1Y161,dio[403],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y168,IOB_X1Y162,dio[404],LVCMOS18,6,FAST,NONE
RIOB18_X312Y170,IOB_X1Y163,dio[405],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y170,IOB_X1Y164,dio[406],LVCMOS18,4,FAST,PULLDOWN
RIOB18_X312Y172,IOB_X1Y165,dio[407],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y172,IOB_X1Y166,dio[408],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y174,IOB_X1Y167,dio[409],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y174,IOB_X1Y168,dio[410],LVCMOS18,16,FAST,KEEPER
RIOB18_X312Y176,IOB_X1Y169,dio[411],LVCMOS18,16,FAST,NONE
RIOB18_X312Y176,IOB_X1Y170,dio[412],LVCMOS18,12,SLOW,KEEPER
RIOB18_X312Y178,IOB_X1Y171,dio[413],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y178,IOB_X1Y172,dio[414],LVCMOS18,16,FAST,KEEPER
RIOB18_X312Y18,IOB_X1Y17,dio[415],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y18,IOB_X1Y18,dio[416],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y180,IOB_X1Y173,dio[417],LVCMOS18,12,SLOW,PULLDOWN
RIOB18_X312Y180,IOB_X1Y174,dio[418],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y183,IOB_X1Y175,dio[419],LVCMOS18,4,FAST,PULLUP
RIOB18_X312Y183,IOB_X1Y176,dio[420],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y185,IOB_X1Y177,dio[421],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y185,IOB_X1Y178,dio[422],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y187,IOB_X1Y179,dio[423],LVCMOS18,4,FAST,NONE
RIOB18_X312Y187,IOB_X1Y180,dio[424],LVCMOS18,4,FAST,NONE
RIOB18_X312Y189,IOB_X1Y181,dio[425],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y189,IOB_X1Y182,dio[426],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y191,IOB_X1Y183,dio[427],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y191,IOB_X1Y184,dio[428],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y193,IOB_X1Y185,dio[429],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y193,IOB_X1Y186,dio[430],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y195,IOB_X1Y187,dio[431],LVCMOS18,4,FAST,NONE
RIOB18_X312Y195,IOB_X1Y188,dio[432],LVCMOS18,8,SLOW,PULLUP
RIOB18_X312Y197,IOB_X1Y189,dio[433],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y197,IOB_X1Y190,dio[434],LVCMOS18,4,SLOW,NONE
RIOB18_X312Y199,IOB_X1Y191,dio[435],LVCMOS18,8,FAST,NONE
RIOB18_X312Y199,IOB_X1Y192,dio[436],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y2,IOB_X1Y1,dio[437],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y2,IOB_X1Y2,dio[438],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y20,IOB_X1Y19,dio[439],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y20,IOB_X1Y20,dio[440],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y201,IOB_X1Y193,dio[441],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y201,IOB_X1Y194,dio[442],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y203,IOB_X1Y195,dio[443],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y203,IOB_X1Y196,dio[444],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y205,IOB_X1Y197,dio[445],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y205,IOB_X1Y198,dio[446],LVCMOS18,6,FAST,NONE
RIOB18_X312Y210,IOB_X1Y201,dio[447],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y210,IOB_X1Y202,dio[448],LVCMOS18,8,FAST,PULLDOWN
RIOB18_X312Y212,IOB_X1Y203,dio[449],LVCMOS18,2,SLOW,PULLUP
RIOB18_X312Y212,IOB_X1Y204,dio[450],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y214,IOB_X1Y205,dio[451],LVCMOS18,12,FAST,PULLDOWN
RIOB18_X312Y214,IOB_X1Y206,dio[452],LVCMOS18,8,FAST,NONE
RIOB18_X312Y216,IOB_X1Y207,dio[453],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y216,IOB_X1Y208,dio[454],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y218,IOB_X1Y209,dio[455],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y218,IOB_X1Y210,dio[456],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y22,IOB_X1Y21,dio[457],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y22,IOB_X1Y22,dio[458],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y220,IOB_X1Y211,dio[459],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y220,IOB_X1Y212,dio[460],LVCMOS18,12,FAST,KEEPER
RIOB18_X312Y222,IOB_X1Y213,dio[461],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y222,IOB_X1Y214,dio[462],LVCMOS18,2,FAST,NONE
RIOB18_X312Y224,IOB_X1Y215,dio[463],LVCMOS18,16,FAST,NONE
RIOB18_X312Y224,IOB_X1Y216,dio[464],LVCMOS18,12,FAST,NONE
RIOB18_X312Y226,IOB_X1Y217,dio[465],LVCMOS18,6,FAST,PULLUP
RIOB18_X312Y226,IOB_X1Y218,dio[466],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y228,IOB_X1Y219,dio[467],LVCMOS18,8,FAST,NONE
RIOB18_X312Y228,IOB_X1Y220,dio[468],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y230,IOB_X1Y221,dio[469],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y230,IOB_X1Y222,dio[470],LVCMOS18,16,FAST,NONE
RIOB18_X312Y232,IOB_X1Y223,dio[471],LVCMOS18,8,FAST,NONE
RIOB18_X312Y232,IOB_X1Y224,dio[472],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y235,IOB_X1Y225,dio[473],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y235,IOB_X1Y226,dio[474],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y237,IOB_X1Y227,dio[475],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y237,IOB_X1Y228,dio[476],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y239,IOB_X1Y229,dio[477],LVCMOS18,4,SLOW,NONE
RIOB18_X312Y239,IOB_X1Y230,dio[478],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y24,IOB_X1Y23,dio[479],LVCMOS18,16,SLOW,NONE
RIOB18_X312Y24,IOB_X1Y24,dio[480],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y241,IOB_X1Y231,dio[481],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y241,IOB_X1Y232,dio[482],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y243,IOB_X1Y233,dio[483],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y243,IOB_X1Y234,dio[484],LVCMOS18,2,SLOW,PULLUP
RIOB18_X312Y245,IOB_X1Y235,dio[485],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y245,IOB_X1Y236,dio[486],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y247,IOB_X1Y237,dio[487],LVCMOS18,16,FAST,NONE
RIOB18_X312Y247,IOB_X1Y238,dio[488],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y249,IOB_X1Y239,dio[489],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y249,IOB_X1Y240,dio[490],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y251,IOB_X1Y241,dio[491],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y251,IOB_X1Y242,dio[492],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y253,IOB_X1Y243,dio[493],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y253,IOB_X1Y244,dio[494],LVCMOS18,16,FAST,KEEPER
RIOB18_X312Y255,IOB_X1Y245,dio[495],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y255,IOB_X1Y246,dio[496],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y257,IOB_X1Y247,dio[497],LVCMOS18,8,SLOW,PULLUP
RIOB18_X312Y257,IOB_X1Y248,dio[498],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y262,IOB_X1Y251,dio[499],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y262,IOB_X1Y252,dio[500],LVCMOS18,2,SLOW,KEEPER
RIOB18_X312Y264,IOB_X1Y253,dio[501],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y264,IOB_X1Y254,dio[502],LVCMOS18,16,SLOW,NONE
RIOB18_X312Y266,IOB_X1Y255,dio[503],LVCMOS18,12,SLOW,KEEPER
RIOB18_X312Y266,IOB_X1Y256,dio[504],LVCMOS18,12,FAST,PULLDOWN
RIOB18_X312Y268,IOB_X1Y257,dio[505],LVCMOS18,6,FAST,KEEPER
RIOB18_X312Y268,IOB_X1Y258,dio[506],LVCMOS18,4,FAST,NONE
RIOB18_X312Y27,IOB_X1Y25,dio[507],LVCMOS18,16,FAST,NONE
RIOB18_X312Y27,IOB_X1Y26,dio[508],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y270,IOB_X1Y259,dio[509],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y270,IOB_X1Y260,dio[510],LVCMOS18,2,FAST,PULLUP
RIOB18_X312Y272,IOB_X1Y261,dio[511],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y272,IOB_X1Y262,dio[512],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y274,IOB_X1Y263,dio[513],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y274,IOB_X1Y264,dio[514],LVCMOS18,16,FAST,NONE
RIOB18_X312Y276,IOB_X1Y265,dio[515],LVCMOS18,4,FAST,PULLDOWN
RIOB18_X312Y276,IOB_X1Y266,dio[516],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y278,IOB_X1Y267,dio[517],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y278,IOB_X1Y268,dio[518],LVCMOS18,4,SLOW,PULLUP
RIOB18_X312Y280,IOB_X1Y269,dio[519],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y280,IOB_X1Y270,dio[520],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y282,IOB_X1Y271,dio[521],LVCMOS18,16,SLOW,NONE
RIOB18_X312Y282,IOB_X1Y272,dio[522],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y284,IOB_X1Y273,dio[523],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y284,IOB_X1Y274,dio[524],LVCMOS18,2,SLOW,KEEPER
RIOB18_X312Y287,IOB_X1Y275,dio[525],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y287,IOB_X1Y276,dio[526],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y289,IOB_X1Y277,dio[527],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y289,IOB_X1Y278,dio[528],LVCMOS18,4,FAST,PULLDOWN
RIOB18_X312Y29,IOB_X1Y27,dio[529],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y29,IOB_X1Y28,dio[530],LVCMOS18,8,FAST,NONE
RIOB18_X312Y291,IOB_X1Y279,dio[531],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y291,IOB_X1Y280,dio[532],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y293,IOB_X1Y281,dio[533],LVCMOS18,8,FAST,PULLDOWN
RIOB18_X312Y293,IOB_X1Y282,dio[534],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y295,IOB_X1Y283,dio[535],LVCMOS18,2,FAST,NONE
RIOB18_X312Y295,IOB_X1Y284,dio[536],LVCMOS18,8,FAST,NONE
RIOB18_X312Y297,IOB_X1Y285,dio[537],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y297,IOB_X1Y286,dio[538],LVCMOS18,4,SLOW,KEEPER
RIOB18_X312Y299,IOB_X1Y287,dio[539],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y299,IOB_X1Y288,dio[540],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y301,IOB_X1Y289,dio[541],LVCMOS18,2,SLOW,PULLDOWN
RIOB18_X312Y301,IOB_X1Y290,dio[542],LVCMOS18,4,SLOW,PULLUP
RIOB18_X312Y303,IOB_X1Y291,dio[543],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y303,IOB_X1Y292,dio[544],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y305,IOB_X1Y293,dio[545],LVCMOS18,12,FAST,NONE
RIOB18_X312Y305,IOB_X1Y294,dio[546],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y307,IOB_X1Y295,dio[547],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y307,IOB_X1Y296,dio[548],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y309,IOB_X1Y297,dio[549],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y309,IOB_X1Y298,dio[550],LVCMOS18,4,SLOW,NONE
RIOB18_X312Y31,IOB_X1Y29,dio[551],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y31,IOB_X1Y30,dio[552],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y314,IOB_X1Y301,dio[553],LVCMOS18,2,SLOW,KEEPER
RIOB18_X312Y314,IOB_X1Y302,dio[554],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y316,IOB_X1Y303,dio[555],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y316,IOB_X1Y304,dio[556],LVCMOS18,6,FAST,PULLUP
RIOB18_X312Y318,IOB_X1Y305,dio[557],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y318,IOB_X1Y306,dio[558],LVCMOS18,4,SLOW,PULLUP
RIOB18_X312Y320,IOB_X1Y307,dio[559],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y320,IOB_X1Y308,dio[560],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y322,IOB_X1Y309,dio[561],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y322,IOB_X1Y310,dio[562],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y324,IOB_X1Y311,dio[563],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y324,IOB_X1Y312,dio[564],LVCMOS18,6,FAST,NONE
RIOB18_X312Y326,IOB_X1Y313,dio[565],LVCMOS18,8,FAST,PULLUP
RIOB18_X312Y326,IOB_X1Y314,dio[566],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y328,IOB_X1Y315,dio[567],LVCMOS18,12,FAST,NONE
RIOB18_X312Y328,IOB_X1Y316,dio[568],LVCMOS18,2,FAST,PULLUP
RIOB18_X312Y33,IOB_X1Y31,dio[569],LVCMOS18,12,FAST,NONE
RIOB18_X312Y33,IOB_X1Y32,dio[570],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y330,IOB_X1Y317,dio[571],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y330,IOB_X1Y318,dio[572],LVCMOS18,8,FAST,NONE
RIOB18_X312Y332,IOB_X1Y319,dio[573],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y332,IOB_X1Y320,dio[574],LVCMOS18,12,FAST,NONE
RIOB18_X312Y334,IOB_X1Y321,dio[575],LVCMOS18,16,FAST,NONE
RIOB18_X312Y334,IOB_X1Y322,dio[576],LVCMOS18,16,SLOW,KEEPER
RIOB18_X312Y336,IOB_X1Y323,dio[577],LVCMOS18,6,FAST,NONE
RIOB18_X312Y336,IOB_X1Y324,dio[578],LVCMOS18,4,FAST,NONE
RIOB18_X312Y339,IOB_X1Y325,dio[579],LVCMOS18,16,FAST,KEEPER
RIOB18_X312Y339,IOB_X1Y326,dio[580],LVCMOS18,16,SLOW,NONE
RIOB18_X312Y341,IOB_X1Y327,dio[581],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y341,IOB_X1Y328,dio[582],LVCMOS18,2,SLOW,PULLUP
RIOB18_X312Y343,IOB_X1Y329,dio[583],LVCMOS18,16,SLOW,PULLUP
RIOB18_X312Y343,IOB_X1Y330,dio[584],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y345,IOB_X1Y331,dio[585],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y345,IOB_X1Y332,dio[586],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y347,IOB_X1Y333,dio[587],LVCMOS18,8,FAST,NONE
RIOB18_X312Y347,IOB_X1Y334,dio[588],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y349,IOB_X1Y335,dio[589],LVCMOS18,4,FAST,PULLUP
RIOB18_X312Y349,IOB_X1Y336,dio[590],LVCMOS18,12,SLOW,PULLDOWN
RIOB18_X312Y35,IOB_X1Y33,dio[591],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y35,IOB_X1Y34,dio[592],LVCMOS18,4,SLOW,PULLUP
RIOB18_X312Y351,IOB_X1Y337,dio[593],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y351,IOB_X1Y338,dio[594],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y353,IOB_X1Y339,dio[595],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y353,IOB_X1Y340,dio[596],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y355,IOB_X1Y341,dio[597],LVCMOS18,8,FAST,NONE
RIOB18_X312Y355,IOB_X1Y342,dio[598],LVCMOS18,8,SLOW,PULLDOWN
RIOB18_X312Y357,IOB_X1Y343,dio[599],LVCMOS18,6,FAST,NONE
RIOB18_X312Y357,IOB_X1Y344,dio[600],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y359,IOB_X1Y345,dio[601],LVCMOS18,8,SLOW,NONE
RIOB18_X312Y359,IOB_X1Y346,dio[602],LVCMOS18,16,SLOW,PULLDOWN
RIOB18_X312Y361,IOB_X1Y347,dio[603],LVCMOS18,8,FAST,NONE
RIOB18_X312Y361,IOB_X1Y348,dio[604],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y37,IOB_X1Y35,dio[605],LVCMOS18,4,SLOW,KEEPER
RIOB18_X312Y37,IOB_X1Y36,dio[606],LVCMOS18,12,SLOW,PULLDOWN
RIOB18_X312Y39,IOB_X1Y37,dio[607],LVCMOS18,4,FAST,PULLUP
RIOB18_X312Y39,IOB_X1Y38,dio[608],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y4,IOB_X1Y3,dio[609],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y4,IOB_X1Y4,dio[610],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y41,IOB_X1Y39,dio[611],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y41,IOB_X1Y40,dio[612],LVCMOS18,16,SLOW,NONE
RIOB18_X312Y43,IOB_X1Y41,dio[613],LVCMOS18,16,FAST,NONE
RIOB18_X312Y43,IOB_X1Y42,dio[614],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y45,IOB_X1Y43,dio[615],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y45,IOB_X1Y44,dio[616],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y47,IOB_X1Y45,dio[617],LVCMOS18,12,FAST,PULLUP
RIOB18_X312Y47,IOB_X1Y46,dio[618],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y49,IOB_X1Y47,dio[619],LVCMOS18,2,FAST,PULLUP
RIOB18_X312Y49,IOB_X1Y48,dio[620],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y54,IOB_X1Y51,dio[621],LVCMOS18,12,SLOW,PULLDOWN
RIOB18_X312Y54,IOB_X1Y52,dio[622],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y56,IOB_X1Y53,dio[623],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y56,IOB_X1Y54,dio[624],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y58,IOB_X1Y55,dio[625],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y58,IOB_X1Y56,dio[626],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y6,IOB_X1Y5,dio[627],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y6,IOB_X1Y6,dio[628],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y60,IOB_X1Y57,dio[629],LVCMOS18,8,FAST,KEEPER
RIOB18_X312Y60,IOB_X1Y58,dio[630],LVCMOS18,2,FAST,PULLDOWN
RIOB18_X312Y62,IOB_X1Y59,dio[631],LVCMOS18,6,SLOW,PULLUP
RIOB18_X312Y62,IOB_X1Y60,dio[632],LVCMOS18,4,SLOW,PULLDOWN
RIOB18_X312Y64,IOB_X1Y61,dio[633],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y64,IOB_X1Y62,dio[634],LVCMOS18,2,SLOW,PULLUP
RIOB18_X312Y66,IOB_X1Y63,dio[635],LVCMOS18,6,FAST,PULLUP
RIOB18_X312Y66,IOB_X1Y64,dio[636],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y68,IOB_X1Y65,dio[637],LVCMOS18,4,SLOW,KEEPER
RIOB18_X312Y68,IOB_X1Y66,dio[638],LVCMOS18,2,FAST,PULLUP
RIOB18_X312Y70,IOB_X1Y67,dio[639],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y70,IOB_X1Y68,dio[640],LVCMOS18,16,FAST,PULLDOWN
RIOB18_X312Y72,IOB_X1Y69,dio[641],LVCMOS18,8,FAST,PULLDOWN
RIOB18_X312Y72,IOB_X1Y70,dio[642],LVCMOS18,8,FAST,PULLDOWN
RIOB18_X312Y74,IOB_X1Y71,dio[643],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y74,IOB_X1Y72,dio[644],LVCMOS18,6,FAST,KEEPER
RIOB18_X312Y76,IOB_X1Y73,dio[645],LVCMOS18,2,SLOW,KEEPER
RIOB18_X312Y76,IOB_X1Y74,dio[646],LVCMOS18,4,FAST,NONE
RIOB18_X312Y79,IOB_X1Y75,dio[647],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y79,IOB_X1Y76,dio[648],LVCMOS18,6,SLOW,KEEPER
RIOB18_X312Y8,IOB_X1Y7,dio[649],LVCMOS18,6,SLOW,PULLDOWN
RIOB18_X312Y8,IOB_X1Y8,dio[650],LVCMOS18,16,FAST,PULLUP
RIOB18_X312Y81,IOB_X1Y77,dio[651],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y81,IOB_X1Y78,dio[652],LVCMOS18,2,FAST,KEEPER
RIOB18_X312Y83,IOB_X1Y79,dio[653],LVCMOS18,8,FAST,NONE
RIOB18_X312Y83,IOB_X1Y80,dio[654],LVCMOS18,4,FAST,NONE
RIOB18_X312Y85,IOB_X1Y81,dio[655],LVCMOS18,12,FAST,KEEPER
RIOB18_X312Y85,IOB_X1Y82,dio[656],LVCMOS18,6,FAST,PULLDOWN
RIOB18_X312Y87,IOB_X1Y83,dio[657],LVCMOS18,12,SLOW,KEEPER
RIOB18_X312Y87,IOB_X1Y84,dio[658],LVCMOS18,6,FAST,NONE
RIOB18_X312Y89,IOB_X1Y85,dio[659],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y89,IOB_X1Y86,dio[660],LVCMOS18,12,SLOW,PULLUP
RIOB18_X312Y91,IOB_X1Y87,dio[661],LVCMOS18,6,SLOW,NONE
RIOB18_X312Y91,IOB_X1Y88,dio[662],LVCMOS18,12,SLOW,NONE
RIOB18_X312Y93,IOB_X1Y89,dio[663],LVCMOS18,6,FAST,KEEPER
RIOB18_X312Y93,IOB_X1Y90,dio[664],LVCMOS18,8,FAST,PULLDOWN
RIOB18_X312Y95,IOB_X1Y91,dio[665],LVCMOS18,2,SLOW,NONE
RIOB18_X312Y95,IOB_X1Y92,dio[666],LVCMOS18,4,FAST,PULLDOWN
RIOB18_X312Y97,IOB_X1Y93,dio[667],LVCMOS18,12,FAST,KEEPER
RIOB18_X312Y97,IOB_X1Y94,dio[668],LVCMOS18,8,SLOW,KEEPER
RIOB18_X312Y99,IOB_X1Y95,dio[669],LVCMOS18,4,FAST,KEEPER
RIOB18_X312Y99,IOB_X1Y96,dio[670],LVCMOS18,8,FAST,KEEPER
1 tile,site,pin,iostandard,drive,slew
2 LIOB18_X81Y10,IOB_X0Y10,dio[0],LVCMOS18,6,FAST,PULLDOWN
3 LIOB18_X81Y101,IOB_X0Y97,dio[1],LVCMOS18,6,FAST,PULLUP
4 LIOB18_X81Y101,IOB_X0Y98,dio[2],LVCMOS18,4,FAST,PULLDOWN
5 LIOB18_X81Y106,IOB_X0Y101,dio[3],LVCMOS18,6,FAST,KEEPER
6 LIOB18_X81Y106,IOB_X0Y102,dio[4],LVCMOS18,6,FAST,PULLDOWN
7 LIOB18_X81Y108,IOB_X0Y103,dio[5],LVCMOS18,2,SLOW,KEEPER
8 LIOB18_X81Y108,IOB_X0Y104,dio[6],LVCMOS18,16,FAST,PULLUP
9 LIOB18_X81Y110,IOB_X0Y105,dio[7],LVCMOS18,16,SLOW,NONE
10 LIOB18_X81Y110,IOB_X0Y106,dio[8],LVCMOS18,2,FAST,PULLUP
11 LIOB18_X81Y112,IOB_X0Y107,dio[9],LVCMOS18,6,SLOW,PULLDOWN
12 LIOB18_X81Y112,IOB_X0Y108,dio[10],LVCMOS18,4,SLOW,NONE
13 LIOB18_X81Y114,IOB_X0Y109,dio[11],LVCMOS18,16,SLOW,PULLDOWN
14 LIOB18_X81Y114,IOB_X0Y110,dio[12],LVCMOS18,6,FAST,KEEPER
15 LIOB18_X81Y116,IOB_X0Y111,dio[13],LVCMOS18,8,FAST,NONE
16 LIOB18_X81Y116,IOB_X0Y112,dio[14],LVCMOS18,8,FAST,PULLUP
17 LIOB18_X81Y118,IOB_X0Y113,dio[15],LVCMOS18,12,SLOW,PULLUP
18 LIOB18_X81Y118,IOB_X0Y114,dio[16],LVCMOS18,6,FAST,NONE
19 LIOB18_X81Y12,IOB_X0Y11,dio[17],LVCMOS18,6,FAST,NONE
20 LIOB18_X81Y12,IOB_X0Y12,dio[18],LVCMOS18,8,FAST,PULLUP
21 LIOB18_X81Y120,IOB_X0Y115,dio[19],LVCMOS18,16,FAST,KEEPER
22 LIOB18_X81Y120,IOB_X0Y116,dio[20],LVCMOS18,6,SLOW,KEEPER
23 LIOB18_X81Y122,IOB_X0Y117,dio[21],LVCMOS18,6,FAST,KEEPER
24 LIOB18_X81Y122,IOB_X0Y118,dio[22],LVCMOS18,2,FAST,NONE
25 LIOB18_X81Y124,IOB_X0Y119,dio[23],LVCMOS18,12,SLOW,PULLDOWN
26 LIOB18_X81Y124,IOB_X0Y120,dio[24],LVCMOS18,12,SLOW,PULLUP
27 LIOB18_X81Y126,IOB_X0Y121,dio[25],LVCMOS18,8,FAST,PULLUP
28 LIOB18_X81Y126,IOB_X0Y122,dio[26],LVCMOS18,2,SLOW,PULLUP
29 LIOB18_X81Y128,IOB_X0Y123,dio[27],LVCMOS18,2,FAST,NONE
30 LIOB18_X81Y128,IOB_X0Y124,dio[28],LVCMOS18,16,FAST,PULLUP
31 LIOB18_X81Y131,IOB_X0Y125,dio[29],LVCMOS18,6,SLOW,PULLDOWN
32 LIOB18_X81Y131,IOB_X0Y126,dio[30],LVCMOS18,2,SLOW,PULLUP
33 LIOB18_X81Y133,IOB_X0Y127,dio[31],LVCMOS18,8,FAST,KEEPER
34 LIOB18_X81Y133,IOB_X0Y128,dio[32],LVCMOS18,16,FAST,NONE
35 LIOB18_X81Y135,IOB_X0Y129,dio[33],LVCMOS18,4,FAST,NONE
36 LIOB18_X81Y135,IOB_X0Y130,dio[34],LVCMOS18,4,FAST,NONE
37 LIOB18_X81Y137,IOB_X0Y131,dio[35],LVCMOS18,16,SLOW,PULLDOWN
38 LIOB18_X81Y137,IOB_X0Y132,dio[36],LVCMOS18,4,FAST,NONE
39 LIOB18_X81Y139,IOB_X0Y133,dio[37],LVCMOS18,12,SLOW,KEEPER
40 LIOB18_X81Y139,IOB_X0Y134,dio[38],LVCMOS18,4,SLOW,NONE
41 LIOB18_X81Y14,IOB_X0Y13,dio[39],LVCMOS18,8,SLOW,PULLUP
42 LIOB18_X81Y14,IOB_X0Y14,dio[40],LVCMOS18,4,FAST,KEEPER
43 LIOB18_X81Y141,IOB_X0Y135,dio[41],LVCMOS18,16,SLOW,PULLDOWN
44 LIOB18_X81Y141,IOB_X0Y136,dio[42],LVCMOS18,6,FAST,PULLUP
45 LIOB18_X81Y143,IOB_X0Y137,dio[43],LVCMOS18,12,SLOW,KEEPER
46 LIOB18_X81Y143,IOB_X0Y138,dio[44],LVCMOS18,4,FAST,PULLDOWN
47 LIOB18_X81Y145,IOB_X0Y139,dio[45],LVCMOS18,8,SLOW,PULLDOWN
48 LIOB18_X81Y145,IOB_X0Y140,dio[46],LVCMOS18,2,FAST,NONE
49 LIOB18_X81Y147,IOB_X0Y141,dio[47],LVCMOS18,2,SLOW,NONE
50 LIOB18_X81Y147,IOB_X0Y142,dio[48],LVCMOS18,8,SLOW,PULLUP
51 LIOB18_X81Y149,IOB_X0Y143,dio[49],LVCMOS18,16,FAST,PULLDOWN
52 LIOB18_X81Y149,IOB_X0Y144,dio[50],LVCMOS18,4,FAST,PULLDOWN
53 LIOB18_X81Y151,IOB_X0Y145,dio[51],LVCMOS18,6,FAST,KEEPER
54 LIOB18_X81Y151,IOB_X0Y146,dio[52],LVCMOS18,12,SLOW,NONE
55 LIOB18_X81Y153,IOB_X0Y147,dio[53],LVCMOS18,4,FAST,KEEPER
56 LIOB18_X81Y153,IOB_X0Y148,dio[54],LVCMOS18,16,SLOW,PULLDOWN
57 LIOB18_X81Y158,IOB_X0Y151,dio[55],LVCMOS18,16,SLOW,NONE
58 LIOB18_X81Y158,IOB_X0Y152,dio[56],LVCMOS18,4,SLOW,NONE
59 LIOB18_X81Y16,IOB_X0Y15,dio[57],LVCMOS18,8,SLOW,KEEPER
60 LIOB18_X81Y16,IOB_X0Y16,dio[58],LVCMOS18,12,SLOW,NONE
61 LIOB18_X81Y160,IOB_X0Y153,dio[59],LVCMOS18,2,FAST,PULLUP
62 LIOB18_X81Y160,IOB_X0Y154,dio[60],LVCMOS18,6,FAST,KEEPER
63 LIOB18_X81Y162,IOB_X0Y155,dio[61],LVCMOS18,4,FAST,NONE
64 LIOB18_X81Y162,IOB_X0Y156,dio[62],LVCMOS18,6,SLOW,PULLUP
65 LIOB18_X81Y164,IOB_X0Y157,dio[63],LVCMOS18,4,FAST,NONE
66 LIOB18_X81Y164,IOB_X0Y158,dio[64],LVCMOS18,2,FAST,PULLDOWN
67 LIOB18_X81Y166,IOB_X0Y159,dio[65],LVCMOS18,4,FAST,NONE
68 LIOB18_X81Y166,IOB_X0Y160,dio[66],LVCMOS18,16,SLOW,NONE
69 LIOB18_X81Y168,IOB_X0Y161,dio[67],LVCMOS18,6,SLOW,NONE
70 LIOB18_X81Y168,IOB_X0Y162,dio[68],LVCMOS18,4,SLOW,KEEPER
71 LIOB18_X81Y170,IOB_X0Y163,dio[69],LVCMOS18,12,FAST,PULLUP
72 LIOB18_X81Y170,IOB_X0Y164,dio[70],LVCMOS18,2,SLOW,NONE
73 LIOB18_X81Y172,IOB_X0Y165,dio[71],LVCMOS18,12,FAST,PULLUP
74 LIOB18_X81Y172,IOB_X0Y166,dio[72],LVCMOS18,8,SLOW,NONE
75 LIOB18_X81Y174,IOB_X0Y167,dio[73],LVCMOS18,8,FAST,PULLDOWN
76 LIOB18_X81Y174,IOB_X0Y168,dio[74],LVCMOS18,8,FAST,PULLUP
77 LIOB18_X81Y176,IOB_X0Y169,dio[75],LVCMOS18,16,FAST,PULLUP
78 LIOB18_X81Y176,IOB_X0Y170,dio[76],LVCMOS18,4,FAST,NONE
79 LIOB18_X81Y178,IOB_X0Y171,dio[77],LVCMOS18,8,SLOW,NONE
80 LIOB18_X81Y178,IOB_X0Y172,dio[78],LVCMOS18,12,SLOW,PULLDOWN
81 LIOB18_X81Y18,IOB_X0Y17,dio[79],LVCMOS18,12,FAST,PULLUP
82 LIOB18_X81Y18,IOB_X0Y18,dio[80],LVCMOS18,2,FAST,KEEPER
83 LIOB18_X81Y180,IOB_X0Y173,dio[81],LVCMOS18,8,SLOW,PULLUP
84 LIOB18_X81Y180,IOB_X0Y174,dio[82],LVCMOS18,16,SLOW,PULLDOWN
85 LIOB18_X81Y183,IOB_X0Y175,dio[83],LVCMOS18,6,SLOW,PULLDOWN
86 LIOB18_X81Y183,IOB_X0Y176,dio[84],LVCMOS18,8,FAST,PULLDOWN
87 LIOB18_X81Y185,IOB_X0Y177,dio[85],LVCMOS18,2,SLOW,NONE
88 LIOB18_X81Y185,IOB_X0Y178,dio[86],LVCMOS18,8,SLOW,PULLUP
89 LIOB18_X81Y187,IOB_X0Y179,dio[87],LVCMOS18,8,FAST,NONE
90 LIOB18_X81Y187,IOB_X0Y180,dio[88],LVCMOS18,16,SLOW,KEEPER
91 LIOB18_X81Y189,IOB_X0Y181,dio[89],LVCMOS18,16,SLOW,PULLUP
92 LIOB18_X81Y189,IOB_X0Y182,dio[90],LVCMOS18,6,FAST,NONE
93 LIOB18_X81Y191,IOB_X0Y183,dio[91],LVCMOS18,4,SLOW,KEEPER
94 LIOB18_X81Y191,IOB_X0Y184,dio[92],LVCMOS18,16,SLOW,NONE
95 LIOB18_X81Y193,IOB_X0Y185,dio[93],LVCMOS18,2,SLOW,KEEPER
96 LIOB18_X81Y193,IOB_X0Y186,dio[94],LVCMOS18,6,SLOW,PULLUP
97 LIOB18_X81Y195,IOB_X0Y187,dio[95],LVCMOS18,6,SLOW,PULLUP
98 LIOB18_X81Y195,IOB_X0Y188,dio[96],LVCMOS18,4,SLOW,KEEPER
99 LIOB18_X81Y197,IOB_X0Y189,dio[97],LVCMOS18,8,SLOW,PULLUP
100 LIOB18_X81Y197,IOB_X0Y190,dio[98],LVCMOS18,6,SLOW,PULLDOWN
101 LIOB18_X81Y199,IOB_X0Y191,dio[99],LVCMOS18,8,SLOW,NONE
102 LIOB18_X81Y199,IOB_X0Y192,dio[100],LVCMOS18,2,FAST,KEEPER
103 LIOB18_X81Y2,IOB_X0Y1,dio[101],LVCMOS18,12,SLOW,PULLDOWN
104 LIOB18_X81Y2,IOB_X0Y2,dio[102],LVCMOS18,6,SLOW,NONE
105 LIOB18_X81Y20,IOB_X0Y19,dio[103],LVCMOS18,6,SLOW,KEEPER
106 LIOB18_X81Y20,IOB_X0Y20,dio[104],LVCMOS18,6,FAST,PULLUP
107 LIOB18_X81Y201,IOB_X0Y193,dio[105],LVCMOS18,6,FAST,NONE
108 LIOB18_X81Y201,IOB_X0Y194,dio[106],LVCMOS18,2,SLOW,PULLDOWN
109 LIOB18_X81Y203,IOB_X0Y195,dio[107],LVCMOS18,2,SLOW,PULLDOWN
110 LIOB18_X81Y203,IOB_X0Y196,dio[108],LVCMOS18,2,SLOW,NONE
111 LIOB18_X81Y205,IOB_X0Y197,dio[109],LVCMOS18,12,SLOW,NONE
112 LIOB18_X81Y205,IOB_X0Y198,dio[110],LVCMOS18,16,FAST,PULLUP
113 LIOB18_X81Y210,IOB_X0Y201,dio[111],LVCMOS18,8,SLOW,KEEPER
114 LIOB18_X81Y210,IOB_X0Y202,dio[112],LVCMOS18,12,FAST,KEEPER
115 LIOB18_X81Y212,IOB_X0Y203,dio[113],LVCMOS18,6,FAST,KEEPER
116 LIOB18_X81Y212,IOB_X0Y204,dio[114],LVCMOS18,6,SLOW,NONE
117 LIOB18_X81Y214,IOB_X0Y205,dio[115],LVCMOS18,12,SLOW,PULLUP
118 LIOB18_X81Y214,IOB_X0Y206,dio[116],LVCMOS18,2,FAST,KEEPER
119 LIOB18_X81Y216,IOB_X0Y207,dio[117],LVCMOS18,6,SLOW,KEEPER
120 LIOB18_X81Y216,IOB_X0Y208,dio[118],LVCMOS18,6,FAST,PULLDOWN
121 LIOB18_X81Y218,IOB_X0Y209,dio[119],LVCMOS18,12,SLOW,PULLUP
122 LIOB18_X81Y218,IOB_X0Y210,dio[120],LVCMOS18,4,SLOW,PULLUP
123 LIOB18_X81Y22,IOB_X0Y21,dio[121],LVCMOS18,8,SLOW,PULLDOWN
124 LIOB18_X81Y22,IOB_X0Y22,dio[122],LVCMOS18,16,FAST,KEEPER
125 LIOB18_X81Y220,IOB_X0Y211,dio[123],LVCMOS18,12,SLOW,PULLUP
126 LIOB18_X81Y220,IOB_X0Y212,dio[124],LVCMOS18,2,FAST,KEEPER
127 LIOB18_X81Y222,IOB_X0Y213,dio[125],LVCMOS18,12,FAST,PULLDOWN
128 LIOB18_X81Y222,IOB_X0Y214,dio[126],LVCMOS18,2,SLOW,PULLDOWN
129 LIOB18_X81Y224,IOB_X0Y215,dio[127],LVCMOS18,4,SLOW,PULLUP
130 LIOB18_X81Y224,IOB_X0Y216,dio[128],LVCMOS18,6,FAST,NONE
131 LIOB18_X81Y226,IOB_X0Y217,dio[129],LVCMOS18,8,FAST,PULLDOWN
132 LIOB18_X81Y226,IOB_X0Y218,dio[130],LVCMOS18,2,FAST,KEEPER
133 LIOB18_X81Y228,IOB_X0Y219,dio[131],LVCMOS18,2,FAST,KEEPER
134 LIOB18_X81Y228,IOB_X0Y220,dio[132],LVCMOS18,6,SLOW,PULLUP
135 LIOB18_X81Y230,IOB_X0Y221,dio[133],LVCMOS18,2,SLOW,KEEPER
136 LIOB18_X81Y230,IOB_X0Y222,dio[134],LVCMOS18,16,FAST,PULLDOWN
137 LIOB18_X81Y232,IOB_X0Y223,dio[135],LVCMOS18,8,FAST,PULLUP
138 LIOB18_X81Y232,IOB_X0Y224,dio[136],LVCMOS18,6,SLOW,NONE
139 LIOB18_X81Y235,IOB_X0Y225,dio[137],LVCMOS18,16,SLOW,PULLUP
140 LIOB18_X81Y235,IOB_X0Y226,dio[138],LVCMOS18,8,FAST,KEEPER
141 LIOB18_X81Y237,IOB_X0Y227,dio[139],LVCMOS18,6,FAST,PULLUP
142 LIOB18_X81Y237,IOB_X0Y228,dio[140],LVCMOS18,16,SLOW,PULLDOWN
143 LIOB18_X81Y239,IOB_X0Y229,dio[141],LVCMOS18,12,FAST,PULLDOWN
144 LIOB18_X81Y239,IOB_X0Y230,dio[142],LVCMOS18,16,FAST,PULLUP
145 LIOB18_X81Y24,IOB_X0Y23,dio[143],LVCMOS18,4,SLOW,KEEPER
146 LIOB18_X81Y24,IOB_X0Y24,dio[144],LVCMOS18,12,SLOW,KEEPER
147 LIOB18_X81Y241,IOB_X0Y231,dio[145],LVCMOS18,12,SLOW,NONE
148 LIOB18_X81Y241,IOB_X0Y232,dio[146],LVCMOS18,16,FAST,KEEPER
149 LIOB18_X81Y243,IOB_X0Y233,dio[147],LVCMOS18,12,SLOW,NONE
150 LIOB18_X81Y243,IOB_X0Y234,dio[148],LVCMOS18,8,SLOW,PULLDOWN
151 LIOB18_X81Y245,IOB_X0Y235,dio[149],LVCMOS18,12,SLOW,PULLUP
152 LIOB18_X81Y245,IOB_X0Y236,dio[150],LVCMOS18,8,SLOW,PULLUP
153 LIOB18_X81Y247,IOB_X0Y237,dio[151],LVCMOS18,8,FAST,KEEPER
154 LIOB18_X81Y247,IOB_X0Y238,dio[152],LVCMOS18,2,FAST,PULLDOWN
155 LIOB18_X81Y249,IOB_X0Y239,dio[153],LVCMOS18,2,SLOW,KEEPER
156 LIOB18_X81Y249,IOB_X0Y240,dio[154],LVCMOS18,16,SLOW,NONE
157 LIOB18_X81Y251,IOB_X0Y241,dio[155],LVCMOS18,8,SLOW,KEEPER
158 LIOB18_X81Y251,IOB_X0Y242,dio[156],LVCMOS18,12,SLOW,KEEPER
159 LIOB18_X81Y253,IOB_X0Y243,dio[157],LVCMOS18,2,FAST,PULLUP
160 LIOB18_X81Y253,IOB_X0Y244,dio[158],LVCMOS18,16,FAST,PULLUP
161 LIOB18_X81Y255,IOB_X0Y245,dio[159],LVCMOS18,4,SLOW,NONE
162 LIOB18_X81Y255,IOB_X0Y246,dio[160],LVCMOS18,16,SLOW,PULLUP
163 LIOB18_X81Y257,IOB_X0Y247,dio[161],LVCMOS18,6,FAST,PULLDOWN
164 LIOB18_X81Y257,IOB_X0Y248,dio[162],LVCMOS18,12,SLOW,PULLDOWN
165 LIOB18_X81Y262,IOB_X0Y251,dio[163],LVCMOS18,16,SLOW,PULLUP
166 LIOB18_X81Y262,IOB_X0Y252,dio[164],LVCMOS18,6,SLOW,NONE
167 LIOB18_X81Y264,IOB_X0Y253,dio[165],LVCMOS18,12,SLOW,PULLUP
168 LIOB18_X81Y264,IOB_X0Y254,dio[166],LVCMOS18,6,SLOW,NONE
169 LIOB18_X81Y266,IOB_X0Y255,dio[167],LVCMOS18,6,FAST,KEEPER
170 LIOB18_X81Y266,IOB_X0Y256,dio[168],LVCMOS18,4,SLOW,PULLUP
171 LIOB18_X81Y268,IOB_X0Y257,dio[169],LVCMOS18,8,FAST,KEEPER
172 LIOB18_X81Y268,IOB_X0Y258,dio[170],LVCMOS18,6,FAST,PULLDOWN
173 LIOB18_X81Y27,IOB_X0Y25,dio[171],LVCMOS18,8,FAST,NONE
174 LIOB18_X81Y27,IOB_X0Y26,dio[172],LVCMOS18,8,FAST,NONE
175 LIOB18_X81Y270,IOB_X0Y259,dio[173],LVCMOS18,12,FAST,NONE
176 LIOB18_X81Y270,IOB_X0Y260,dio[174],LVCMOS18,8,SLOW,PULLUP
177 LIOB18_X81Y272,IOB_X0Y261,dio[175],LVCMOS18,12,SLOW,NONE
178 LIOB18_X81Y272,IOB_X0Y262,dio[176],LVCMOS18,12,FAST,KEEPER
179 LIOB18_X81Y274,IOB_X0Y263,dio[177],LVCMOS18,12,FAST,PULLUP
180 LIOB18_X81Y274,IOB_X0Y264,dio[178],LVCMOS18,2,SLOW,PULLDOWN
181 LIOB18_X81Y276,IOB_X0Y265,dio[179],LVCMOS18,2,FAST,KEEPER
182 LIOB18_X81Y276,IOB_X0Y266,dio[180],LVCMOS18,6,FAST,NONE
183 LIOB18_X81Y278,IOB_X0Y267,dio[181],LVCMOS18,6,SLOW,PULLDOWN
184 LIOB18_X81Y278,IOB_X0Y268,dio[182],LVCMOS18,4,FAST,PULLDOWN
185 LIOB18_X81Y280,IOB_X0Y269,dio[183],LVCMOS18,16,FAST,PULLUP
186 LIOB18_X81Y280,IOB_X0Y270,dio[184],LVCMOS18,12,FAST,PULLDOWN
187 LIOB18_X81Y282,IOB_X0Y271,dio[185],LVCMOS18,6,FAST,KEEPER
188 LIOB18_X81Y282,IOB_X0Y272,dio[186],LVCMOS18,2,SLOW,KEEPER
189 LIOB18_X81Y284,IOB_X0Y273,dio[187],LVCMOS18,12,SLOW,PULLDOWN
190 LIOB18_X81Y284,IOB_X0Y274,dio[188],LVCMOS18,2,SLOW,KEEPER
191 LIOB18_X81Y287,IOB_X0Y275,dio[189],LVCMOS18,4,FAST,PULLDOWN
192 LIOB18_X81Y287,IOB_X0Y276,dio[190],LVCMOS18,8,SLOW,KEEPER
193 LIOB18_X81Y289,IOB_X0Y277,dio[191],LVCMOS18,8,FAST,KEEPER
194 LIOB18_X81Y289,IOB_X0Y278,dio[192],LVCMOS18,2,FAST,PULLDOWN
195 LIOB18_X81Y29,IOB_X0Y27,dio[193],LVCMOS18,16,SLOW,PULLUP
196 LIOB18_X81Y29,IOB_X0Y28,dio[194],LVCMOS18,16,FAST,NONE
197 LIOB18_X81Y291,IOB_X0Y279,dio[195],LVCMOS18,2,FAST,NONE
198 LIOB18_X81Y291,IOB_X0Y280,dio[196],LVCMOS18,12,SLOW,KEEPER
199 LIOB18_X81Y293,IOB_X0Y281,dio[197],LVCMOS18,8,FAST,NONE
200 LIOB18_X81Y293,IOB_X0Y282,dio[198],LVCMOS18,16,FAST,PULLUP
201 LIOB18_X81Y295,IOB_X0Y283,dio[199],LVCMOS18,4,SLOW,KEEPER
202 LIOB18_X81Y295,IOB_X0Y284,dio[200],LVCMOS18,12,SLOW,KEEPER
203 LIOB18_X81Y297,IOB_X0Y285,dio[201],LVCMOS18,12,FAST,PULLUP
204 LIOB18_X81Y297,IOB_X0Y286,dio[202],LVCMOS18,2,FAST,NONE
205 LIOB18_X81Y299,IOB_X0Y287,dio[203],LVCMOS18,16,SLOW,PULLUP
206 LIOB18_X81Y299,IOB_X0Y288,dio[204],LVCMOS18,12,SLOW,PULLDOWN
207 LIOB18_X81Y301,IOB_X0Y289,dio[205],LVCMOS18,8,SLOW,NONE
208 LIOB18_X81Y301,IOB_X0Y290,dio[206],LVCMOS18,12,FAST,KEEPER
209 LIOB18_X81Y303,IOB_X0Y291,dio[207],LVCMOS18,12,FAST,KEEPER
210 LIOB18_X81Y303,IOB_X0Y292,dio[208],LVCMOS18,8,FAST,PULLUP
211 LIOB18_X81Y305,IOB_X0Y293,dio[209],LVCMOS18,6,SLOW,KEEPER
212 LIOB18_X81Y305,IOB_X0Y294,dio[210],LVCMOS18,6,SLOW,NONE
213 LIOB18_X81Y307,IOB_X0Y295,dio[211],LVCMOS18,8,SLOW,PULLUP
214 LIOB18_X81Y307,IOB_X0Y296,dio[212],LVCMOS18,6,SLOW,PULLUP
215 LIOB18_X81Y309,IOB_X0Y297,dio[213],LVCMOS18,8,SLOW,PULLDOWN
216 LIOB18_X81Y309,IOB_X0Y298,dio[214],LVCMOS18,4,FAST,PULLDOWN
217 LIOB18_X81Y31,IOB_X0Y29,dio[215],LVCMOS18,4,SLOW,NONE
218 LIOB18_X81Y31,IOB_X0Y30,dio[216],LVCMOS18,12,SLOW,PULLDOWN
219 LIOB18_X81Y314,IOB_X0Y301,dio[217],LVCMOS18,8,SLOW,PULLDOWN
220 LIOB18_X81Y314,IOB_X0Y302,dio[218],LVCMOS18,2,FAST,PULLUP
221 LIOB18_X81Y316,IOB_X0Y303,dio[219],LVCMOS18,8,FAST,KEEPER
222 LIOB18_X81Y316,IOB_X0Y304,dio[220],LVCMOS18,12,SLOW,NONE
223 LIOB18_X81Y318,IOB_X0Y305,dio[221],LVCMOS18,8,SLOW,PULLDOWN
224 LIOB18_X81Y318,IOB_X0Y306,dio[222],LVCMOS18,12,SLOW,NONE
225 LIOB18_X81Y320,IOB_X0Y307,dio[223],LVCMOS18,12,SLOW,KEEPER
226 LIOB18_X81Y320,IOB_X0Y308,dio[224],LVCMOS18,8,FAST,PULLUP
227 LIOB18_X81Y322,IOB_X0Y309,dio[225],LVCMOS18,12,FAST,NONE
228 LIOB18_X81Y322,IOB_X0Y310,dio[226],LVCMOS18,8,SLOW,KEEPER
229 LIOB18_X81Y324,IOB_X0Y311,dio[227],LVCMOS18,12,SLOW,NONE
230 LIOB18_X81Y324,IOB_X0Y312,dio[228],LVCMOS18,4,SLOW,KEEPER
231 LIOB18_X81Y326,IOB_X0Y313,dio[229],LVCMOS18,8,FAST,PULLUP
232 LIOB18_X81Y326,IOB_X0Y314,dio[230],LVCMOS18,16,FAST,KEEPER
233 LIOB18_X81Y328,IOB_X0Y315,dio[231],LVCMOS18,16,SLOW,PULLUP
234 LIOB18_X81Y328,IOB_X0Y316,dio[232],LVCMOS18,6,FAST,NONE
235 LIOB18_X81Y33,IOB_X0Y31,dio[233],LVCMOS18,8,FAST,PULLUP
236 LIOB18_X81Y33,IOB_X0Y32,dio[234],LVCMOS18,6,FAST,PULLUP
237 LIOB18_X81Y330,IOB_X0Y317,dio[235],LVCMOS18,16,FAST,KEEPER
238 LIOB18_X81Y330,IOB_X0Y318,dio[236],LVCMOS18,16,SLOW,PULLUP
239 LIOB18_X81Y332,IOB_X0Y319,dio[237],LVCMOS18,8,SLOW,PULLDOWN
240 LIOB18_X81Y332,IOB_X0Y320,dio[238],LVCMOS18,16,FAST,PULLDOWN
241 LIOB18_X81Y334,IOB_X0Y321,dio[239],LVCMOS18,12,SLOW,KEEPER
242 LIOB18_X81Y334,IOB_X0Y322,dio[240],LVCMOS18,2,SLOW,KEEPER
243 LIOB18_X81Y336,IOB_X0Y323,dio[241],LVCMOS18,8,SLOW,KEEPER
244 LIOB18_X81Y336,IOB_X0Y324,dio[242],LVCMOS18,8,SLOW,NONE
245 LIOB18_X81Y339,IOB_X0Y325,dio[243],LVCMOS18,6,FAST,PULLDOWN
246 LIOB18_X81Y339,IOB_X0Y326,dio[244],LVCMOS18,4,SLOW,NONE
247 LIOB18_X81Y341,IOB_X0Y327,dio[245],LVCMOS18,6,FAST,PULLUP
248 LIOB18_X81Y341,IOB_X0Y328,dio[246],LVCMOS18,2,SLOW,NONE
249 LIOB18_X81Y343,IOB_X0Y329,dio[247],LVCMOS18,12,SLOW,PULLUP
250 LIOB18_X81Y343,IOB_X0Y330,dio[248],LVCMOS18,2,FAST,NONE
251 LIOB18_X81Y345,IOB_X0Y331,dio[249],LVCMOS18,16,FAST,NONE
252 LIOB18_X81Y345,IOB_X0Y332,dio[250],LVCMOS18,12,FAST,NONE
253 LIOB18_X81Y347,IOB_X0Y333,dio[251],LVCMOS18,6,SLOW,NONE
254 LIOB18_X81Y347,IOB_X0Y334,dio[252],LVCMOS18,4,FAST,NONE
255 LIOB18_X81Y349,IOB_X0Y335,dio[253],LVCMOS18,4,FAST,PULLDOWN
256 LIOB18_X81Y349,IOB_X0Y336,dio[254],LVCMOS18,16,SLOW,KEEPER
257 LIOB18_X81Y35,IOB_X0Y33,dio[255],LVCMOS18,2,FAST,PULLUP
258 LIOB18_X81Y35,IOB_X0Y34,dio[256],LVCMOS18,12,FAST,PULLDOWN
259 LIOB18_X81Y351,IOB_X0Y337,dio[257],LVCMOS18,2,SLOW,NONE
260 LIOB18_X81Y351,IOB_X0Y338,dio[258],LVCMOS18,12,FAST,NONE
261 LIOB18_X81Y353,IOB_X0Y339,dio[259],LVCMOS18,8,SLOW,NONE
262 LIOB18_X81Y353,IOB_X0Y340,dio[260],LVCMOS18,16,FAST,NONE
263 LIOB18_X81Y355,IOB_X0Y341,dio[261],LVCMOS18,6,FAST,PULLUP
264 LIOB18_X81Y355,IOB_X0Y342,dio[262],LVCMOS18,16,FAST,KEEPER
265 LIOB18_X81Y357,IOB_X0Y343,dio[263],LVCMOS18,2,SLOW,PULLDOWN
266 LIOB18_X81Y357,IOB_X0Y344,dio[264],LVCMOS18,6,SLOW,PULLDOWN
267 LIOB18_X81Y359,IOB_X0Y345,dio[265],LVCMOS18,12,SLOW,PULLDOWN
268 LIOB18_X81Y359,IOB_X0Y346,dio[266],LVCMOS18,6,FAST,PULLDOWN
269 LIOB18_X81Y361,IOB_X0Y347,dio[267],LVCMOS18,12,FAST,PULLDOWN
270 LIOB18_X81Y361,IOB_X0Y348,dio[268],LVCMOS18,16,FAST,PULLUP
271 LIOB18_X81Y37,IOB_X0Y35,dio[269],LVCMOS18,6,FAST,PULLDOWN
272 LIOB18_X81Y37,IOB_X0Y36,dio[270],LVCMOS18,2,FAST,NONE
273 LIOB18_X81Y39,IOB_X0Y37,dio[271],LVCMOS18,6,FAST,PULLUP
274 LIOB18_X81Y39,IOB_X0Y38,dio[272],LVCMOS18,16,FAST,KEEPER
275 LIOB18_X81Y4,IOB_X0Y3,dio[273],LVCMOS18,16,SLOW,KEEPER
276 LIOB18_X81Y4,IOB_X0Y4,dio[274],LVCMOS18,8,FAST,PULLUP
277 LIOB18_X81Y41,IOB_X0Y39,dio[275],LVCMOS18,12,SLOW,KEEPER
278 LIOB18_X81Y41,IOB_X0Y40,dio[276],LVCMOS18,8,SLOW,PULLUP
279 LIOB18_X81Y43,IOB_X0Y41,dio[277],LVCMOS18,16,SLOW,NONE
280 LIOB18_X81Y43,IOB_X0Y42,dio[278],LVCMOS18,6,FAST,PULLDOWN
281 LIOB18_X81Y45,IOB_X0Y43,dio[279],LVCMOS18,16,SLOW,KEEPER
282 LIOB18_X81Y45,IOB_X0Y44,dio[280],LVCMOS18,16,SLOW,NONE
283 LIOB18_X81Y47,IOB_X0Y45,dio[281],LVCMOS18,4,FAST,KEEPER
284 LIOB18_X81Y47,IOB_X0Y46,dio[282],LVCMOS18,4,FAST,NONE
285 LIOB18_X81Y49,IOB_X0Y47,dio[283],LVCMOS18,12,SLOW,NONE
286 LIOB18_X81Y49,IOB_X0Y48,dio[284],LVCMOS18,8,FAST,KEEPER
287 LIOB18_X81Y54,IOB_X0Y51,dio[285],LVCMOS18,12,FAST,KEEPER
288 LIOB18_X81Y54,IOB_X0Y52,dio[286],LVCMOS18,2,SLOW,PULLDOWN
289 LIOB18_X81Y56,IOB_X0Y53,dio[287],LVCMOS18,16,FAST,NONE
290 LIOB18_X81Y56,IOB_X0Y54,dio[288],LVCMOS18,8,SLOW,KEEPER
291 LIOB18_X81Y58,IOB_X0Y55,dio[289],LVCMOS18,4,SLOW,KEEPER
292 LIOB18_X81Y58,IOB_X0Y56,dio[290],LVCMOS18,8,FAST,PULLDOWN
293 LIOB18_X81Y6,IOB_X0Y5,dio[291],LVCMOS18,8,SLOW,KEEPER
294 LIOB18_X81Y6,IOB_X0Y6,dio[292],LVCMOS18,6,SLOW,PULLUP
295 LIOB18_X81Y60,IOB_X0Y57,dio[293],LVCMOS18,16,FAST,PULLDOWN
296 LIOB18_X81Y60,IOB_X0Y58,dio[294],LVCMOS18,6,SLOW,KEEPER
297 LIOB18_X81Y62,IOB_X0Y59,dio[295],LVCMOS18,6,FAST,KEEPER
298 LIOB18_X81Y62,IOB_X0Y60,dio[296],LVCMOS18,6,FAST,PULLDOWN
299 LIOB18_X81Y64,IOB_X0Y61,dio[297],LVCMOS18,8,SLOW,PULLUP
300 LIOB18_X81Y64,IOB_X0Y62,dio[298],LVCMOS18,2,SLOW,NONE
301 LIOB18_X81Y66,IOB_X0Y63,dio[299],LVCMOS18,16,FAST,PULLUP
302 LIOB18_X81Y66,IOB_X0Y64,dio[300],LVCMOS18,16,SLOW,PULLUP
303 LIOB18_X81Y68,IOB_X0Y65,dio[301],LVCMOS18,2,SLOW,KEEPER
304 LIOB18_X81Y68,IOB_X0Y66,dio[302],LVCMOS18,4,FAST,KEEPER
305 LIOB18_X81Y70,IOB_X0Y67,dio[303],LVCMOS18,2,FAST,PULLUP
306 LIOB18_X81Y70,IOB_X0Y68,dio[304],LVCMOS18,4,SLOW,NONE
307 LIOB18_X81Y72,IOB_X0Y69,dio[305],LVCMOS18,4,SLOW,KEEPER
308 LIOB18_X81Y72,IOB_X0Y70,dio[306],LVCMOS18,8,SLOW,PULLDOWN
309 LIOB18_X81Y74,IOB_X0Y71,dio[307],LVCMOS18,2,FAST,PULLDOWN
310 LIOB18_X81Y74,IOB_X0Y72,dio[308],LVCMOS18,6,SLOW,NONE
311 LIOB18_X81Y76,IOB_X0Y73,dio[309],LVCMOS18,8,SLOW,NONE
312 LIOB18_X81Y76,IOB_X0Y74,dio[310],LVCMOS18,12,FAST,KEEPER
313 LIOB18_X81Y79,IOB_X0Y75,dio[311],LVCMOS18,2,SLOW,KEEPER
314 LIOB18_X81Y79,IOB_X0Y76,dio[312],LVCMOS18,12,SLOW,NONE
315 LIOB18_X81Y8,IOB_X0Y7,dio[313],LVCMOS18,4,SLOW,PULLDOWN
316 LIOB18_X81Y8,IOB_X0Y8,dio[314],LVCMOS18,12,FAST,NONE
317 LIOB18_X81Y81,IOB_X0Y77,dio[315],LVCMOS18,12,SLOW,KEEPER
318 LIOB18_X81Y81,IOB_X0Y78,dio[316],LVCMOS18,2,FAST,NONE
319 LIOB18_X81Y83,IOB_X0Y79,dio[317],LVCMOS18,16,FAST,NONE
320 LIOB18_X81Y83,IOB_X0Y80,dio[318],LVCMOS18,16,SLOW,PULLDOWN
321 LIOB18_X81Y85,IOB_X0Y81,dio[319],LVCMOS18,4,SLOW,PULLDOWN
322 LIOB18_X81Y85,IOB_X0Y82,dio[320],LVCMOS18,4,FAST,PULLDOWN
323 LIOB18_X81Y87,IOB_X0Y83,dio[321],LVCMOS18,8,SLOW,PULLUP
324 LIOB18_X81Y87,IOB_X0Y84,dio[322],LVCMOS18,6,FAST,NONE
325 LIOB18_X81Y89,IOB_X0Y85,dio[323],LVCMOS18,16,FAST,PULLDOWN
326 LIOB18_X81Y89,IOB_X0Y86,dio[324],LVCMOS18,16,SLOW,KEEPER
327 LIOB18_X81Y91,IOB_X0Y87,dio[325],LVCMOS18,6,SLOW,KEEPER
328 LIOB18_X81Y91,IOB_X0Y88,dio[326],LVCMOS18,8,SLOW,PULLUP
329 LIOB18_X81Y93,IOB_X0Y89,dio[327],LVCMOS18,8,SLOW,PULLUP
330 LIOB18_X81Y93,IOB_X0Y90,dio[328],LVCMOS18,16,FAST,NONE
331 LIOB18_X81Y95,IOB_X0Y91,dio[329],LVCMOS18,12,FAST,PULLUP
332 LIOB18_X81Y95,IOB_X0Y92,dio[330],LVCMOS18,16,FAST,PULLUP
333 LIOB18_X81Y97,IOB_X0Y93,dio[331],LVCMOS18,16,FAST,PULLUP
334 LIOB18_X81Y97,IOB_X0Y94,dio[332],LVCMOS18,12,SLOW,PULLUP
335 LIOB18_X81Y99,IOB_X0Y95,dio[333],LVCMOS18,6,FAST,PULLUP
336 LIOB18_X81Y99,IOB_X0Y96,dio[334],LVCMOS18,4,FAST,NONE
337 RIOB18_X312Y10,IOB_X1Y9,dio[335],LVCMOS18,6,SLOW,PULLDOWN
338 RIOB18_X312Y10,IOB_X1Y10,dio[336],LVCMOS18,2,FAST,PULLUP
339 RIOB18_X312Y101,IOB_X1Y97,dio[337],LVCMOS18,4,FAST,PULLUP
340 RIOB18_X312Y101,IOB_X1Y98,dio[338],LVCMOS18,6,SLOW,KEEPER
341 RIOB18_X312Y106,IOB_X1Y101,dio[339],LVCMOS18,12,SLOW,PULLUP
342 RIOB18_X312Y106,IOB_X1Y102,dio[340],LVCMOS18,6,SLOW,PULLUP
343 RIOB18_X312Y108,IOB_X1Y103,dio[341],LVCMOS18,8,FAST,NONE
344 RIOB18_X312Y108,IOB_X1Y104,dio[342],LVCMOS18,6,SLOW,PULLDOWN
345 RIOB18_X312Y110,IOB_X1Y105,dio[343],LVCMOS18,6,FAST,PULLUP
346 RIOB18_X312Y110,IOB_X1Y106,dio[344],LVCMOS18,2,FAST,KEEPER
347 RIOB18_X312Y112,IOB_X1Y107,dio[345],LVCMOS18,2,FAST,NONE
348 RIOB18_X312Y112,IOB_X1Y108,dio[346],LVCMOS18,6,SLOW,NONE
349 RIOB18_X312Y114,IOB_X1Y109,dio[347],LVCMOS18,8,FAST,PULLUP
350 RIOB18_X312Y114,IOB_X1Y110,dio[348],LVCMOS18,16,FAST,PULLUP
351 RIOB18_X312Y116,IOB_X1Y111,dio[349],LVCMOS18,16,FAST,PULLDOWN
352 RIOB18_X312Y116,IOB_X1Y112,dio[350],LVCMOS18,12,SLOW,PULLUP
353 RIOB18_X312Y118,IOB_X1Y113,dio[351],LVCMOS18,8,SLOW,PULLUP
354 RIOB18_X312Y118,IOB_X1Y114,dio[352],LVCMOS18,4,FAST,KEEPER
355 RIOB18_X312Y12,IOB_X1Y11,dio[353],LVCMOS18,2,FAST,KEEPER
356 RIOB18_X312Y12,IOB_X1Y12,dio[354],LVCMOS18,4,SLOW,PULLUP
357 RIOB18_X312Y120,IOB_X1Y115,dio[355],LVCMOS18,6,SLOW,KEEPER
358 RIOB18_X312Y120,IOB_X1Y116,dio[356],LVCMOS18,16,SLOW,PULLDOWN
359 RIOB18_X312Y122,IOB_X1Y117,dio[357],LVCMOS18,16,SLOW,PULLUP
360 RIOB18_X312Y122,IOB_X1Y118,dio[358],LVCMOS18,6,FAST,PULLDOWN
361 RIOB18_X312Y124,IOB_X1Y119,dio[359],LVCMOS18,6,FAST,NONE
362 RIOB18_X312Y124,IOB_X1Y120,dio[360],LVCMOS18,2,FAST,PULLDOWN
363 RIOB18_X312Y126,IOB_X1Y121,dio[361],LVCMOS18,12,FAST,PULLUP
364 RIOB18_X312Y126,IOB_X1Y122,dio[362],LVCMOS18,12,FAST,KEEPER
365 RIOB18_X312Y128,IOB_X1Y123,dio[363],LVCMOS18,6,SLOW,PULLDOWN
366 RIOB18_X312Y128,IOB_X1Y124,dio[364],LVCMOS18,6,FAST,NONE
367 RIOB18_X312Y131,IOB_X1Y125,dio[365],LVCMOS18,4,FAST,PULLUP
368 RIOB18_X312Y131,IOB_X1Y126,dio[366],LVCMOS18,6,FAST,NONE
369 RIOB18_X312Y133,IOB_X1Y127,dio[367],LVCMOS18,2,SLOW,PULLDOWN
370 RIOB18_X312Y133,IOB_X1Y128,dio[368],LVCMOS18,8,SLOW,NONE
371 RIOB18_X312Y135,IOB_X1Y129,dio[369],LVCMOS18,12,SLOW,KEEPER
372 RIOB18_X312Y135,IOB_X1Y130,dio[370],LVCMOS18,12,SLOW,NONE
373 RIOB18_X312Y137,IOB_X1Y131,dio[371],LVCMOS18,4,SLOW,PULLDOWN
374 RIOB18_X312Y137,IOB_X1Y132,dio[372],LVCMOS18,6,SLOW,PULLDOWN
375 RIOB18_X312Y139,IOB_X1Y133,dio[373],LVCMOS18,16,SLOW,PULLUP
376 RIOB18_X312Y139,IOB_X1Y134,dio[374],LVCMOS18,8,FAST,KEEPER
377 RIOB18_X312Y14,IOB_X1Y13,dio[375],LVCMOS18,8,SLOW,NONE
378 RIOB18_X312Y14,IOB_X1Y14,dio[376],LVCMOS18,16,SLOW,PULLUP
379 RIOB18_X312Y141,IOB_X1Y135,dio[377],LVCMOS18,16,FAST,KEEPER
380 RIOB18_X312Y141,IOB_X1Y136,dio[378],LVCMOS18,2,FAST,NONE
381 RIOB18_X312Y143,IOB_X1Y137,dio[379],LVCMOS18,2,FAST,KEEPER
382 RIOB18_X312Y143,IOB_X1Y138,dio[380],LVCMOS18,6,SLOW,PULLUP
383 RIOB18_X312Y145,IOB_X1Y139,dio[381],LVCMOS18,6,FAST,PULLDOWN
384 RIOB18_X312Y145,IOB_X1Y140,dio[382],LVCMOS18,8,FAST,NONE
385 RIOB18_X312Y147,IOB_X1Y141,dio[383],LVCMOS18,4,FAST,NONE
386 RIOB18_X312Y147,IOB_X1Y142,dio[384],LVCMOS18,4,FAST,NONE
387 RIOB18_X312Y149,IOB_X1Y143,dio[385],LVCMOS18,8,SLOW,NONE
388 RIOB18_X312Y149,IOB_X1Y144,dio[386],LVCMOS18,12,SLOW,NONE
389 RIOB18_X312Y151,IOB_X1Y145,dio[387],LVCMOS18,12,SLOW,PULLDOWN
390 RIOB18_X312Y151,IOB_X1Y146,dio[388],LVCMOS18,16,SLOW,KEEPER
391 RIOB18_X312Y153,IOB_X1Y147,dio[389],LVCMOS18,12,FAST,PULLDOWN
392 RIOB18_X312Y153,IOB_X1Y148,dio[390],LVCMOS18,16,SLOW,KEEPER
393 RIOB18_X312Y158,IOB_X1Y151,dio[391],LVCMOS18,4,SLOW,KEEPER
394 RIOB18_X312Y158,IOB_X1Y152,dio[392],LVCMOS18,8,SLOW,PULLDOWN
395 RIOB18_X312Y16,IOB_X1Y15,dio[393],LVCMOS18,16,SLOW,KEEPER
396 RIOB18_X312Y16,IOB_X1Y16,dio[394],LVCMOS18,12,SLOW,PULLUP
397 RIOB18_X312Y160,IOB_X1Y153,dio[395],LVCMOS18,4,SLOW,PULLDOWN
398 RIOB18_X312Y160,IOB_X1Y154,dio[396],LVCMOS18,6,SLOW,KEEPER
399 RIOB18_X312Y162,IOB_X1Y155,dio[397],LVCMOS18,2,FAST,KEEPER
400 RIOB18_X312Y162,IOB_X1Y156,dio[398],LVCMOS18,8,SLOW,PULLUP
401 RIOB18_X312Y164,IOB_X1Y157,dio[399],LVCMOS18,8,FAST,PULLUP
402 RIOB18_X312Y164,IOB_X1Y158,dio[400],LVCMOS18,8,SLOW,NONE
403 RIOB18_X312Y166,IOB_X1Y159,dio[401],LVCMOS18,8,FAST,NONE
404 RIOB18_X312Y166,IOB_X1Y160,dio[402],LVCMOS18,2,SLOW,NONE
405 RIOB18_X312Y168,IOB_X1Y161,dio[403],LVCMOS18,6,SLOW,KEEPER
406 RIOB18_X312Y168,IOB_X1Y162,dio[404],LVCMOS18,6,FAST,NONE
407 RIOB18_X312Y170,IOB_X1Y163,dio[405],LVCMOS18,4,SLOW,PULLDOWN
408 RIOB18_X312Y170,IOB_X1Y164,dio[406],LVCMOS18,4,FAST,PULLDOWN
409 RIOB18_X312Y172,IOB_X1Y165,dio[407],LVCMOS18,8,SLOW,NONE
410 RIOB18_X312Y172,IOB_X1Y166,dio[408],LVCMOS18,6,SLOW,KEEPER
411 RIOB18_X312Y174,IOB_X1Y167,dio[409],LVCMOS18,2,FAST,PULLDOWN
412 RIOB18_X312Y174,IOB_X1Y168,dio[410],LVCMOS18,16,FAST,KEEPER
413 RIOB18_X312Y176,IOB_X1Y169,dio[411],LVCMOS18,16,FAST,NONE
414 RIOB18_X312Y176,IOB_X1Y170,dio[412],LVCMOS18,12,SLOW,KEEPER
415 RIOB18_X312Y178,IOB_X1Y171,dio[413],LVCMOS18,8,FAST,PULLUP
416 RIOB18_X312Y178,IOB_X1Y172,dio[414],LVCMOS18,16,FAST,KEEPER
417 RIOB18_X312Y18,IOB_X1Y17,dio[415],LVCMOS18,8,SLOW,PULLDOWN
418 RIOB18_X312Y18,IOB_X1Y18,dio[416],LVCMOS18,8,SLOW,NONE
419 RIOB18_X312Y180,IOB_X1Y173,dio[417],LVCMOS18,12,SLOW,PULLDOWN
420 RIOB18_X312Y180,IOB_X1Y174,dio[418],LVCMOS18,6,FAST,PULLDOWN
421 RIOB18_X312Y183,IOB_X1Y175,dio[419],LVCMOS18,4,FAST,PULLUP
422 RIOB18_X312Y183,IOB_X1Y176,dio[420],LVCMOS18,6,SLOW,PULLUP
423 RIOB18_X312Y185,IOB_X1Y177,dio[421],LVCMOS18,12,FAST,PULLUP
424 RIOB18_X312Y185,IOB_X1Y178,dio[422],LVCMOS18,2,SLOW,PULLDOWN
425 RIOB18_X312Y187,IOB_X1Y179,dio[423],LVCMOS18,4,FAST,NONE
426 RIOB18_X312Y187,IOB_X1Y180,dio[424],LVCMOS18,4,FAST,NONE
427 RIOB18_X312Y189,IOB_X1Y181,dio[425],LVCMOS18,16,FAST,PULLUP
428 RIOB18_X312Y189,IOB_X1Y182,dio[426],LVCMOS18,6,SLOW,PULLDOWN
429 RIOB18_X312Y191,IOB_X1Y183,dio[427],LVCMOS18,6,SLOW,NONE
430 RIOB18_X312Y191,IOB_X1Y184,dio[428],LVCMOS18,16,SLOW,PULLDOWN
431 RIOB18_X312Y193,IOB_X1Y185,dio[429],LVCMOS18,8,FAST,PULLUP
432 RIOB18_X312Y193,IOB_X1Y186,dio[430],LVCMOS18,12,FAST,PULLUP
433 RIOB18_X312Y195,IOB_X1Y187,dio[431],LVCMOS18,4,FAST,NONE
434 RIOB18_X312Y195,IOB_X1Y188,dio[432],LVCMOS18,8,SLOW,PULLUP
435 RIOB18_X312Y197,IOB_X1Y189,dio[433],LVCMOS18,16,FAST,PULLDOWN
436 RIOB18_X312Y197,IOB_X1Y190,dio[434],LVCMOS18,4,SLOW,NONE
437 RIOB18_X312Y199,IOB_X1Y191,dio[435],LVCMOS18,8,FAST,NONE
438 RIOB18_X312Y199,IOB_X1Y192,dio[436],LVCMOS18,6,SLOW,PULLUP
439 RIOB18_X312Y2,IOB_X1Y1,dio[437],LVCMOS18,8,SLOW,NONE
440 RIOB18_X312Y2,IOB_X1Y2,dio[438],LVCMOS18,6,SLOW,KEEPER
441 RIOB18_X312Y20,IOB_X1Y19,dio[439],LVCMOS18,12,FAST,PULLUP
442 RIOB18_X312Y20,IOB_X1Y20,dio[440],LVCMOS18,16,SLOW,PULLUP
443 RIOB18_X312Y201,IOB_X1Y193,dio[441],LVCMOS18,12,SLOW,NONE
444 RIOB18_X312Y201,IOB_X1Y194,dio[442],LVCMOS18,8,SLOW,KEEPER
445 RIOB18_X312Y203,IOB_X1Y195,dio[443],LVCMOS18,6,FAST,PULLDOWN
446 RIOB18_X312Y203,IOB_X1Y196,dio[444],LVCMOS18,16,SLOW,PULLDOWN
447 RIOB18_X312Y205,IOB_X1Y197,dio[445],LVCMOS18,16,SLOW,PULLUP
448 RIOB18_X312Y205,IOB_X1Y198,dio[446],LVCMOS18,6,FAST,NONE
449 RIOB18_X312Y210,IOB_X1Y201,dio[447],LVCMOS18,4,FAST,KEEPER
450 RIOB18_X312Y210,IOB_X1Y202,dio[448],LVCMOS18,8,FAST,PULLDOWN
451 RIOB18_X312Y212,IOB_X1Y203,dio[449],LVCMOS18,2,SLOW,PULLUP
452 RIOB18_X312Y212,IOB_X1Y204,dio[450],LVCMOS18,6,SLOW,KEEPER
453 RIOB18_X312Y214,IOB_X1Y205,dio[451],LVCMOS18,12,FAST,PULLDOWN
454 RIOB18_X312Y214,IOB_X1Y206,dio[452],LVCMOS18,8,FAST,NONE
455 RIOB18_X312Y216,IOB_X1Y207,dio[453],LVCMOS18,8,FAST,KEEPER
456 RIOB18_X312Y216,IOB_X1Y208,dio[454],LVCMOS18,12,SLOW,NONE
457 RIOB18_X312Y218,IOB_X1Y209,dio[455],LVCMOS18,8,SLOW,KEEPER
458 RIOB18_X312Y218,IOB_X1Y210,dio[456],LVCMOS18,4,SLOW,PULLDOWN
459 RIOB18_X312Y22,IOB_X1Y21,dio[457],LVCMOS18,16,SLOW,PULLDOWN
460 RIOB18_X312Y22,IOB_X1Y22,dio[458],LVCMOS18,16,SLOW,KEEPER
461 RIOB18_X312Y220,IOB_X1Y211,dio[459],LVCMOS18,2,SLOW,NONE
462 RIOB18_X312Y220,IOB_X1Y212,dio[460],LVCMOS18,12,FAST,KEEPER
463 RIOB18_X312Y222,IOB_X1Y213,dio[461],LVCMOS18,6,FAST,PULLDOWN
464 RIOB18_X312Y222,IOB_X1Y214,dio[462],LVCMOS18,2,FAST,NONE
465 RIOB18_X312Y224,IOB_X1Y215,dio[463],LVCMOS18,16,FAST,NONE
466 RIOB18_X312Y224,IOB_X1Y216,dio[464],LVCMOS18,12,FAST,NONE
467 RIOB18_X312Y226,IOB_X1Y217,dio[465],LVCMOS18,6,FAST,PULLUP
468 RIOB18_X312Y226,IOB_X1Y218,dio[466],LVCMOS18,6,SLOW,PULLDOWN
469 RIOB18_X312Y228,IOB_X1Y219,dio[467],LVCMOS18,8,FAST,NONE
470 RIOB18_X312Y228,IOB_X1Y220,dio[468],LVCMOS18,8,SLOW,PULLDOWN
471 RIOB18_X312Y230,IOB_X1Y221,dio[469],LVCMOS18,4,SLOW,PULLDOWN
472 RIOB18_X312Y230,IOB_X1Y222,dio[470],LVCMOS18,16,FAST,NONE
473 RIOB18_X312Y232,IOB_X1Y223,dio[471],LVCMOS18,8,FAST,NONE
474 RIOB18_X312Y232,IOB_X1Y224,dio[472],LVCMOS18,8,SLOW,PULLDOWN
475 RIOB18_X312Y235,IOB_X1Y225,dio[473],LVCMOS18,4,SLOW,PULLDOWN
476 RIOB18_X312Y235,IOB_X1Y226,dio[474],LVCMOS18,8,SLOW,PULLDOWN
477 RIOB18_X312Y237,IOB_X1Y227,dio[475],LVCMOS18,16,FAST,PULLDOWN
478 RIOB18_X312Y237,IOB_X1Y228,dio[476],LVCMOS18,8,SLOW,KEEPER
479 RIOB18_X312Y239,IOB_X1Y229,dio[477],LVCMOS18,4,SLOW,NONE
480 RIOB18_X312Y239,IOB_X1Y230,dio[478],LVCMOS18,8,SLOW,KEEPER
481 RIOB18_X312Y24,IOB_X1Y23,dio[479],LVCMOS18,16,SLOW,NONE
482 RIOB18_X312Y24,IOB_X1Y24,dio[480],LVCMOS18,6,SLOW,KEEPER
483 RIOB18_X312Y241,IOB_X1Y231,dio[481],LVCMOS18,8,SLOW,NONE
484 RIOB18_X312Y241,IOB_X1Y232,dio[482],LVCMOS18,6,SLOW,PULLUP
485 RIOB18_X312Y243,IOB_X1Y233,dio[483],LVCMOS18,2,SLOW,PULLDOWN
486 RIOB18_X312Y243,IOB_X1Y234,dio[484],LVCMOS18,2,SLOW,PULLUP
487 RIOB18_X312Y245,IOB_X1Y235,dio[485],LVCMOS18,6,SLOW,KEEPER
488 RIOB18_X312Y245,IOB_X1Y236,dio[486],LVCMOS18,8,SLOW,PULLDOWN
489 RIOB18_X312Y247,IOB_X1Y237,dio[487],LVCMOS18,16,FAST,NONE
490 RIOB18_X312Y247,IOB_X1Y238,dio[488],LVCMOS18,2,SLOW,NONE
491 RIOB18_X312Y249,IOB_X1Y239,dio[489],LVCMOS18,16,FAST,PULLUP
492 RIOB18_X312Y249,IOB_X1Y240,dio[490],LVCMOS18,2,SLOW,PULLDOWN
493 RIOB18_X312Y251,IOB_X1Y241,dio[491],LVCMOS18,12,FAST,PULLUP
494 RIOB18_X312Y251,IOB_X1Y242,dio[492],LVCMOS18,8,SLOW,KEEPER
495 RIOB18_X312Y253,IOB_X1Y243,dio[493],LVCMOS18,6,SLOW,PULLUP
496 RIOB18_X312Y253,IOB_X1Y244,dio[494],LVCMOS18,16,FAST,KEEPER
497 RIOB18_X312Y255,IOB_X1Y245,dio[495],LVCMOS18,2,SLOW,PULLDOWN
498 RIOB18_X312Y255,IOB_X1Y246,dio[496],LVCMOS18,2,SLOW,NONE
499 RIOB18_X312Y257,IOB_X1Y247,dio[497],LVCMOS18,8,SLOW,PULLUP
500 RIOB18_X312Y257,IOB_X1Y248,dio[498],LVCMOS18,16,SLOW,PULLUP
501 RIOB18_X312Y262,IOB_X1Y251,dio[499],LVCMOS18,16,SLOW,PULLDOWN
502 RIOB18_X312Y262,IOB_X1Y252,dio[500],LVCMOS18,2,SLOW,KEEPER
503 RIOB18_X312Y264,IOB_X1Y253,dio[501],LVCMOS18,6,FAST,PULLDOWN
504 RIOB18_X312Y264,IOB_X1Y254,dio[502],LVCMOS18,16,SLOW,NONE
505 RIOB18_X312Y266,IOB_X1Y255,dio[503],LVCMOS18,12,SLOW,KEEPER
506 RIOB18_X312Y266,IOB_X1Y256,dio[504],LVCMOS18,12,FAST,PULLDOWN
507 RIOB18_X312Y268,IOB_X1Y257,dio[505],LVCMOS18,6,FAST,KEEPER
508 RIOB18_X312Y268,IOB_X1Y258,dio[506],LVCMOS18,4,FAST,NONE
509 RIOB18_X312Y27,IOB_X1Y25,dio[507],LVCMOS18,16,FAST,NONE
510 RIOB18_X312Y27,IOB_X1Y26,dio[508],LVCMOS18,8,FAST,KEEPER
511 RIOB18_X312Y270,IOB_X1Y259,dio[509],LVCMOS18,2,FAST,PULLDOWN
512 RIOB18_X312Y270,IOB_X1Y260,dio[510],LVCMOS18,2,FAST,PULLUP
513 RIOB18_X312Y272,IOB_X1Y261,dio[511],LVCMOS18,16,SLOW,PULLDOWN
514 RIOB18_X312Y272,IOB_X1Y262,dio[512],LVCMOS18,4,SLOW,PULLDOWN
515 RIOB18_X312Y274,IOB_X1Y263,dio[513],LVCMOS18,8,FAST,PULLUP
516 RIOB18_X312Y274,IOB_X1Y264,dio[514],LVCMOS18,16,FAST,NONE
517 RIOB18_X312Y276,IOB_X1Y265,dio[515],LVCMOS18,4,FAST,PULLDOWN
518 RIOB18_X312Y276,IOB_X1Y266,dio[516],LVCMOS18,6,SLOW,PULLUP
519 RIOB18_X312Y278,IOB_X1Y267,dio[517],LVCMOS18,8,SLOW,NONE
520 RIOB18_X312Y278,IOB_X1Y268,dio[518],LVCMOS18,4,SLOW,PULLUP
521 RIOB18_X312Y280,IOB_X1Y269,dio[519],LVCMOS18,12,FAST,PULLUP
522 RIOB18_X312Y280,IOB_X1Y270,dio[520],LVCMOS18,16,SLOW,PULLUP
523 RIOB18_X312Y282,IOB_X1Y271,dio[521],LVCMOS18,16,SLOW,NONE
524 RIOB18_X312Y282,IOB_X1Y272,dio[522],LVCMOS18,8,SLOW,PULLDOWN
525 RIOB18_X312Y284,IOB_X1Y273,dio[523],LVCMOS18,8,SLOW,PULLDOWN
526 RIOB18_X312Y284,IOB_X1Y274,dio[524],LVCMOS18,2,SLOW,KEEPER
527 RIOB18_X312Y287,IOB_X1Y275,dio[525],LVCMOS18,2,FAST,PULLDOWN
528 RIOB18_X312Y287,IOB_X1Y276,dio[526],LVCMOS18,6,FAST,PULLDOWN
529 RIOB18_X312Y289,IOB_X1Y277,dio[527],LVCMOS18,16,SLOW,PULLDOWN
530 RIOB18_X312Y289,IOB_X1Y278,dio[528],LVCMOS18,4,FAST,PULLDOWN
531 RIOB18_X312Y29,IOB_X1Y27,dio[529],LVCMOS18,4,SLOW,PULLDOWN
532 RIOB18_X312Y29,IOB_X1Y28,dio[530],LVCMOS18,8,FAST,NONE
533 RIOB18_X312Y291,IOB_X1Y279,dio[531],LVCMOS18,8,SLOW,PULLDOWN
534 RIOB18_X312Y291,IOB_X1Y280,dio[532],LVCMOS18,16,FAST,PULLDOWN
535 RIOB18_X312Y293,IOB_X1Y281,dio[533],LVCMOS18,8,FAST,PULLDOWN
536 RIOB18_X312Y293,IOB_X1Y282,dio[534],LVCMOS18,6,SLOW,NONE
537 RIOB18_X312Y295,IOB_X1Y283,dio[535],LVCMOS18,2,FAST,NONE
538 RIOB18_X312Y295,IOB_X1Y284,dio[536],LVCMOS18,8,FAST,NONE
539 RIOB18_X312Y297,IOB_X1Y285,dio[537],LVCMOS18,16,FAST,PULLDOWN
540 RIOB18_X312Y297,IOB_X1Y286,dio[538],LVCMOS18,4,SLOW,KEEPER
541 RIOB18_X312Y299,IOB_X1Y287,dio[539],LVCMOS18,12,SLOW,PULLUP
542 RIOB18_X312Y299,IOB_X1Y288,dio[540],LVCMOS18,6,SLOW,PULLDOWN
543 RIOB18_X312Y301,IOB_X1Y289,dio[541],LVCMOS18,2,SLOW,PULLDOWN
544 RIOB18_X312Y301,IOB_X1Y290,dio[542],LVCMOS18,4,SLOW,PULLUP
545 RIOB18_X312Y303,IOB_X1Y291,dio[543],LVCMOS18,16,FAST,PULLUP
546 RIOB18_X312Y303,IOB_X1Y292,dio[544],LVCMOS18,16,SLOW,KEEPER
547 RIOB18_X312Y305,IOB_X1Y293,dio[545],LVCMOS18,12,FAST,NONE
548 RIOB18_X312Y305,IOB_X1Y294,dio[546],LVCMOS18,8,FAST,KEEPER
549 RIOB18_X312Y307,IOB_X1Y295,dio[547],LVCMOS18,12,SLOW,NONE
550 RIOB18_X312Y307,IOB_X1Y296,dio[548],LVCMOS18,16,SLOW,PULLUP
551 RIOB18_X312Y309,IOB_X1Y297,dio[549],LVCMOS18,4,FAST,KEEPER
552 RIOB18_X312Y309,IOB_X1Y298,dio[550],LVCMOS18,4,SLOW,NONE
553 RIOB18_X312Y31,IOB_X1Y29,dio[551],LVCMOS18,6,SLOW,KEEPER
554 RIOB18_X312Y31,IOB_X1Y30,dio[552],LVCMOS18,2,SLOW,NONE
555 RIOB18_X312Y314,IOB_X1Y301,dio[553],LVCMOS18,2,SLOW,KEEPER
556 RIOB18_X312Y314,IOB_X1Y302,dio[554],LVCMOS18,8,FAST,KEEPER
557 RIOB18_X312Y316,IOB_X1Y303,dio[555],LVCMOS18,2,FAST,KEEPER
558 RIOB18_X312Y316,IOB_X1Y304,dio[556],LVCMOS18,6,FAST,PULLUP
559 RIOB18_X312Y318,IOB_X1Y305,dio[557],LVCMOS18,16,FAST,PULLUP
560 RIOB18_X312Y318,IOB_X1Y306,dio[558],LVCMOS18,4,SLOW,PULLUP
561 RIOB18_X312Y320,IOB_X1Y307,dio[559],LVCMOS18,8,SLOW,PULLDOWN
562 RIOB18_X312Y320,IOB_X1Y308,dio[560],LVCMOS18,8,SLOW,PULLDOWN
563 RIOB18_X312Y322,IOB_X1Y309,dio[561],LVCMOS18,6,SLOW,PULLDOWN
564 RIOB18_X312Y322,IOB_X1Y310,dio[562],LVCMOS18,4,FAST,KEEPER
565 RIOB18_X312Y324,IOB_X1Y311,dio[563],LVCMOS18,4,FAST,KEEPER
566 RIOB18_X312Y324,IOB_X1Y312,dio[564],LVCMOS18,6,FAST,NONE
567 RIOB18_X312Y326,IOB_X1Y313,dio[565],LVCMOS18,8,FAST,PULLUP
568 RIOB18_X312Y326,IOB_X1Y314,dio[566],LVCMOS18,6,SLOW,PULLUP
569 RIOB18_X312Y328,IOB_X1Y315,dio[567],LVCMOS18,12,FAST,NONE
570 RIOB18_X312Y328,IOB_X1Y316,dio[568],LVCMOS18,2,FAST,PULLUP
571 RIOB18_X312Y33,IOB_X1Y31,dio[569],LVCMOS18,12,FAST,NONE
572 RIOB18_X312Y33,IOB_X1Y32,dio[570],LVCMOS18,12,FAST,PULLUP
573 RIOB18_X312Y330,IOB_X1Y317,dio[571],LVCMOS18,4,FAST,KEEPER
574 RIOB18_X312Y330,IOB_X1Y318,dio[572],LVCMOS18,8,FAST,NONE
575 RIOB18_X312Y332,IOB_X1Y319,dio[573],LVCMOS18,8,SLOW,KEEPER
576 RIOB18_X312Y332,IOB_X1Y320,dio[574],LVCMOS18,12,FAST,NONE
577 RIOB18_X312Y334,IOB_X1Y321,dio[575],LVCMOS18,16,FAST,NONE
578 RIOB18_X312Y334,IOB_X1Y322,dio[576],LVCMOS18,16,SLOW,KEEPER
579 RIOB18_X312Y336,IOB_X1Y323,dio[577],LVCMOS18,6,FAST,NONE
580 RIOB18_X312Y336,IOB_X1Y324,dio[578],LVCMOS18,4,FAST,NONE
581 RIOB18_X312Y339,IOB_X1Y325,dio[579],LVCMOS18,16,FAST,KEEPER
582 RIOB18_X312Y339,IOB_X1Y326,dio[580],LVCMOS18,16,SLOW,NONE
583 RIOB18_X312Y341,IOB_X1Y327,dio[581],LVCMOS18,6,SLOW,NONE
584 RIOB18_X312Y341,IOB_X1Y328,dio[582],LVCMOS18,2,SLOW,PULLUP
585 RIOB18_X312Y343,IOB_X1Y329,dio[583],LVCMOS18,16,SLOW,PULLUP
586 RIOB18_X312Y343,IOB_X1Y330,dio[584],LVCMOS18,8,SLOW,KEEPER
587 RIOB18_X312Y345,IOB_X1Y331,dio[585],LVCMOS18,12,SLOW,PULLUP
588 RIOB18_X312Y345,IOB_X1Y332,dio[586],LVCMOS18,16,FAST,PULLUP
589 RIOB18_X312Y347,IOB_X1Y333,dio[587],LVCMOS18,8,FAST,NONE
590 RIOB18_X312Y347,IOB_X1Y334,dio[588],LVCMOS18,6,SLOW,KEEPER
591 RIOB18_X312Y349,IOB_X1Y335,dio[589],LVCMOS18,4,FAST,PULLUP
592 RIOB18_X312Y349,IOB_X1Y336,dio[590],LVCMOS18,12,SLOW,PULLDOWN
593 RIOB18_X312Y35,IOB_X1Y33,dio[591],LVCMOS18,6,SLOW,PULLDOWN
594 RIOB18_X312Y35,IOB_X1Y34,dio[592],LVCMOS18,4,SLOW,PULLUP
595 RIOB18_X312Y351,IOB_X1Y337,dio[593],LVCMOS18,6,SLOW,KEEPER
596 RIOB18_X312Y351,IOB_X1Y338,dio[594],LVCMOS18,8,FAST,KEEPER
597 RIOB18_X312Y353,IOB_X1Y339,dio[595],LVCMOS18,6,FAST,PULLDOWN
598 RIOB18_X312Y353,IOB_X1Y340,dio[596],LVCMOS18,6,SLOW,KEEPER
599 RIOB18_X312Y355,IOB_X1Y341,dio[597],LVCMOS18,8,FAST,NONE
600 RIOB18_X312Y355,IOB_X1Y342,dio[598],LVCMOS18,8,SLOW,PULLDOWN
601 RIOB18_X312Y357,IOB_X1Y343,dio[599],LVCMOS18,6,FAST,NONE
602 RIOB18_X312Y357,IOB_X1Y344,dio[600],LVCMOS18,8,SLOW,KEEPER
603 RIOB18_X312Y359,IOB_X1Y345,dio[601],LVCMOS18,8,SLOW,NONE
604 RIOB18_X312Y359,IOB_X1Y346,dio[602],LVCMOS18,16,SLOW,PULLDOWN
605 RIOB18_X312Y361,IOB_X1Y347,dio[603],LVCMOS18,8,FAST,NONE
606 RIOB18_X312Y361,IOB_X1Y348,dio[604],LVCMOS18,6,FAST,PULLDOWN
607 RIOB18_X312Y37,IOB_X1Y35,dio[605],LVCMOS18,4,SLOW,KEEPER
608 RIOB18_X312Y37,IOB_X1Y36,dio[606],LVCMOS18,12,SLOW,PULLDOWN
609 RIOB18_X312Y39,IOB_X1Y37,dio[607],LVCMOS18,4,FAST,PULLUP
610 RIOB18_X312Y39,IOB_X1Y38,dio[608],LVCMOS18,6,FAST,PULLDOWN
611 RIOB18_X312Y4,IOB_X1Y3,dio[609],LVCMOS18,16,FAST,PULLDOWN
612 RIOB18_X312Y4,IOB_X1Y4,dio[610],LVCMOS18,12,SLOW,PULLUP
613 RIOB18_X312Y41,IOB_X1Y39,dio[611],LVCMOS18,6,SLOW,NONE
614 RIOB18_X312Y41,IOB_X1Y40,dio[612],LVCMOS18,16,SLOW,NONE
615 RIOB18_X312Y43,IOB_X1Y41,dio[613],LVCMOS18,16,FAST,NONE
616 RIOB18_X312Y43,IOB_X1Y42,dio[614],LVCMOS18,12,FAST,PULLUP
617 RIOB18_X312Y45,IOB_X1Y43,dio[615],LVCMOS18,6,FAST,PULLDOWN
618 RIOB18_X312Y45,IOB_X1Y44,dio[616],LVCMOS18,6,SLOW,PULLDOWN
619 RIOB18_X312Y47,IOB_X1Y45,dio[617],LVCMOS18,12,FAST,PULLUP
620 RIOB18_X312Y47,IOB_X1Y46,dio[618],LVCMOS18,2,SLOW,NONE
621 RIOB18_X312Y49,IOB_X1Y47,dio[619],LVCMOS18,2,FAST,PULLUP
622 RIOB18_X312Y49,IOB_X1Y48,dio[620],LVCMOS18,4,SLOW,PULLDOWN
623 RIOB18_X312Y54,IOB_X1Y51,dio[621],LVCMOS18,12,SLOW,PULLDOWN
624 RIOB18_X312Y54,IOB_X1Y52,dio[622],LVCMOS18,2,FAST,PULLDOWN
625 RIOB18_X312Y56,IOB_X1Y53,dio[623],LVCMOS18,6,SLOW,NONE
626 RIOB18_X312Y56,IOB_X1Y54,dio[624],LVCMOS18,4,SLOW,PULLDOWN
627 RIOB18_X312Y58,IOB_X1Y55,dio[625],LVCMOS18,8,SLOW,KEEPER
628 RIOB18_X312Y58,IOB_X1Y56,dio[626],LVCMOS18,12,SLOW,PULLUP
629 RIOB18_X312Y6,IOB_X1Y5,dio[627],LVCMOS18,6,SLOW,PULLUP
630 RIOB18_X312Y6,IOB_X1Y6,dio[628],LVCMOS18,16,FAST,PULLDOWN
631 RIOB18_X312Y60,IOB_X1Y57,dio[629],LVCMOS18,8,FAST,KEEPER
632 RIOB18_X312Y60,IOB_X1Y58,dio[630],LVCMOS18,2,FAST,PULLDOWN
633 RIOB18_X312Y62,IOB_X1Y59,dio[631],LVCMOS18,6,SLOW,PULLUP
634 RIOB18_X312Y62,IOB_X1Y60,dio[632],LVCMOS18,4,SLOW,PULLDOWN
635 RIOB18_X312Y64,IOB_X1Y61,dio[633],LVCMOS18,2,FAST,KEEPER
636 RIOB18_X312Y64,IOB_X1Y62,dio[634],LVCMOS18,2,SLOW,PULLUP
637 RIOB18_X312Y66,IOB_X1Y63,dio[635],LVCMOS18,6,FAST,PULLUP
638 RIOB18_X312Y66,IOB_X1Y64,dio[636],LVCMOS18,6,FAST,PULLDOWN
639 RIOB18_X312Y68,IOB_X1Y65,dio[637],LVCMOS18,4,SLOW,KEEPER
640 RIOB18_X312Y68,IOB_X1Y66,dio[638],LVCMOS18,2,FAST,PULLUP
641 RIOB18_X312Y70,IOB_X1Y67,dio[639],LVCMOS18,12,SLOW,NONE
642 RIOB18_X312Y70,IOB_X1Y68,dio[640],LVCMOS18,16,FAST,PULLDOWN
643 RIOB18_X312Y72,IOB_X1Y69,dio[641],LVCMOS18,8,FAST,PULLDOWN
644 RIOB18_X312Y72,IOB_X1Y70,dio[642],LVCMOS18,8,FAST,PULLDOWN
645 RIOB18_X312Y74,IOB_X1Y71,dio[643],LVCMOS18,12,SLOW,NONE
646 RIOB18_X312Y74,IOB_X1Y72,dio[644],LVCMOS18,6,FAST,KEEPER
647 RIOB18_X312Y76,IOB_X1Y73,dio[645],LVCMOS18,2,SLOW,KEEPER
648 RIOB18_X312Y76,IOB_X1Y74,dio[646],LVCMOS18,4,FAST,NONE
649 RIOB18_X312Y79,IOB_X1Y75,dio[647],LVCMOS18,2,SLOW,NONE
650 RIOB18_X312Y79,IOB_X1Y76,dio[648],LVCMOS18,6,SLOW,KEEPER
651 RIOB18_X312Y8,IOB_X1Y7,dio[649],LVCMOS18,6,SLOW,PULLDOWN
652 RIOB18_X312Y8,IOB_X1Y8,dio[650],LVCMOS18,16,FAST,PULLUP
653 RIOB18_X312Y81,IOB_X1Y77,dio[651],LVCMOS18,2,SLOW,NONE
654 RIOB18_X312Y81,IOB_X1Y78,dio[652],LVCMOS18,2,FAST,KEEPER
655 RIOB18_X312Y83,IOB_X1Y79,dio[653],LVCMOS18,8,FAST,NONE
656 RIOB18_X312Y83,IOB_X1Y80,dio[654],LVCMOS18,4,FAST,NONE
657 RIOB18_X312Y85,IOB_X1Y81,dio[655],LVCMOS18,12,FAST,KEEPER
658 RIOB18_X312Y85,IOB_X1Y82,dio[656],LVCMOS18,6,FAST,PULLDOWN
659 RIOB18_X312Y87,IOB_X1Y83,dio[657],LVCMOS18,12,SLOW,KEEPER
660 RIOB18_X312Y87,IOB_X1Y84,dio[658],LVCMOS18,6,FAST,NONE
661 RIOB18_X312Y89,IOB_X1Y85,dio[659],LVCMOS18,4,FAST,KEEPER
662 RIOB18_X312Y89,IOB_X1Y86,dio[660],LVCMOS18,12,SLOW,PULLUP
663 RIOB18_X312Y91,IOB_X1Y87,dio[661],LVCMOS18,6,SLOW,NONE
664 RIOB18_X312Y91,IOB_X1Y88,dio[662],LVCMOS18,12,SLOW,NONE
665 RIOB18_X312Y93,IOB_X1Y89,dio[663],LVCMOS18,6,FAST,KEEPER
666 RIOB18_X312Y93,IOB_X1Y90,dio[664],LVCMOS18,8,FAST,PULLDOWN
667 RIOB18_X312Y95,IOB_X1Y91,dio[665],LVCMOS18,2,SLOW,NONE
668 RIOB18_X312Y95,IOB_X1Y92,dio[666],LVCMOS18,4,FAST,PULLDOWN
669 RIOB18_X312Y97,IOB_X1Y93,dio[667],LVCMOS18,12,FAST,KEEPER
670 RIOB18_X312Y97,IOB_X1Y94,dio[668],LVCMOS18,8,SLOW,KEEPER
671 RIOB18_X312Y99,IOB_X1Y95,dio[669],LVCMOS18,4,FAST,KEEPER
672 RIOB18_X312Y99,IOB_X1Y96,dio[670],LVCMOS18,8,FAST,KEEPER

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
IOI.ILOGIC_Y0.IDELMUXE3.P0 IOI.ILOGIC_Y0.IDELMUXE3.P1
IOI.ILOGIC_Y0.IFFDELMUXE3.P0 IOI.ILOGIC_Y0.IFFDELMUXE3.P1
IOI.ILOGIC_Y0.IFF.SRTYPE.ASYNC IOI.ILOGIC_Y0.IFF.SRTYPE.SYNC
IOI.ILOGIC_Y0.IFF.DDR_CLK_EDGE.OPPOSITE_EDGE IOI.ILOGIC_Y0.IFF.DDR_CLK_EDGE.SAME_EDGE IOI.ILOGIC_Y0.IFF.DDR_CLK_EDGE.SAME_EDGE_PIPELINED
IOI.ILOGIC_Y1.IDELMUXE3.P0 IOI.ILOGIC_Y1.IDELMUXE3.P1
IOI.ILOGIC_Y1.IFFDELMUXE3.P0 IOI.ILOGIC_Y1.IFFDELMUXE3.P1
IOI.ILOGIC_Y1.IFF.SRTYPE.ASYNC IOI.ILOGIC_Y1.IFF.SRTYPE.SYNC
IOI.ILOGIC_Y1.IFF.DDR_CLK_EDGE.OPPOSITE_EDGE IOI.ILOGIC_Y1.IFF.DDR_CLK_EDGE.SAME_EDGE IOI.ILOGIC_Y1.IFF.DDR_CLK_EDGE.SAME_EDGE_PIPELINED

View File

@ -0,0 +1,517 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import json
import io
import os
import random
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray import lut_maker
from prjxray import verilog
from prjxray.db import Database
def gen_sites():
'''
IOB18S: main IOB of a diff pair
IOB18M: secondary IOB of a diff pair
Virtex-7 "VX" parts are high-performance-bank only (IOB18 / IOI = LIOI,
RIOI and their TBYTESRC/TBYTETERM variants); there are no IOB33/HR sites,
so the kintex7 035-iob-ilogic fuzzer cannot run here. Cover BOTH the L-
and R-side IOB18 columns so LIOI and RIOI get real measurements rather
than a transplant. SING rows are excluded (their ILOGIC is fuzzed
separately and has a different frame window).
'''
db = Database(util.get_db_root(), util.get_part())
grid = db.grid()
for tile_name in sorted(grid.tiles()):
if "IOB18" not in tile_name or "SING" in tile_name:
continue
loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['IOB18S', 'IOB18M']:
yield tile_name, site_name
def write_params(params):
pinstr = 'tile,site,pin,iostandard,drive,slew\n'
for vals in params:
pinstr += ','.join(map(str, vals)) + '\n'
open('params.csv', 'w').write(pinstr)
def use_iserdese2(p, luts, connects):
iobdelay = random.choice((
'NONE',
'BOTH',
'IBUF',
'IFD',
))
p['IOBDELAY'] = verilog.quote(iobdelay)
p['INIT_Q1'] = random.randint(0, 1)
p['INIT_Q2'] = random.randint(0, 1)
p['INIT_Q3'] = random.randint(0, 1)
p['INIT_Q4'] = random.randint(0, 1)
p['SRVAL_Q1'] = random.randint(0, 1)
p['SRVAL_Q2'] = random.randint(0, 1)
p['SRVAL_Q3'] = random.randint(0, 1)
p['SRVAL_Q4'] = random.randint(0, 1)
p['NUM_CE'] = random.randint(1, 2)
p['IS_CLK_INVERTED'] = random.randint(0, 1)
p['IS_CLKB_INVERTED'] = random.randint(0, 1)
p['IS_OCLK_INVERTED'] = random.randint(0, 1)
p['IS_OCLKB_INVERTED'] = random.randint(0, 1)
p['IS_CLKDIV_INVERTED'] = random.randint(0, 1)
p['IS_D_INVERTED'] = random.randint(0, 1)
p['INTERFACE_TYPE'] = verilog.quote(
random.choice(
(
'MEMORY',
'MEMORY_DDR3',
'MEMORY_QDR',
'NETWORKING',
'OVERSAMPLE',
)))
p['DATA_RATE'] = verilog.quote(random.choice((
'SDR',
'DDR',
)))
if verilog.unquote(p['DATA_RATE']) == 'SDR':
data_widths = [2, 3, 4, 5, 6, 7, 8]
else:
data_widths = [4, 6, 8]
p['DATA_WIDTH'] = random.choice(data_widths)
p['SERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))
use_delay = iobdelay != 'NONE'
if iobdelay == 'NONE':
p['mux_config'] = 'direct'
p['iddr_mux_config'] = 'direct'
elif iobdelay == 'BOTH':
p['mux_config'] = 'idelay'
p['iddr_mux_config'] = 'idelay'
elif iobdelay == 'IBUF':
p['mux_config'] = 'idelay'
p['iddr_mux_config'] = 'direct'
elif iobdelay == 'IFD':
p['mux_config'] = 'direct'
p['iddr_mux_config'] = 'idelay'
p['OFB_USED'] = verilog.quote(random.choice(('TRUE', 'FALSE')))
p['DYN_CLKDIV_INV_EN'] = verilog.quote(random.choice(('TRUE', 'FALSE')))
p['DYN_CLK_INV_EN'] = verilog.quote(random.choice(('TRUE', 'FALSE')))
if use_delay:
print(
"""
wire idelay_{site};
(* KEEP, DONT_TOUCH, LOC = "{idelay_loc}" *)
IDELAYE2 #(
) idelay_site_{site} (
.IDATAIN({iwire}),
.DATAOUT(idelay_{site})
);""".format(**p),
file=connects)
p['ddly_connection'] = '.DDLY(idelay_{site}),'.format(**p)
else:
p['ddly_connection'] = ''
if verilog.unquote(p['OFB_USED']) == 'TRUE':
p['ODATA_RATE'] = verilog.quote(random.choice((
'SDR',
'DDR',
)))
if verilog.unquote(p['ODATA_RATE']) == 'SDR':
data_widths = [2, 3, 4, 5, 6, 7, 8]
else:
data_widths = [4, 6, 8]
p['ODATA_WIDTH'] = random.choice(data_widths)
p['OSERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))
if p['ODATA_WIDTH'] == 4 and verilog.unquote(p['ODATA_RATE']) == 'DDR':
p['TRISTATE_WIDTH'] = 4
else:
p['TRISTATE_WIDTH'] = 1
print(
"""
wire tfb_{site};
wire ofb_{site};
(* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
OSERDESE2 #(
.SERDES_MODE({OSERDES_MODE}),
.DATA_RATE_TQ({ODATA_RATE}),
.DATA_RATE_OQ({ODATA_RATE}),
.DATA_WIDTH({ODATA_WIDTH}),
.TRISTATE_WIDTH({TRISTATE_WIDTH})
) oserdese2_{site} (
.CLK(0),
.CLKDIV(0),
.D1(0),
.TFB(tfb_{site}),
.OQ({owire}),
.TQ({twire}),
.OFB(ofb_{site})
);""".format(**p),
file=connects)
p['ofb_connections'] = """
.OFB(ofb_{site}),
""".format(**p)
else:
p['ofb_connections'] = ''
if random.randint(0, 1):
clknet = luts.get_next_output_net()
else:
clknet = random.choice((
'clk_BUFG1',
'clk_BUFG2',
))
if random.randint(0, 1):
clkbnet = luts.get_next_output_net()
else:
clkbnet = random.choice((
'clk_BUFG1',
'clk_BUFG2',
))
if random.randint(0, 1):
oclknet = luts.get_next_output_net()
else:
oclknet = random.choice((
'clk_BUFG1',
'clk_BUFG2',
))
clkdiv = random.choice(('clk_BUFG3', 'clk_BUFG4'))
p['DISABLE_CLOCKS'] = random.randint(0, 1)
if p['DISABLE_CLOCKS']:
clknet = '0'
clkbnet = '0'
oclknet = '0'
clkdiv = '0'
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{ilogic_loc}" *)
ISERDESE2 #(
.SERDES_MODE({SERDES_MODE}),
.INIT_Q1({INIT_Q1}),
.INIT_Q2({INIT_Q2}),
.INIT_Q3({INIT_Q3}),
.INIT_Q4({INIT_Q4}),
.SRVAL_Q1({SRVAL_Q1}),
.SRVAL_Q2({SRVAL_Q2}),
.SRVAL_Q3({SRVAL_Q3}),
.SRVAL_Q4({SRVAL_Q4}),
.DYN_CLKDIV_INV_EN({DYN_CLKDIV_INV_EN}),
.DYN_CLK_INV_EN({DYN_CLK_INV_EN}),
.INTERFACE_TYPE({INTERFACE_TYPE}),
.IS_CLK_INVERTED({IS_CLK_INVERTED}),
.IS_CLKB_INVERTED({IS_CLKB_INVERTED}),
.IS_OCLK_INVERTED({IS_OCLK_INVERTED}),
.IS_OCLKB_INVERTED({IS_OCLKB_INVERTED}),
.IS_CLKDIV_INVERTED({IS_CLKDIV_INVERTED}),
.IS_D_INVERTED({IS_D_INVERTED}),
.OFB_USED({OFB_USED}),
.NUM_CE({NUM_CE}),
.DATA_RATE({DATA_RATE}),
.DATA_WIDTH({DATA_WIDTH}),
.IOBDELAY({IOBDELAY})
) iserdese2_{site} (
{ddly_connection}
{ofb_connections}
.D({iwire}),
.CLK({clknet}),
.CLKB({clkbnet}),
.OCLK({oclknet}),
.O({onet}),
.Q1({q1net}),
.CLKDIV({clkdiv})
);'''.format(
clkdiv=clkdiv,
clknet=clknet,
clkbnet=clkbnet,
oclknet=oclknet,
onet=luts.get_next_input_net(),
q1net=luts.get_next_input_net(),
shiftout1net=luts.get_next_input_net(),
shiftout2net=luts.get_next_input_net(),
**p),
file=connects)
def use_direct_and_iddr(p, luts, connects):
p['mux_config'] = random.choice((
'direct',
'idelay',
'none',
))
p['iddr_mux_config'] = random.choice((
'direct',
'idelay',
'none',
))
if p['iddr_mux_config'] != 'none':
p['INIT_Q1'] = random.randint(0, 1)
p['INIT_Q2'] = random.randint(0, 1)
p['IS_C_INVERTED'] = random.randint(0, 1)
p['IS_D_INVERTED'] = random.randint(0, 1)
p['SRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
p['DDR_CLK_EDGE'] = verilog.quote(
random.choice(
(
'OPPOSITE_EDGE',
'SAME_EDGE',
'SAME_EDGE_PIPELINED',
)))
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{ilogic_loc}" *)
IDDR #(
.IS_D_INVERTED({IS_D_INVERTED}),
.IS_C_INVERTED({IS_C_INVERTED}),
.INIT_Q1({INIT_Q1}),
.INIT_Q2({INIT_Q2}),
.SRTYPE({SRTYPE}),
.DDR_CLK_EDGE({DDR_CLK_EDGE})
) iddr_{site} (
.C({cnet}),
.D(iddr_d_{site}),
.Q1({q1}),
.Q2({q2})
);
'''.format(
cnet=luts.get_next_output_net(),
q1=luts.get_next_input_net(),
q2=luts.get_next_input_net(),
**p),
file=connects)
if p['iddr_mux_config'] == 'idelay' or p['mux_config'] == 'idelay' or p[
'iddr_mux_config'] == 'tristate_feedback':
print(
"""
wire idelay_{site};
(* KEEP, DONT_TOUCH, LOC = "{idelay_loc}" *)
IDELAYE2 #(
) idelay_site_{site} (
.IDATAIN({iwire}),
.DATAOUT(idelay_{site})
);""".format(**p),
file=connects)
print(
"""
assign {owire} = {onet};
assign {twire} = {tnet};
""".format(
onet=luts.get_next_output_net(),
tnet=luts.get_next_output_net(),
**p),
file=connects)
if p['iddr_mux_config'] == 'direct':
print(
'''
assign iddr_d_{site} = {iwire};'''.format(**p, ),
file=connects)
elif p['iddr_mux_config'] == 'idelay':
print(
'''
assign iddr_d_{site} = idelay_{site};'''.format(**p, ),
file=connects)
elif p['iddr_mux_config'] == 'tristate_feedback':
print(
'''
assign iddr_d_{site} = tfb_{site} ? ofb_{site} : idelay_{site};'''.format(
**p, ),
file=connects)
elif p['iddr_mux_config'] == 'none':
pass
else:
assert False, p['mux_config']
if p['mux_config'] == 'direct':
print(
'''
assign {net} = {iwire};'''.format(
net=luts.get_next_input_net(),
**p,
),
file=connects)
elif p['mux_config'] == 'idelay':
print(
'''
assign {net} = idelay_{site};'''.format(
net=luts.get_next_input_net(),
**p,
),
file=connects)
elif p['mux_config'] == 'none':
pass
else:
assert False, p['mux_config']
def run():
# IOSTANDARD does not affect the ILOGIC config bits being measured, so pin
# it to LVCMOS18 (valid on every HP bank at the default drive). LVCMOS12's
# default drive of 12 is illegal on HP banks (DRC BIVB-1), and mixing
# standards only adds bank-compatibility failure modes for no extra ILOGIC
# coverage.
iostandards = ['LVCMOS18']
iostandard = random.choice(iostandards)
drives = [2, 4, 6, 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;
wire clk_BUFG1;
wire clk_BUFG2;
wire clk_BUFG3;
wire clk_BUFG4;
(* KEEP, DONT_TOUCH *)
BUFG bufg1(
.O(clk_BUFG1)
);
(* KEEP, DONT_TOUCH *)
BUFG bufg2(
.O(clk_BUFG2)
);
(* KEEP, DONT_TOUCH *)
BUFG bufg3(
.O(clk_BUFG3)
);
(* KEEP, DONT_TOUCH *)
BUFG bufg4(
.O(clk_BUFG4)
);
'''.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)
if __name__ == '__main__':
run()

View File

@ -0,0 +1,44 @@
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
#
# IOB18 (HP-bank) ISERDES fuzzer for Virtex-7. The kintex7 035b-iob-iserdes
# fuzzer targets IOB33/HR sites that do not exist on this part, so its RIOI
# ISERDES results were transplanted. This variant places ISERDESE2 on real
# IOB18 sites on BOTH the L and R columns and measures the ISERDES config bits
# directly, merging to lioi and rioi (segmaker emits the IOI. prefix, which
# mergedb rewrites per side).
N := 40
include ../fuzzer.mk
database: build/segbits_iob18_iserdes.db
build/segbits_iob18_iserdes.rdb: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -c 20 -m 1 -M 1 -o build/segbits_iob18_iserdes.rdb2 $$(find -name segdata_*.txt)
# Keep only ISERDES-related solutions (the rest belong to 035-iob18-ilogic).
grep -e ".ISERDES." build/segbits_iob18_iserdes.rdb2 > $@
grep -e ".IDDR.IN_USE." build/segbits_iob18_iserdes.rdb2 >> $@ || true
build/segbits_iob18_iserdes.db: build/segbits_iob18_iserdes.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --groups tag_groups.txt --seg-fn-in $^ --seg-fn-out $@
${XRAY_MASKMERGE} build/mask_iob18_iserdes.db $$(find -name segdata_*.txt)
pushdb:
${XRAY_MERGEDB} lioi build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} lioi_tbytesrc build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} lioi_tbyteterm build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} rioi build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} rioi_tbytesrc build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} rioi_tbyteterm build/segbits_iob18_iserdes.db
${XRAY_MERGEDB} mask_lioi build/mask_iob18_iserdes.db
${XRAY_MERGEDB} mask_lioi_tbytesrc build/mask_iob18_iserdes.db
${XRAY_MERGEDB} mask_lioi_tbyteterm build/mask_iob18_iserdes.db
${XRAY_MERGEDB} mask_rioi build/mask_iob18_iserdes.db
${XRAY_MERGEDB} mask_rioi_tbytesrc build/mask_iob18_iserdes.db
${XRAY_MERGEDB} mask_rioi_tbyteterm build/mask_iob18_iserdes.db
.PHONY: database pushdb

View File

View File

@ -0,0 +1,284 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import json
from prjxray.segmaker import Segmaker
from prjxray import util
from prjxray import verilog
iface_types = [
"NETWORKING", "OVERSAMPLE", "MEMORY", "MEMORY_DDR3", "MEMORY_QDR"
]
data_rates = ["SDR", "DDR"]
data_widths = {
"SDR": [2, 3, 4, 5, 6, 7, 8],
"DDR": [4, 6, 8, 10, 14],
}
def run():
segmk = Segmaker("design.bits")
# Load tags
with open("params.json", "r") as fp:
data = json.load(fp)
loc_to_tile_site_map = {}
# Output tags
for param_list in data:
for params in param_list:
loc = verilog.unquote(params["SITE_LOC"])
get_xy = util.create_xy_fun('IOB_')
x, y = get_xy(loc.replace("ILOGIC", "IOB"))
loc_to_tile_site_map[loc] = params["TILE_NAME"] + ".IOB_Y%d" % (
y % 2)
# Site not used at all
if not params["IS_USED"]:
segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", 0)
segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 0)
segmk.add_site_tag(loc, "ISERDES.IN_USE", 0)
segmk.add_site_tag(loc, "IDDR.IN_USE", 0)
segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0)
segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0)
for i in iface_types:
if i == "NETWORKING":
for j in data_rates:
for k in data_widths[j]:
tag = "ISERDES.%s.%s.W%s" % (i, j, k)
segmk.add_site_tag(loc, tag, 0)
else:
segmk.add_site_tag(loc, "ISERDES.%s.DDR.W4" % i, 0)
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0)
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0)
for i in range(1, 4 + 1):
segmk.add_site_tag(loc, "IFF.ZINIT_Q%d" % i, 0)
for i in range(1, 4 + 1):
segmk.add_site_tag(loc, "IFF.ZSRVAL_Q%d" % i, 0)
# segmk.add_site_tag(loc, "ISERDES.IS_CLKB_INVERTED", 0)
# segmk.add_site_tag(loc, "ISERDES.IS_CLK_INVERTED", 1)
segmk.add_site_tag(loc, "ISERDES.DYN_CLKDIV_INV_EN", 0)
segmk.add_site_tag(loc, "ISERDES.DYN_CLK_INV_EN", 0)
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 1)
segmk.add_site_tag(loc, "ISERDES.OFB_USED", 0)
# Site used as ISERDESE2
elif verilog.unquote(params["BEL_TYPE"]) == "ISERDESE2":
segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1)
segmk.add_site_tag(loc, "ISERDES.IN_USE", 1)
if "SHIFTOUT_USED" in params:
if params["CHAINED"]:
value = params["SHIFTOUT_USED"]
segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", value)
if "SERDES_MODE" in params:
value = verilog.unquote(params["SERDES_MODE"])
if value == "MASTER":
segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 1)
segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0)
if value == "SLAVE":
segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0)
segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 1)
iface_type = verilog.unquote(params["INTERFACE_TYPE"])
data_rate = verilog.unquote(params["DATA_RATE"])
data_width = int(params["DATA_WIDTH"])
for i in iface_types:
if i == "NETWORKING":
for j in data_rates:
for k in data_widths[j]:
tag = "ISERDES.%s.%s.W%s" % (i, j, k)
if i == iface_type:
if j == data_rate:
if k == data_width:
segmk.add_site_tag(loc, tag, 1)
else:
if i == iface_type:
segmk.add_site_tag(loc, "ISERDES.%s.DDR.W4" % i, 1)
if "NUM_CE" in params:
value = params["NUM_CE"]
if value == 1:
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1)
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0)
if value == 2:
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0)
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 1)
for i in range(1, 4 + 1):
if ("INIT_Q%d" % i) in params:
segmk.add_site_tag(
loc, "IFF.ZINIT_Q%d" % i,
not params["INIT_Q%d" % i])
for i in range(1, 4 + 1):
if ("SRVAL_Q%d" % i) in params:
segmk.add_site_tag(
loc, "IFF.ZSRVAL_Q%d" % i,
not params["SRVAL_Q%d" % i])
for inv in ["CLK", "CLKB", "OCLK", "OCLKB", "CLKDIV",
"CLKDIVP"]:
if "IS_{}_INVERTED".format(inv) in params:
segmk.add_site_tag(
loc, "ISERDES.INV_{}".format(inv),
params["IS_{}_INVERTED".format(inv)])
segmk.add_site_tag(
loc, "ISERDES.ZINV_{}".format(inv),
not params["IS_{}_INVERTED".format(inv)])
if "DYN_CLKDIV_INV_EN" in params:
value = verilog.unquote(params["DYN_CLKDIV_INV_EN"])
segmk.add_site_tag(
loc, "ISERDES.DYN_CLKDIV_INV_EN", int(value == "TRUE"))
if "DYN_CLK_INV_EN" in params:
value = verilog.unquote(params["DYN_CLK_INV_EN"])
segmk.add_site_tag(
loc, "ISERDES.DYN_CLK_INV_EN", int(value == "TRUE"))
# This parameter actually controls muxes used both in ILOGIC and
# ISERDES mode.
if "IOBDELAY" in params:
value = verilog.unquote(params["IOBDELAY"])
if value == "NONE":
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 1)
if value == "IBUF":
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 0)
if value == "IFD":
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 1)
if value == "BOTH":
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 0)
if "OFB_USED" in params:
value = verilog.unquote(params["OFB_USED"])
segmk.add_site_tag(
loc, "ISERDES.OFB_USED", int(value == "TRUE"))
# Site used as IDDR
elif verilog.unquote(params["BEL_TYPE"]) in ["IDDR",
"IDDR_NO_CLK"]:
segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1)
segmk.add_site_tag(loc, "IDDR.IN_USE", 1)
segmk.add_site_tag(loc, "ISERDES.IN_USE", 0)
if "DDR_CLK_EDGE" in params:
value = verilog.unquote(params["DDR_CLK_EDGE"])
segmk.add_site_tag(
loc, "IFF.DDR_CLK_EDGE.OPPOSITE_EDGE",
int(value == "OPPOSITE_EDGE"))
segmk.add_site_tag(
loc, "IFF.DDR_CLK_EDGE.SAME_EDGE",
int(value == "SAME_EDGE"))
segmk.add_site_tag(
loc, "IFF.DDR_CLK_EDGE.SAME_EDGE_PIPELINED",
int(value == "SAME_EDGE_PIPELINED"))
if "SRTYPE" in params:
value = verilog.unquote(params["SRTYPE"])
if value == "ASYNC":
segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 1)
segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 0)
if value == "SYNC":
segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 0)
segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 1)
if "IDELMUX" in params:
if params["IDELMUX"] == 1:
segmk.add_site_tag(loc, "IDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 0)
else:
segmk.add_site_tag(loc, "IDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IDELMUXE3.P1", 1)
if "IFFDELMUX" in params:
if params["IFFDELMUX"] == 1:
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0)
else:
segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0)
segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1)
for inv in ["C", "D"]:
if "IS_{}_INVERTED".format(inv) in params:
segmk.add_site_tag(
loc, "INV_{}".format(inv),
params["IS_{}_INVERTED".format(inv)])
segmk.add_site_tag(
loc, "ZINV_{}".format(inv),
not params["IS_{}_INVERTED".format(inv)])
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1)
segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0)
# Should not happen
else:
print("Unknown BEL_TYPE '{}'".format(params["BEL_TYPE"]))
exit(-1)
# Write segments and tags for later check
def_tags = {t: 0 for d in segmk.site_tags.values() for t in d.keys()}
with open("tags.json", "w") as fp:
tags = {}
for l, d in segmk.site_tags.items():
d1 = dict(def_tags)
d1.update({k: int(v) for k, v in d.items()})
tags[loc_to_tile_site_map[l]] = d1
json.dump(tags, fp, sort_keys=True, indent=1)
def bitfilter(frame_idx, bit_idx):
if frame_idx < 26 or frame_idx > 29:
return False
return True
segmk.compile(bitfilter=bitfilter)
segmk.write()
if __name__ == "__main__":
run()

View File

@ -0,0 +1,45 @@
# Copyright (C) 2017-2022 The Project X-Ray Authors
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
create_project -force -part $::env(XRAY_PART) design design
read_verilog top.v
synth_design -top top
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_param tcl.collectionResultDisplayLimit 0
set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}]
set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-81}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-84}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-85}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-87}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-85}]
set_property IS_ENABLED 0 [get_drc_checks {AVAL-28}]
# ISERDES/ILOGIC fuzzer deliberately builds "invalid" clocking and D-inversion
# mux configs to observe their bits; suppress the DRCs that would block bitgen.
set_property IS_ENABLED 0 [get_drc_checks {REQP-105}]
set_property IS_ENABLED 0 [get_drc_checks {PDRC-26}]
set_property IS_ENABLED 0 [get_drc_checks {PDRC-158}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1580}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1581}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-1582}]
# ISERDESE2-specific DRCs (CLK/CLKDIV topology) the iserdes fuzzer must bypass.
set_property IS_ENABLED 0 [get_drc_checks {NDRV-1}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-98}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-103}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-109}]
set_property IS_ENABLED 0 [get_drc_checks {REQP-111}]
place_design
route_design
write_checkpoint -force design.dcp
write_bitstream -force design.bit

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
IOI.ILOGIC_Y0.ISERDES.MEMORY.DDR.W4 IOI.ILOGIC_Y0.ISERDES.MEMORY_DDR.W.DDR.W4 IOI.ILOGIC_Y0.ISERDES.MEMORY_QDR.DDR.W4 IOI.ILOGIC_Y0.ISERDES.NETWORKING.DDR.W10 IOI.ILOGIC_Y0.ISERDES.NETWORKING.DDR.W14 IOI.ILOGIC_Y0.ISERDES.NETWORKING.DDR.W4 IOI.ILOGIC_Y0.ISERDES.NETWORKING.DDR.W6 IOI.ILOGIC_Y0.ISERDES.NETWORKING.DDR.W8 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W2 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W3 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W4 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W5 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W6 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W7 IOI.ILOGIC_Y0.ISERDES.NETWORKING.SDR.W8 IOI.ILOGIC_Y0.ISERDES.OVERSAMPLE.DDR.W4
IOI.ILOGIC_Y0.ISERDES.MODE.MASTER IOI.ILOGIC_Y0.ISERDES.MODE.SLAVE
IOI.ILOGIC_Y0.ISERDES.NUM_CE.N1 IOI.ILOGIC_Y0.ISERDES.NUM_CE.N2
IOI.ILOGIC_Y1.ISERDES.MEMORY.DDR.W4 IOI.ILOGIC_Y1.ISERDES.MEMORY_DDR.W.DDR.W4 IOI.ILOGIC_Y1.ISERDES.MEMORY_QDR.DDR.W4 IOI.ILOGIC_Y1.ISERDES.NETWORKING.DDR.W10 IOI.ILOGIC_Y1.ISERDES.NETWORKING.DDR.W14 IOI.ILOGIC_Y1.ISERDES.NETWORKING.DDR.W4 IOI.ILOGIC_Y1.ISERDES.NETWORKING.DDR.W6 IOI.ILOGIC_Y1.ISERDES.NETWORKING.DDR.W8 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W2 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W3 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W4 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W5 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W6 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W7 IOI.ILOGIC_Y1.ISERDES.NETWORKING.SDR.W8 IOI.ILOGIC_Y1.ISERDES.OVERSAMPLE.DDR.W4
IOI.ILOGIC_Y1.ISERDES.MODE.MASTER IOI.ILOGIC_Y1.ISERDES.MODE.SLAVE
IOI.ILOGIC_Y1.ISERDES.NUM_CE.N1 IOI.ILOGIC_Y1.ISERDES.NUM_CE.N2

View File

@ -0,0 +1,496 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import os, random
random.seed(int(os.getenv("SEED"), 16))
import json
from prjxray import util
from prjxray import verilog
from prjxray.db import Database
# =============================================================================
def gen_sites():
db = Database(util.get_db_root(), util.get_part())
grid = db.grid()
tile_list = []
for tile_name in sorted(grid.tiles()):
if "IOB18" not in tile_name or "SING" in tile_name:
continue
tile_list.append(tile_name)
get_xy = util.create_xy_fun('[LR]IOB18_')
tile_list.sort(key=get_xy)
for iob_tile_name in tile_list:
iob_gridinfo = grid.gridinfo_at_loc(
grid.loc_of_tilename(iob_tile_name))
iob33s = [k for k, v in iob_gridinfo.sites.items() if v == "IOB18S"][0]
iob33m = [k for k, v in iob_gridinfo.sites.items() if v == "IOB18M"][0]
top_sites = {
"IOB": iob33m,
"ILOGIC": iob33m.replace("IOB", "ILOGIC"),
"IDELAY": iob33m.replace("IOB", "IDELAY"),
}
bot_sites = {
"IOB": iob33s,
"ILOGIC": iob33s.replace("IOB", "ILOGIC"),
"IDELAY": iob33s.replace("IOB", "IDELAY"),
}
yield iob_tile_name, top_sites, bot_sites
def gen_iserdes(loc):
# Site params
params = {
"SITE_LOC": verilog.quote(loc),
"USE_IDELAY": random.randint(0, 1),
"BEL_TYPE": verilog.quote("ISERDESE2"),
"INIT_Q1": random.randint(0, 1),
"INIT_Q2": random.randint(0, 1),
"INIT_Q3": random.randint(0, 1),
"INIT_Q4": random.randint(0, 1),
"SRVAL_Q1": random.randint(0, 1),
"SRVAL_Q2": random.randint(0, 1),
"SRVAL_Q3": random.randint(0, 1),
"SRVAL_Q4": random.randint(0, 1),
"NUM_CE": random.randint(1, 2),
# The following one shows negative correlation (0 - not inverted)
"IS_D_INVERTED": random.randint(0, 1),
# No bits were found for parameters below
"IS_OCLKB_INVERTED": random.randint(0, 1),
"IS_OCLK_INVERTED": random.randint(0, 1),
"IS_CLKDIVP_INVERTED": random.randint(0, 1),
"IS_CLKDIV_INVERTED": random.randint(0, 1),
"IS_CLKB_INVERTED": random.randint(0, 1),
"IS_CLK_INVERTED": random.randint(0, 1),
"DYN_CLKDIV_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])),
"DYN_CLK_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])),
"IOBDELAY": verilog.quote(
random.choice(["NONE", "IBUF", "IFD", "BOTH"])),
"OFB_USED": verilog.quote(
random.choice(["TRUE"] + ["FALSE"] * 9)), # Force more FALSEs
}
iface_type = random.choice(
["NETWORKING", "OVERSAMPLE", "MEMORY", "MEMORY_DDR3", "MEMORY_QDR"])
data_rate = random.choice(["SDR", "DDR"])
serdes_mode = random.choice(["MASTER", "SLAVE"])
params["INTERFACE_TYPE"] = verilog.quote(iface_type)
params["DATA_RATE"] = verilog.quote(data_rate)
params["SERDES_MODE"] = verilog.quote(serdes_mode)
# Networking mode
if iface_type == "NETWORKING":
data_widths = {
"SDR": [2, 3, 4, 5, 6, 7, 8],
"DDR": [4, 6, 8, 10, 14],
}
params["DATA_WIDTH"] = random.choice(data_widths[data_rate])
# Others
else:
params["DATA_WIDTH"] = 4
if verilog.unquote(params["OFB_USED"]) == "TRUE":
params["IOBDELAY"] = verilog.quote("NONE")
return params
def gen_iddr(loc):
# Site params
params = {
"SITE_LOC":
verilog.quote(loc),
"USE_IDELAY":
random.randint(0, 1),
"BEL_TYPE":
verilog.quote(random.choice(["IDDR", "IDDR_NO_CLK"])),
"INIT_Q1":
random.randint(0, 1),
"INIT_Q2":
random.randint(0, 1),
"SRTYPE":
verilog.quote(random.choice(["ASYNC", "SYNC"])),
"DDR_CLK_EDGE":
verilog.quote(
random.choice(
["OPPOSITE_EDGE", "SAME_EDGE", "SAME_EDGE_PIPELINED"])),
"CE1USED":
random.randint(0, 1),
"SR_MODE":
verilog.quote(random.choice(["NONE", "SET", "RST"])),
"IS_C_INVERTED":
random.randint(0, 1),
"IS_D_INVERTED":
random.randint(0, 1),
}
if params["USE_IDELAY"]:
params["IDELMUX"] = random.randint(0, 1)
params["IFFDELMUX"] = random.randint(0, 1)
else:
params["IDELMUX"] = 0
params["IFFDELMUX"] = 0
return params
def run():
# Get all [LR]IOI3 tiles
tiles = list(gen_sites())
# Header
print("// Tile count: %d" % len(tiles))
print("// Seed: '%s'" % os.getenv("SEED"))
print(
'''
module top (
(* CLOCK_BUFFER_TYPE = "NONE" *)
input wire clk1,
(* CLOCK_BUFFER_TYPE = "NONE" *)
input wire clk2,
input wire ce,
input wire rst,
input wire [{N}:0] di,
output wire [{N}:0] do
);
wire [{N}:0] di_buf;
wire [{N}:0] do_buf;
// IDELAYCTRL
(* KEEP, DONT_TOUCH *)
IDELAYCTRL idelayctrl();
'''.format(**{"N": len(tiles) - 1}))
# LOCes IOBs
data = []
for i, sites in enumerate(tiles):
tile_name = sites[0]
# Use site
if random.randint(0, 19) > 0: # Use more often
# Top sites
if random.randint(0, 1):
this_sites = sites[1]
other_sites = sites[2]
# Bottom sites
else:
this_sites = sites[2]
other_sites = sites[1]
# Generate cell
bel_types = ["IDDR", "ISERDESE2"]
bel_type = bel_types[int(
random.randint(0, 2) > 0)] # ISERDES more often
if bel_type == "ISERDESE2":
params = gen_iserdes(this_sites["ILOGIC"])
if bel_type == "IDDR":
params = gen_iddr(this_sites["ILOGIC"])
params["IDELAY_LOC"] = verilog.quote(this_sites["IDELAY"])
params["IS_USED"] = 1
# Instantiate the cell
print('')
print('// This : ' + " ".join(this_sites.values()))
print('// Other: ' + " ".join(other_sites.values()))
print('(* LOC="%s", KEEP, DONT_TOUCH *)' % this_sites["IOB"])
print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i))
print('(* LOC="%s", KEEP, DONT_TOUCH *)' % other_sites["IOB"])
print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i))
clk1_conn = random.choice(["clk1", ""])
param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items())
print(
'ilogic_single #(%s) ilogic_%03d (.clk1(%s), .clk2(clk2), .ce(ce), .rst(rst), .I(di_buf[%3d]), .O(do_buf[%3d]));'
% (param_str, i, clk1_conn, i, i))
params["CHAINED"] = 0
params["TILE_NAME"] = tile_name
# Params for the second site
other_params = {
"TILE_NAME": tile_name,
"SITE_LOC": verilog.quote(other_sites["ILOGIC"]),
"IDELAY_LOC": verilog.quote(other_sites["IDELAY"]),
"IS_USED": 0,
}
# Append to data list
data.append([params, other_params])
# Don't use sites
else:
params_list = [
{
"TILE_NAME": tile_name,
"SITE_LOC": verilog.quote(sites[1]["ILOGIC"]),
"IDELAY_LOC": verilog.quote(sites[1]["IDELAY"]),
"IS_USED": 0,
},
{
"TILE_NAME": tile_name,
"SITE_LOC": verilog.quote(sites[2]["ILOGIC"]),
"IDELAY_LOC": verilog.quote(sites[2]["IDELAY"]),
"IS_USED": 0,
}
]
data.append(params_list)
# Store params
with open("params.json", "w") as fp:
json.dump(data, fp, sort_keys=True, indent=1)
print(
'''
endmodule
(* KEEP, DONT_TOUCH *)
module ilogic_single(
input wire clk1,
input wire clk2,
input wire ce,
input wire rst,
input wire I,
output wire O,
input wire [1:0] shiftin,
output wire [1:0] shiftout
);
parameter SITE_LOC = "";
parameter IS_USED = 1;
parameter BEL_TYPE = "ISERDESE2";
parameter IDELAY_LOC = "";
parameter USE_IDELAY = 0;
parameter IDELMUX = 0;
parameter IFFDELMUX = 0;
parameter INTERFACE_TYPE = "NETWORKING";
parameter DATA_RATE = "DDR";
parameter DATA_WIDTH = 4;
parameter SERDES_MODE = "MASTER";
parameter NUM_CE = 2;
parameter INIT_Q1 = 0;
parameter INIT_Q2 = 0;
parameter INIT_Q3 = 0;
parameter INIT_Q4 = 0;
parameter SRVAL_Q1 = 0;
parameter SRVAL_Q2 = 0;
parameter SRVAL_Q3 = 0;
parameter SRVAL_Q4 = 0;
parameter IS_D_INVERTED = 0;
parameter IS_OCLK_INVERTED = 0;
parameter IS_OCLKB_INVERTED = 0;
parameter IS_CLK_INVERTED = 0;
parameter IS_CLKB_INVERTED = 0;
parameter IS_CLKDIV_INVERTED = 0;
parameter IS_CLKDIVP_INVERTED = 0;
parameter DYN_CLKDIV_INV_EN = "FALSE";
parameter DYN_CLK_INV_EN = "FALSE";
parameter IOBDELAY = "NONE";
parameter OFB_USED = "FALSE";
parameter DDR_CLK_EDGE = "OPPOSITE_EDGE";
parameter SRTYPE = "ASYNC";
parameter CE1USED = 0;
parameter SR_MODE = "NONE";
parameter IS_C_INVERTED = 0;
wire [8:0] x;
wire ddly;
(* KEEP, DONT_TOUCH *)
generate if (IS_USED && USE_IDELAY) begin
// IDELAY
(* LOC=IDELAY_LOC, KEEP, DONT_TOUCH *)
IDELAYE2 idelay
(
.C(clk),
.REGRST(),
.LD(),
.CE(),
.INC(),
.CINVCTRL(),
.CNTVALUEIN(),
.IDATAIN(I),
.DATAIN(),
.LDPIPEEN(),
.DATAOUT(ddly),
.CNTVALUEOUT()
);
end else begin
assign ddly = 0;
end endgenerate
(* KEEP, DONT_TOUCH *)
generate if (IS_USED && BEL_TYPE == "ISERDESE2") begin
// ISERDES
(* LOC=SITE_LOC, KEEP, DONT_TOUCH *)
ISERDESE2 #
(
.INTERFACE_TYPE(INTERFACE_TYPE),
.DATA_RATE(DATA_RATE),
.DATA_WIDTH(DATA_WIDTH),
.SERDES_MODE(SERDES_MODE),
.NUM_CE(NUM_CE),
.IS_D_INVERTED(IS_D_INVERTED),
.IS_OCLK_INVERTED(IS_OCLK_INVERTED),
.IS_OCLKB_INVERTED(IS_OCLKB_INVERTED),
.IS_CLK_INVERTED(IS_CLK_INVERTED),
.IS_CLKB_INVERTED(IS_CLKB_INVERTED),
.IS_CLKDIV_INVERTED(IS_CLKDIV_INVERTED),
.IS_CLKDIVP_INVERTED(IS_CLKDIVP_INVERTED),
.INIT_Q1(INIT_Q1),
.INIT_Q2(INIT_Q2),
.INIT_Q3(INIT_Q3),
.INIT_Q4(INIT_Q4),
.SRVAL_Q1(SRVAL_Q1),
.SRVAL_Q2(SRVAL_Q2),
.SRVAL_Q3(SRVAL_Q3),
.SRVAL_Q4(SRVAL_Q4),
.DYN_CLKDIV_INV_EN(DYN_CLKDIV_INV_EN),
.DYN_CLK_INV_EN(DYN_CLK_INV_EN),
.IOBDELAY(IOBDELAY),
.OFB_USED(OFB_USED)
)
isedres
(
.D(I),
.DDLY(),
.OFB(),
//.TFB(),
.CE1(),
.CE2(),
.DYNCLKSEL(),
.CLK(clk1),
.CLKB(clk2),
.OCLK(),
.OCLKB(),
.DYNCLKDIVSEL(),
.CLKDIV(),
.CLKDIVP(),
.RST(),
.BITSLIP(),
.O(x[8]),
.Q1(x[0]),
.Q2(x[1]),
.Q3(x[2]),
.Q4(x[3]),
.Q5(x[4]),
.Q6(x[5]),
.Q7(x[6]),
.Q8(x[7]),
.SHIFTIN1(shiftin[0]),
.SHIFTIN2(shiftin[1]),
.SHIFTOUT1(shiftout[0]),
.SHIFTOUT2(shiftout[1])
);
end else if (IS_USED && BEL_TYPE == "IDDR") begin
// IDDR
(* LOC=SITE_LOC, KEEP, DONT_TOUCH *)
IDDR #
(
.IS_C_INVERTED(IS_C_INVERTED),
.IS_D_INVERTED(IS_D_INVERTED),
.DDR_CLK_EDGE(DDR_CLK_EDGE),
.INIT_Q1(INIT_Q1),
.INIT_Q2(INIT_Q2),
.SRTYPE(SRTYPE)
)
iddr
(
.C(clk1),
.CE( (CE1USED) ? ce : 1'hx ),
.D( (IFFDELMUX) ? ddly : I ),
.S( (SR_MODE == "SET") ? rst : 1'd0 ),
.R( (SR_MODE == "RST") ? rst : 1'd0 ),
.Q1(x[0]),
.Q2(x[1])
);
assign x[8] = (IDELMUX) ? ddly : I;
assign x[7:2] = 0;
end else if (IS_USED && BEL_TYPE == "IDDR_NO_CLK") begin
// IDDR
(* LOC=SITE_LOC, KEEP, DONT_TOUCH *)
IDDR #
(
.IS_C_INVERTED(IS_C_INVERTED),
.IS_D_INVERTED(IS_D_INVERTED),
.DDR_CLK_EDGE(DDR_CLK_EDGE),
.INIT_Q1(INIT_Q1),
.INIT_Q2(INIT_Q2),
.SRTYPE(SRTYPE)
)
iddr
(
.C(),
.CE( (CE1USED) ? ce : 1'hx ),
.D( (IFFDELMUX) ? ddly : I ),
.S( (SR_MODE == "SET") ? rst : 1'd0 ),
.R( (SR_MODE == "RST") ? rst : 1'd0 ),
.Q1(x[0]),
.Q2(x[1])
);
assign x[8] = (IDELMUX) ? ddly : I;
assign x[7:2] = 0;
end else begin
assign x[0] = I;
assign x[1] = I;
assign x[2] = I;
assign x[3] = I;
assign x[4] = I;
assign x[5] = I;
assign x[6] = I;
assign x[7] = I;
assign x[8] = I;
end endgenerate
// Output
assign O = |x;
endmodule
''')
run()

View File

@ -0,0 +1,66 @@
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
#
# 045a — fill the CK_IN[1..13] gap in segbits_hclk_cmt[_l].db.
#
# Mirrors 045-hclk-cmt-pips/Makefile but iterates over the 21 unsolved
# CK_IN PIPs in targets.csv (rather than sweeping all PIPs). Re-uses
# 045's cmt_regions.csv (build/ symlink), bits.dbf, and segmatch+mergedb
# downstream chain.
export FUZDIR=$(shell pwd)
PARENT_FUZDIR=$(FUZDIR)/../045-hclk-cmt-pips
PIP_TYPE?=hclk_cmt
PIPLIST_TCL=$(PARENT_FUZDIR)/hclk_cmt_pip_list.tcl
TODO_RE=".*HCLK_CMT.*CK_IN.*"
EXCLUDE_RE="(^.*LEAF)|(^.*BUFMR)|(^.*PHSR)|(^.*CLK_PLL7)|(^.*CLK_MMCM13)"
MAKETODO_FLAGS=--sides ",l" --pip-type ${PIP_TYPE} --seg-type ${PIP_TYPE} --re $(TODO_RE) --exclude-re $(EXCLUDE_RE)
# One specimen per target PIP in targets.csv (21 rows + header). N a few
# above 21 to give segmatch slack for failed-route specimens.
N = 24
FOUR_BIT_PIPS="FREQ_REF"
SPECIMENS_DEPS=build/cmt_regions.csv
A_PIPLIST=hclk_cmt.txt
include ../pip_loop.mk
.PRECIOUS: build/%.rdb
build/%.rdb: $(SPECIMENS_OK)
$(XRAY_SEGMATCH) -c 4 -o $@.4 $(shell find build -name $(subst segbits,segdata,$(patsubst %.rdb,%.txt,$(notdir $@))))
$(XRAY_SEGMATCH) -c 2 -o $@.2 $(shell find build -name $(subst segbits,segdata,$(patsubst %.rdb,%.txt,$(notdir $@))))
grep ${FOUR_BIT_PIPS} $@.4 > $@ || true
grep -v ${FOUR_BIT_PIPS} $@.2 >> $@ || true
build/%.db: build/%.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \
--seg-fn-in $< \
--seg-fn-out $@
cp $< build/$(ITER)/$(notdir $<)
${XRAY_MASKMERGE} $(subst segbits,mask,$@) \
$(shell find build -name $(subst segbits,segdata,$(patsubst %.db,%.txt,$(notdir $@))))
database: build/segbits_hclk_cmt.db build/segbits_hclk_cmt_l.db
cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits_hclk_cmt*.db build/database/${XRAY_DATABASE} || true
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} hclk_cmt build/segbits_hclk_cmt.db
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} hclk_cmt_l build/segbits_hclk_cmt_l.db
# cmt_regions.csv: symlink to 045's existing one so we don't re-run Vivado
# to regenerate it. If the symlink is missing, fall back to running
# 045's output_cmt.tcl.
build/cmt_regions.csv:
mkdir -p build
test -e $@ || ln -sf $(PARENT_FUZDIR)/build/cmt_regions.csv $@
pushdb: database
${XRAY_MERGEDB} hclk_cmt build/database/${XRAY_DATABASE}/segbits_hclk_cmt.db
${XRAY_MERGEDB} mask_hclk_cmt build/mask_hclk_cmt.db
${XRAY_MERGEDB} hclk_cmt_l build/database/${XRAY_DATABASE}/segbits_hclk_cmt_l.db
${XRAY_MERGEDB} mask_hclk_cmt_l build/mask_hclk_cmt_l.db
.PHONY: database pushdb

View File

@ -0,0 +1,191 @@
# 045a — HCLK\_CMT CK\_IN\* segbits
Fills the gap left by `045-hclk-cmt-pips`, which leaves 21 PIPs through the
`HCLK_CMT_CK_IN[1..13]` inputs unsolved (see
`fuzzers/045-hclk-cmt-pips/build/todo.txt`). These are needed to translate
`HCLK_CMT*.MUX_CLK_n.CK_INm` features that nextpnr-xilinx emits when routing
a `IBUFDS_GTE2 → BUFG → fabric` clock (e.g. the VC707 `SGMIICLK_Q0` path).
The 21 unsolved entries split as:
| tile_type | unsolved PIPs |
|-------------|---------------|
| HCLK_CMT | 3 (MUX_CLK_{7,8,10} ← CK_IN{9,4,6}) |
| HCLK_CMT_L | 18 (CK_IN{1,2,3,5,7,8,9,10,11,12,13} → various MMCM/PLL/MUX_CLK_*) |
## Why the parent 045 fuzzer misses them
`045-hclk-cmt-pips` uses random CMT clock-source assignments and relies on
Vivado's placer/router to spread routes across PIPs. For the CK_IN paths
Vivado almost always picks the same physical wire regardless of seed —
either because the CK_IN input is fed from a non-modeled source (a CCIO
that isn't in the design pool) or because the routing engine prefers a
single "shortest path" through the mux fabric. Without explicit
constraints the `(MUX_CLK_n, CK_INm)` cell of the routing matrix never
flips, so `segmatch` can't isolate its bits.
## Approach used here
For each of the 21 PIPs we generate a *forced-route* specimen:
1. `top.py` instantiates a CMT loadload (MMCM/PLL or BUFR sink) plus a
clock-capable source (CCIO pad).
2. `generate.tcl` issues explicit `USER_CLOCK_ROOT`, `LOC`, and
`route_design -mode quick -nets <net>` to pin the clock through the
exact `HCLK_CMT*.MUX_CLK_n.HCLK_CMT_CK_INm` PIP we want to learn.
We confirmed this works on this part by reproducing the same trick in
`~/div2_sgmii_loc_build/` (LOC SLICE_X0Y0 + LOC BUFGCTRL_X0Y0 forced
the clock onto `HCLK_CMT_X88Y26` and set bit `27_181`).
3. The standard prjxray `segmaker` / `segmatch` chain extracts the
set/clear bit pattern for each PIP.
## State as of this session
End-to-end runnable scaffold:
- `targets.csv` — the 21 PIPs (3 HCLK_CMT + 18 HCLK_CMT_L), generated from
`045-hclk-cmt-pips/build/todo.txt`.
- `top.py` — delegates to 045's `top.py` so we share its MMCM/PLL/BUFR
loadload pool. Verified to emit ~3240 lines of Verilog given a SEED.
- `generate.tcl` — implements `pick_target_for_specimen` (round-robin
on SPECIMEN env) and `force_ck_in_route` (walks placed nets, finds one
in the target tile_type, builds a two-leg `find_routing_path` and pins
it with `FIXED_ROUTE`). Parses cleanly through Vivado.
- `Makefile` — N=24 (21 targets + 3 redundant retries on the first three
rows). Uses standard pip_loop.mk.
- `build/cmt_regions.csv` — symlinked from 045's prior build so we share
its CMT site→region mapping.
## How to run
```
cd fuzzers/045a-hclk-cmt-ck-in
source ../../settings/virtex7.sh # set XRAY_PART etc.
make
```
Output: `build/segbits_hclk_cmt.db` + `build/segbits_hclk_cmt_l.db`
which then merge into `database/virtex7/segbits_hclk_cmt[_l].db` via
`pushdb`-equivalent step (see 045's Makefile chain).
## What the first specimen run taught us
Ran `make N=1 build/1/specimen_001/OK` against target row 0
(`HCLK_CMT.HCLK_CMT_MUX_CLK_10.HCLK_CMT_CK_IN6`).
- top.py / generate.tcl chain runs end-to-end through Vivado:
synth → place → route_design → force_ck_in_route → route_design
→ write_bitstream → bit2fasm. ~10 min wall-clock per specimen.
- `force_ck_in_route` scanned 16 nets, found 9 candidates touching
some `HCLK_CMT` tile, tried 3, and bailed: every candidate failed
the `find_routing_path` driver→src leg. Diagnostic line:
`045a: candidate cin1_MMCME2_ADV_X0Y3 via HCLK_CMT_X88Y182 — driver can't reach src`.
- The Vivado design.bit + design.fasm are produced, but with no
target PIP used. Consequence: `int_generate.py` asserts
`"Didn't generate any segments"` because nothing in design.txt
intersects todo.txt.
## Why simple `find_routing_path` isn't enough
Each `HCLK_CMT_CK_INm` input is fed from a specific clock backbone
segment determined by *physical placement* (which BUFGCTRL site,
which BUFR site, which HCLK leaf). 045's random MMCM/PLL/BUFR
placement happens to never land in a topology where the existing
clock drivers can be re-routed to CK_IN6 — which is exactly why
those 21 PIPs survived 100 random specimens in 045 to begin with.
`find_routing_path` faithfully reports "no reachable wires" because
the driver site_pin really can't get to CK_IN6 of the chosen
HCLK_CMT tile without first being moved.
## The pivot the next session needs
Make `force_ck_in_route` *choose the design topology* per specimen,
not just react to whatever random placement landed:
1. **LOC-based force per target.** We already proved on
`~/div2_sgmii_loc_build/` that
`set_property LOC BUFGCTRL_X0Y0 [get_cells sysclk_bufg]` +
`set_property USER_CLOCK_ROOT X0Y0 [get_nets clk]` reliably
moves the clock onto a specific `HCLK_CMT_X88Y26` and lights up
one bit (`27_181`). For each target row in `targets.csv` we
need a small table of `(tile_type instance, expected_BUFG_site,
expected_BUFR_site)` triples; the proc applies those LOC
constraints before `place_design`, not after route.
2. **Drop the post-hoc find_routing_path.** Once Vivado places the
design under the LOC, the natural route will hit the target
PIP — no FIXED_ROUTE injection needed. Verify with
`get_pips -of_objects [get_nets clk]` and only commit specimens
where the target PIP shows up.
3. **Skip-not-fail in int_generate.** For specimens that did
ultimately use the target PIP, write `segdata_*.txt`; for those
that didn't, write an empty `segdata_*.txt` + `tag` line marking
the negative. Avoid the `AssertionError` and let segmatch
benefit from negative evidence.
## Pre-pivot smoke test of the chain
End-to-end pipeline works *modulo* the topology issue: ~10 min per
specimen, parses cleanly, emits bit + fasm + txt. Only the segmaker
step asserts on empty output.
## Probe result (`/tmp/ckin_probe/` on 2026-05-30)
Built a minimal `IBUF → BUFR (LOC X0Y2) → MMCM (LOC X0Y0)` design in
Vivado, dumped every PIP used in HCLK_CMT* tiles plus every PIP whose
name contains `CK_IN`.
Result: **zero HCLK_CMT PIPs used**, and the only `CK_IN` PIP in the
whole design was
`CLK_HROW_BOT_R.CLK_HROW_CK_IN_L0->>CLK_HROW_BOT_R_CK_BUFG_CASCO0`
(BUFG-cascade input, *not* an HCLK_CMT input).
Interpretation: Vivado's BUFR→MMCM routing flows entirely through the
CLK_HROW / BUFG-ring network and bypasses the HCLK_CMT entirely.
Combined with 045's history of 100 random specimens *never* hitting
the 21 unsolved CK_IN PIPs, the most likely explanation is that
**Vivado deliberately doesn't use `HCLK_CMT_CK_IN*` PIPs** for any
standard topology — they exist in silicon but the timing/closure
model avoids them.
That changes the conclusion for the open-flow problem. If Vivado
doesn't set bits for those PIPs and *still* produces a bitstream
that works on hardware, the `IBUFDS_GTE2.IN_USE` / `CK_IN8` lines
nextpnr-xilinx emits are mostly decorative — and our PPIP no-op
patch (silence fasm2frames, emit no bits) is **the correct fix**.
The open-flow VC707 counter's stuck-LED issue is therefore unlikely
to be about missing CK_IN segbits. More plausible culprits:
1. **FF clear-bits** — counter125's FFs initialise via FDRE/FDSE
`ZINI/ZRST` segbits. If the open-flow bitstream programs those
wrong (e.g. wrong `INIT` value, or `FFSYNC` flipped), the counter
starts at `0b10001000` (= LEDs 3 + 7 on, all others off, which is
exactly what we observed) and stays there.
2. **`rst` input routing** — nextpnr placed rst at `IOB_X0Y124`;
check the LIOB18 IBUF + INT-routing FASM lines against Vivado.
3. **OBUF / DRIVE / SLEW** for the LED IOBs — but those would only
affect brightness, not the bit pattern.
Picking up this thread should start at `~/counter125_build/top.fasm`
vs `top_vivado.fasm` for the **CLBLL/CLBLM SLICE FF and rst-input
IOB lines**, not the HCLK_CMT block.
## 045a status
The scaffold is preserved as-is (Makefile, top.py, generate.tcl,
targets.csv) because it might still be valuable as a **negative-result
record** — the 21 PIPs in `targets.csv` are essentially "PIPs the
silicon supports but Vivado refuses to use". A future generation that
needs to fuzz these would do so by *building the routing manually*
with `route_via` from a clean starting design, not by hoping random
placements happen to use them.
## Files
| file | role |
|---------------|------|
| `Makefile` | drives N specimens through the common segmatch chain |
| `targets.csv` | the 21 (tile_type, dst, src) tuples to fuzz |
| `top.py` | per-specimen Verilog generator (placeholder, see TODO) |
| `generate.tcl`| per-specimen Vivado driver: LOC-force the target PIP (TODO) |

View File

View File

@ -0,0 +1,150 @@
# Copyright (C) 2017-2020 The Project X-Ray Authors
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
#
# 045a CK_IN-targeted segbits for HCLK_CMT[_L].
#
# Picks one (tile_type, dst, src) target from targets.csv per specimen
# (round-robin on SPECIMEN env var), then forces a clock net through the
# CK_IN PIP using FIXED_ROUTE. Mirrors the proven pattern in 045's
# route_todo (loop through nets, find one in the right tile type, set
# FIXED_ROUTE via find_routing_path). Standard segmaker chain takes it
# from there.
source "$::env(XRAY_DIR)/utils/utils.tcl"
proc load_targets {} {
set fp [open "$::env(FUZDIR)/targets.csv" r]
gets $fp _header
set rows [list]
for {gets $fp line} {$line != ""} {gets $fp line} {
lappend rows [split $line ","]
}
close $fp
return $rows
}
proc pick_target_for_specimen {} {
# Extract specimen number from cwd (e.g. .../specimen_007 -> 7) since
# prjxray's top_generate chain doesn't export SPECIMEN as an env var.
set cwd [pwd]
set tail [file tail $cwd]
set n 0
if {![regexp {specimen_(\d+)} $tail _m num]} {
puts "045a: WARN could not parse specimen number from cwd $cwd; defaulting to 1"
set num 1
}
set n [expr {$num - 1}]
set rows [load_targets]
set row [lindex $rows [expr {$n % [llength $rows]}]]
puts "045a: specimen=$tail target_row=$n -> $row"
return $row
}
# Try to force a net through the target PIP using FIXED_ROUTE.
#
# Approach: gather candidate (net, tile) pairs FIRST without touching
# routing, score them cheaply (does the driver site_pin even share a
# clock backbone with the target tile?), and only unroute + FIXED_ROUTE
# the most promising candidate. If nothing plausible exists in this
# specimen's random placement, give up immediately leaving the design
# routed as-is instead of repeatedly unrouting nets and crashing into
# unreachable wires.
proc force_ck_in_route {target_tile_type target_dst target_src} {
puts "045a: forcing route through $target_tile_type.$target_dst.$target_src"
# Collect candidates without mutating the design.
set candidates [list]
set max_scan 16 ;# bail-out never scan more than 16 nets / specimen
set scanned 0
foreach net [get_nets] {
if {$scanned >= $max_scan} { break }
incr scanned
set hits [get_wires -of_objects $net -filter "TILE_NAME =~ *HCLK_CMT*"]
if {[llength $hits] == 0} { continue }
foreach hit $hits {
set tile [lindex [split $hit /] 0]
if {[get_property TILE_TYPE [get_tiles $tile]] != $target_tile_type} { continue }
set src_wire [get_wires "$tile/$target_src"]
set dst_wire [get_wires "$tile/$target_dst"]
if {[llength $src_wire] == 0 || [llength $dst_wire] == 0} { continue }
lappend candidates [list $net $tile $src_wire $dst_wire]
break ;# one candidate tile per net is enough
}
}
puts "045a: scanned $scanned nets, found [llength $candidates] candidate (net,tile) pairs"
if {[llength $candidates] == 0} {
puts "045a: no candidate net touches a $target_tile_type tile with $target_src and $target_dst reachable skipping this specimen"
return 0
}
# Try at most 3 candidates. For each, do ONE find_routing_path check
# *before* unrouting; only mutate the net if both legs exist.
set try_limit 3
set tried 0
foreach cand $candidates {
if {$tried >= $try_limit} { break }
incr tried
lassign $cand net tile src_wire dst_wire
set src_node [get_nodes -of_objects $src_wire]
set dst_node [get_nodes -of_objects $dst_wire]
if {[llength $src_node] == 0 || [llength $dst_node] == 0} { continue }
set origin_pin [get_site_pins -filter {DIRECTION == OUT} -of_objects $net]
if {[llength $origin_pin] == 0} { continue }
set origin_node [get_nodes -of_objects $origin_pin]
# Cheap reachability probe BEFORE we destroy any existing routing.
set leg1 [find_routing_path -to $src_node -from $origin_node]
if {[llength $leg1] == 0} {
puts "045a: candidate $net via $tile driver can't reach src; skipping"
continue
}
set leg2 [find_routing_path -to $dst_node -from $src_node]
if {[llength $leg2] == 0} {
puts "045a: candidate $net via $tile src can't reach dst; skipping"
continue
}
# Both legs check out commit.
route_design -unroute -nets $net
set_property FIXED_ROUTE [concat $leg1 $leg2] $net
puts "045a: forced $tile/$target_src -> $tile/$target_dst on net $net (candidate $tried)"
return 1
}
puts "045a: tried $tried candidates, none routable for $target_tile_type.$target_dst.$target_src leaving design unchanged for this specimen"
return 0
}
proc run {} {
create_project -force -part $::env(XRAY_PART) design design
read_verilog top.v
synth_design -top top
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
foreach drc {PDRC-29 PDRC-38 REQP-13 REQP-123 REQP-161 REQP-1575
REQP-1684 REQP-1712 AVAL-50 AVAL-78 AVAL-81} {
set_property IS_ENABLED 0 [get_drc_checks $drc]
}
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
place_design -directive Quick
route_design -directive Quick
set target [pick_target_for_specimen]
lassign $target tile_type dst src
force_ck_in_route $tile_type $dst $src
route_design -directive Quick -preserve
write_checkpoint -force design.dcp
write_bitstream -force design.bit
write_pip_txtdata design.txt
}
run

View File

@ -0,0 +1,22 @@
tile_type,dst,src
HCLK_CMT,HCLK_CMT_MUX_CLK_10,HCLK_CMT_CK_IN6
HCLK_CMT,HCLK_CMT_MUX_CLK_7,HCLK_CMT_CK_IN9
HCLK_CMT,HCLK_CMT_MUX_CLK_8,HCLK_CMT_CK_IN4
HCLK_CMT_L,HCLK_CMT_CK_IN10,HCLK_CMT_CCIO0
HCLK_CMT_L,HCLK_CMT_CK_IN11,HCLK_CMT_MUX_CLK_MMCM11
HCLK_CMT_L,HCLK_CMT_CK_IN11,HCLK_CMT_MUX_CLK_PLL5
HCLK_CMT_L,HCLK_CMT_CK_IN12,HCLK_CMT_MUX_CLK_MMCM6
HCLK_CMT_L,HCLK_CMT_CK_IN12,HCLK_CMT_MUX_CLK_PLL4
HCLK_CMT_L,HCLK_CMT_CK_IN13,HCLK_CMT_CK_BUFHCLK0
HCLK_CMT_L,HCLK_CMT_CK_IN13,HCLK_CMT_MUX_CLK_PLL3
HCLK_CMT_L,HCLK_CMT_CK_IN1,HCLK_CMT_MUX_CLK_MMCM1
HCLK_CMT_L,HCLK_CMT_CK_IN2,HCLK_CMT_MUX_CLK_6
HCLK_CMT_L,HCLK_CMT_CK_IN2,HCLK_CMT_MUX_CLK_7
HCLK_CMT_L,HCLK_CMT_CK_IN2,HCLK_CMT_MUX_CLK_MMCM4
HCLK_CMT_L,HCLK_CMT_CK_IN3,HCLK_CMT_MUX_CLK_5
HCLK_CMT_L,HCLK_CMT_CK_IN5,HCLK_CMT_MUX_CLK_PLL1
HCLK_CMT_L,HCLK_CMT_CK_IN7,HCLK_CMT_MUX_CLK_9
HCLK_CMT_L,HCLK_CMT_CK_IN8,HCLK_CMT_CK_BUFHCLK1
HCLK_CMT_L,HCLK_CMT_CK_IN8,HCLK_CMT_CK_BUFHCLK6
HCLK_CMT_L,HCLK_CMT_CK_IN8,HCLK_CMT_MUX_CLK_PLL5
HCLK_CMT_L,HCLK_CMT_CK_IN9,HCLK_CMT_CK_BUFHCLK9
1 tile_type dst src
2 HCLK_CMT HCLK_CMT_MUX_CLK_10 HCLK_CMT_CK_IN6
3 HCLK_CMT HCLK_CMT_MUX_CLK_7 HCLK_CMT_CK_IN9
4 HCLK_CMT HCLK_CMT_MUX_CLK_8 HCLK_CMT_CK_IN4
5 HCLK_CMT_L HCLK_CMT_CK_IN10 HCLK_CMT_CCIO0
6 HCLK_CMT_L HCLK_CMT_CK_IN11 HCLK_CMT_MUX_CLK_MMCM11
7 HCLK_CMT_L HCLK_CMT_CK_IN11 HCLK_CMT_MUX_CLK_PLL5
8 HCLK_CMT_L HCLK_CMT_CK_IN12 HCLK_CMT_MUX_CLK_MMCM6
9 HCLK_CMT_L HCLK_CMT_CK_IN12 HCLK_CMT_MUX_CLK_PLL4
10 HCLK_CMT_L HCLK_CMT_CK_IN13 HCLK_CMT_CK_BUFHCLK0
11 HCLK_CMT_L HCLK_CMT_CK_IN13 HCLK_CMT_MUX_CLK_PLL3
12 HCLK_CMT_L HCLK_CMT_CK_IN1 HCLK_CMT_MUX_CLK_MMCM1
13 HCLK_CMT_L HCLK_CMT_CK_IN2 HCLK_CMT_MUX_CLK_6
14 HCLK_CMT_L HCLK_CMT_CK_IN2 HCLK_CMT_MUX_CLK_7
15 HCLK_CMT_L HCLK_CMT_CK_IN2 HCLK_CMT_MUX_CLK_MMCM4
16 HCLK_CMT_L HCLK_CMT_CK_IN3 HCLK_CMT_MUX_CLK_5
17 HCLK_CMT_L HCLK_CMT_CK_IN5 HCLK_CMT_MUX_CLK_PLL1
18 HCLK_CMT_L HCLK_CMT_CK_IN7 HCLK_CMT_MUX_CLK_9
19 HCLK_CMT_L HCLK_CMT_CK_IN8 HCLK_CMT_CK_BUFHCLK1
20 HCLK_CMT_L HCLK_CMT_CK_IN8 HCLK_CMT_CK_BUFHCLK6
21 HCLK_CMT_L HCLK_CMT_CK_IN8 HCLK_CMT_MUX_CLK_PLL5
22 HCLK_CMT_L HCLK_CMT_CK_IN9 HCLK_CMT_CK_BUFHCLK9

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
""" 045a — same MMCM/PLL/BUFR loadload design as 045, just driven with a
different SEED. The per-specimen target PIP selection happens in
generate.tcl, which reads targets.csv and picks based on the SPECIMEN
env var.
We delegate to 045's top.py to avoid duplicating ~600 lines of CMT
loadload synthesis. 045's top.py reads
$FUZDIR/build/cmt_regions.csv at module level, so we temporarily
override FUZDIR for the duration of the import.
"""
import os
import sys
import runpy
# Make 045's helpers importable.
PARENT = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..', '045-hclk-cmt-pips')
sys.path.insert(0, PARENT)
# 045's top.py expects FUZDIR pointing at *its own* fuzzer dir so it can
# read build/cmt_regions.csv. Save the caller's value and restore after.
caller_fuzdir = os.environ.get('FUZDIR')
os.environ['FUZDIR'] = PARENT
try:
runpy.run_path(os.path.join(PARENT, 'top.py'), run_name='__main__')
finally:
if caller_fuzdir is None:
os.environ.pop('FUZDIR', None)
else:
os.environ['FUZDIR'] = caller_fuzdir

109
utils/strip_transplant.py Normal file
View File

@ -0,0 +1,109 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
"""
Remove segbits whose recorded provenance is a transplant (a fuzzer that
cannot run on this part, or a foreign-database copy) so the slot can be
re-filled by a real measurement.
For a given <db-type> (e.g. rioi) it edits, in lock-step:
segbits_<db-type>.db (TAG bit bit ...)
segbits_<db-type>.origin_info.db (TAG origin:<fuzzer> bit bit ...)
A tag is dropped iff its origin_info origin EXACTLY equals one of the
--origins values. Tags whose origin is a comma-joined chain (i.e. a
transplant later partly overwritten by a real fuzzer) are kept and
reported, since the chain needs the real re-fuzz merged first.
Use --apply to write; default is a dry run.
"""
import argparse
import os
import sys
def load_origins(fn):
"""tag -> origin (from a *.origin_info.db)."""
origins = {}
if not os.path.exists(fn):
return origins
for line in open(fn):
parts = line.split()
if len(parts) < 2:
continue
tag = parts[0]
# The origin token may sit right after the tag (most fuzzers) or at
# the end of the line (hand-edited entries); search all fields.
origin = None
for p in parts[1:]:
if p.startswith('origin:'):
origin = p[len('origin:'):]
break
origins[tag] = origin
return origins
def strip_file(fn, drop_tags):
"""Rewrite fn keeping only lines whose first field is not in drop_tags.
Returns (kept, removed)."""
kept, removed = [], []
for line in open(fn):
tag = line.split(' ', 1)[0].strip() if line.strip() else None
if tag in drop_tags:
removed.append(line.rstrip('\n'))
elif line.strip():
kept.append(line.rstrip('\n'))
return kept, removed
def main():
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument('--db-root', required=True)
ap.add_argument('--db-type', required=True, help='e.g. rioi, lioi_tbytesrc')
ap.add_argument(
'--origins', required=True, nargs='+',
help='origin strings to drop (exact match), e.g. 035-iob-ilogic')
ap.add_argument('--apply', action='store_true', help='write changes')
args = ap.parse_args()
seg = os.path.join(args.db_root, 'segbits_%s.db' % args.db_type)
org = os.path.join(args.db_root, 'segbits_%s.origin_info.db' % args.db_type)
if not os.path.exists(org):
print(' %s: no origin_info db, skipping' % args.db_type)
return 0
origins = load_origins(org)
bad = set(args.origins)
drop = {t for t, o in origins.items() if o in bad}
chained = {
t: o
for t, o in origins.items()
if o and ',' in o and any(b in o.split(',') for b in bad)
}
print('[%s] drop %d tags with origin in %s' % (args.db_type, len(drop), sorted(bad)))
if chained:
print(' NOTE %d chained-origin tags kept (need real re-fuzz merged '
'first): %s' % (len(chained), sorted(chained)[:4]))
for fn in (seg, org):
if not os.path.exists(fn):
continue
kept, removed = strip_file(fn, drop)
print(' %s: %d kept, %d removed' % (os.path.basename(fn), len(kept), len(removed)))
if args.apply:
with open(fn, 'w') as f:
f.write('\n'.join(sorted(kept)) + ('\n' if kept else ''))
if not args.apply:
print(' (dry run; pass --apply to write)')
return 0
if __name__ == '__main__':
sys.exit(main())