mirror of https://github.com/openXC7/prjxray.git
Working complete HROW pip fuzzer.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
023cd55bb1
commit
c2df5c97eb
|
|
@ -84,7 +84,7 @@ def run(fn_in, fn_out, verbose=False):
|
|||
("bram_block/build/segbits_tilegrid.tdb", 128, 10),
|
||||
("clb/build/segbits_tilegrid.tdb", 36, 2),
|
||||
("dsp/build/segbits_tilegrid.tdb", 28, 10),
|
||||
("clk_hrow/build/segbits_tilegrid.tdb", 30, 7),
|
||||
("clk_hrow/build/segbits_tilegrid.tdb", 30, 18),
|
||||
("clk_bufg/build/segbits_tilegrid.tdb", 30, 8),
|
||||
("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words),
|
||||
("iob_int/build/segbits_tilegrid.tdb", int_frames, int_words),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
N ?= 5
|
||||
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 1 --dframe 1A"
|
||||
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 6 --dframe 1A"
|
||||
include ../fuzzaddr/common.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ def propagate_rebuf(database, tiles_by_grid):
|
|||
rebuf_below]['type']
|
||||
|
||||
assert database[tile_name]['bits']['CLB_IO_CLK'][
|
||||
'offset'] == 47, database[tile_name]['bits']['CLB_IO_CLK']
|
||||
'offset'] == 42, database[tile_name]['bits']['CLB_IO_CLK']
|
||||
database[rebuf_below]['bits'] = copy.deepcopy(
|
||||
database[tile_name]['bits'])
|
||||
database[rebuf_below]['bits']['CLB_IO_CLK']['offset'] = 73
|
||||
|
|
|
|||
|
|
@ -5,12 +5,15 @@ PIPLIST_TCL=$(FUZDIR)/clk_hrow_pip_list.tcl
|
|||
ifeq (${XRAY_PART}, xc7z010clg400-1)
|
||||
# xc7z010clg400-1 is missing some side clock connections, so these bits cannot
|
||||
# be documented.
|
||||
# FIXME: Use EXCLUDE_RE rather than complicated include RE.
|
||||
TODO_RE="[^\.]+\.CLK_HROW_CK_MUX_OUT_[LR][0-9]+\.CLK_HROW_.*[KR_][0-9]+"
|
||||
TODO_EXCLUDE_RE="^CLK_HROW_BOT_R.*CASCIN[0-9]+$$"
|
||||
else
|
||||
TODO_RE=".*"
|
||||
TODO_EXCLUDE_RE="^CLK_HROW_BOT_R.*CASCIN[0-9]+$$"
|
||||
endif
|
||||
|
||||
MAKETODO_FLAGS=--sides "bot_r,top_r" --pip-type ${PIP_TYPE} --seg-type clk_hrow --re $(TODO_RE)
|
||||
MAKETODO_FLAGS=--sides "bot_r,top_r" --pip-type ${PIP_TYPE} --seg-type clk_hrow --re $(TODO_RE) --exclude-re $(TODO_EXCLUDE_RE)
|
||||
N = 50
|
||||
|
||||
# These PIPs all appear to be either a 2 bit solutions.
|
||||
|
|
@ -20,39 +23,49 @@ A_PIPLIST=clk_hrow_bot_r.txt
|
|||
|
||||
include ../pip_loop.mk
|
||||
|
||||
database: build/segbits_clk_hrow.db
|
||||
|
||||
build/cmt_regions.csv: output_cmt.tcl
|
||||
mkdir -p build
|
||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl
|
||||
|
||||
build/segbits_clk_hrow.rdb: $(SPECIMENS_OK)
|
||||
${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow.rdb \
|
||||
$(shell find build -name segdata_clk_hrow_top_r.txt) \
|
||||
$(shell find build -name segdata_clk_hrow_bot_r.txt)
|
||||
|
||||
build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb
|
||||
database: build/segbits_clk_hrow_bot_r.rdb build/segbits_clk_hrow_top_r.rdb
|
||||
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \
|
||||
--seg-fn-in build/segbits_clk_hrow.rdb \
|
||||
--seg-fn-out build/segbits_clk_hrow.db
|
||||
--seg-fn-in build/segbits_clk_hrow_top_r.rdb \
|
||||
--seg-fn-out build/segbits_clk_hrow_top_r.db
|
||||
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \
|
||||
--seg-fn-in build/segbits_clk_hrow_bot_r.rdb \
|
||||
--seg-fn-out build/segbits_clk_hrow_bot_r.db
|
||||
|
||||
# Keep a copy to track iter progress
|
||||
cp build/segbits_clk_hrow.rdb build/$(ITER)/segbits_clk_hrow.rdb
|
||||
cp build/segbits_clk_hrow_top_r.rdb build/$(ITER)/segbits_clk_hrow_top_r.rdb
|
||||
cp build/segbits_clk_hrow_bot_r.rdb build/$(ITER)/segbits_clk_hrow_bot_r.rdb
|
||||
|
||||
${XRAY_MASKMERGE} build/mask_clk_hrow.db \
|
||||
$(shell find build -name segdata_clk_hrow_top_r.txt) \
|
||||
${XRAY_MASKMERGE} build/mask_clk_hrow_top_r.db \
|
||||
$(shell find build -name segdata_clk_hrow_top_r.txt)
|
||||
${XRAY_MASKMERGE} build/mask_clk_hrow_bot_r.db \
|
||||
$(shell find build -name segdata_clk_hrow_bot_r.txt)
|
||||
|
||||
# Clobber existing .db to eliminate potential conflicts
|
||||
rm -f build/database/${XRAY_DATABASE}/*
|
||||
cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits*.db build/database/${XRAY_DATABASE}
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow_bot_r.db
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow_top_r.db
|
||||
|
||||
build/cmt_regions.csv: output_cmt.tcl
|
||||
mkdir -p build
|
||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl
|
||||
|
||||
generate: $(SPECIMENS_OK)
|
||||
|
||||
build/segbits_clk_hrow_top_r.rdb: $(SPECIMENS_OK)
|
||||
${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow_top_r.rdb \
|
||||
$(shell find build -name segdata_clk_hrow_top_r.txt)
|
||||
|
||||
build/segbits_clk_hrow_bot_r.rdb: $(SPECIMENS_OK)
|
||||
${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow_bot_r.rdb \
|
||||
$(shell find build -name segdata_clk_hrow_bot_r.txt)
|
||||
|
||||
build/segbits_clk_hrow.db: build/segbits_clk_hrow_top_.rdb
|
||||
|
||||
pushdb: database
|
||||
${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db
|
||||
${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db
|
||||
${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow.db
|
||||
${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow.db
|
||||
${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow_bot_r.db
|
||||
${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow_top_r.db
|
||||
${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow_bot_r.db
|
||||
${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow_top_r.db
|
||||
|
||||
.PHONY: database pushdb
|
||||
.PHONY: database pushdb generate
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import os
|
||||
import os.path
|
||||
from prjxray.segmaker import Segmaker
|
||||
import pprint
|
||||
|
||||
|
||||
def main():
|
||||
|
|
@ -12,6 +11,7 @@ def main():
|
|||
tiledata = {}
|
||||
pipdata = {}
|
||||
clk_list = {}
|
||||
casco_list = {}
|
||||
ignpip = set()
|
||||
|
||||
with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build',
|
||||
|
|
@ -21,9 +21,13 @@ def main():
|
|||
if tile_type not in pipdata:
|
||||
pipdata[tile_type] = []
|
||||
clk_list[tile_type] = set()
|
||||
casco_list[tile_type] = set()
|
||||
|
||||
pipdata[tile_type].append((src, dst))
|
||||
|
||||
if 'CASCO' in dst:
|
||||
casco_list[tile_type].add(dst)
|
||||
|
||||
if dst.startswith('CLK_HROW_CK_MUX_OUT_'):
|
||||
clk_list[tile_type].add(src)
|
||||
|
||||
|
|
@ -34,9 +38,13 @@ def main():
|
|||
if tile_type not in pipdata:
|
||||
pipdata[tile_type] = []
|
||||
clk_list[tile_type] = set()
|
||||
casco_list[tile_type] = set()
|
||||
|
||||
pipdata[tile_type].append((src, dst))
|
||||
|
||||
if 'CASCO' in dst:
|
||||
casco_list[tile_type].add(dst)
|
||||
|
||||
if dst.startswith('CLK_HROW_CK_MUX_OUT_'):
|
||||
clk_list[tile_type].add(src)
|
||||
|
||||
|
|
@ -78,7 +86,6 @@ def main():
|
|||
active_gclks = {}
|
||||
active_clks = {}
|
||||
|
||||
|
||||
for tile, pips_srcs_dsts in tiledata.items():
|
||||
tile_type = pips_srcs_dsts["type"]
|
||||
pips = pips_srcs_dsts["pips"]
|
||||
|
|
@ -87,15 +94,13 @@ def main():
|
|||
active_clks[tile] = set()
|
||||
|
||||
for src, dst in pips_srcs_dsts["pips"]:
|
||||
if dst.startswith('CLK_HROW_CK_MUX_OUT_'):
|
||||
active_clks[tile].add(src)
|
||||
|
||||
active_clks[tile].add(src)
|
||||
if 'GCLK' in src:
|
||||
if src not in active_gclks:
|
||||
active_gclks[src] = set()
|
||||
|
||||
if 'GCLK' in src:
|
||||
if src not in active_gclks:
|
||||
active_gclks[src] = set()
|
||||
|
||||
active_gclks[src].add(tile)
|
||||
active_gclks[src].add(tile)
|
||||
|
||||
for src, dst in pipdata[tile_type]:
|
||||
if (src, dst) in ignpip:
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ proc route_todo {} {
|
|||
}
|
||||
|
||||
set origin_node [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $net]]
|
||||
set destination_nodes [get_nodes -of_objects [get_site_pins -filter {DIRECTION == IN} -of_objects $net]]
|
||||
set destination_nodes [filter [get_nodes -of_objects [get_site_pins -filter {DIRECTION == IN} -of_objects $net]] {NAME =~ *CLK_HROW*}]
|
||||
route_design -unroute -nets $net
|
||||
set new_route [find_routing_path -to $target_node -from $origin_node]
|
||||
puts "Origin node: $origin_node"
|
||||
|
|
@ -151,6 +151,7 @@ proc run {} {
|
|||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
set_property IS_ENABLED 0 [get_drc_checks {REQP-161}]
|
||||
set_property IS_ENABLED 0 [get_drc_checks {REQP-123}]
|
||||
set_property IS_ENABLED 0 [get_drc_checks {REQP-13}]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ set_property design_mode PinPlanning [current_fileset]
|
|||
open_io_design -name io_1
|
||||
|
||||
set fp [open "cmt_regions.csv" "w"]
|
||||
foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE} {
|
||||
foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE BUFR} {
|
||||
foreach site [get_sites -filter "SITE_TYPE == $site_type"] {
|
||||
puts $fp "$site,[get_property CLOCK_REGION $site]"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
""" Emits top.v's for various BUFHCE routing inputs. """
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray import verilog
|
||||
from prjxray.db import Database
|
||||
from prjxray.lut_maker import LutMaker
|
||||
from io import StringIO
|
||||
|
||||
CMT_XY_FUN = util.create_xy_fun(prefix='')
|
||||
BUFGCTRL_XY_FUN = util.create_xy_fun('BUFGCTRL_')
|
||||
BUFHCE_XY_FUN = util.create_xy_fun('BUFHCE_')
|
||||
|
||||
|
||||
def gen_sites(desired_site_type):
|
||||
|
|
@ -17,7 +23,7 @@ def gen_sites(desired_site_type):
|
|||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
for site, site_type in gridinfo.sites.items():
|
||||
if site_type == desired_site_type:
|
||||
yield site
|
||||
yield loc, gridinfo.tile_type, site
|
||||
|
||||
|
||||
def gen_bufhce_sites():
|
||||
|
|
@ -59,8 +65,10 @@ class ClockSources(object):
|
|||
self.merged_sources = {}
|
||||
self.source_to_cmt = {}
|
||||
self.used_sources_from_cmt = {}
|
||||
self.sources_by_loc = {}
|
||||
self.active_cmt_ports = {}
|
||||
|
||||
def add_clock_source(self, source, cmt):
|
||||
def add_clock_source(self, source, cmt, loc=None):
|
||||
""" Adds a source from a specific CMT.
|
||||
|
||||
cmt='ANY' indicates that this source can be routed to any CMT.
|
||||
|
|
@ -73,6 +81,14 @@ class ClockSources(object):
|
|||
source] == cmt, source
|
||||
self.source_to_cmt[source] = cmt
|
||||
|
||||
self.add_bufg_clock_source(source, cmt, loc)
|
||||
|
||||
def add_bufg_clock_source(self, source, cmt, loc):
|
||||
if loc not in self.sources_by_loc:
|
||||
self.sources_by_loc[loc] = []
|
||||
|
||||
self.sources_by_loc[loc].append((cmt, source))
|
||||
|
||||
def get_random_source(self, cmt):
|
||||
""" Get a random source that is routable to the specific CMT.
|
||||
|
||||
|
|
@ -113,12 +129,91 @@ class ClockSources(object):
|
|||
|
||||
if source_cmt != 'ANY' and len(
|
||||
self.used_sources_from_cmt[source_cmt]) > 14:
|
||||
print('//', self.used_sources_from_cmt)
|
||||
self.used_sources_from_cmt[source_cmt].remove(source)
|
||||
return None
|
||||
else:
|
||||
return source
|
||||
|
||||
def get_bufg_source(self, loc, tile_type, site, todos, i_wire, used_only):
|
||||
bufg_sources = []
|
||||
|
||||
top = '_TOP_' in tile_type
|
||||
bottom = '_BOT_' in tile_type
|
||||
|
||||
assert top ^ bottom, tile_type
|
||||
|
||||
if top:
|
||||
for src_loc, cmt_sources in self.sources_by_loc.items():
|
||||
if src_loc is None:
|
||||
continue
|
||||
if src_loc.grid_y <= loc.grid_y:
|
||||
bufg_sources.extend(cmt_sources)
|
||||
elif bottom:
|
||||
for src_loc, cmt_sources in self.sources_by_loc.items():
|
||||
if src_loc is None:
|
||||
continue
|
||||
if src_loc.grid_y > loc.grid_y:
|
||||
bufg_sources.extend(cmt_sources)
|
||||
|
||||
# CLK_HROW_TOP_R_CK_BUFG_CASCO0 -> CLK_BUFG_BUFGCTRL0_I0
|
||||
# CLK_HROW_TOP_R_CK_BUFG_CASCO22 -> CLK_BUFG_BUFGCTRL11_I0
|
||||
# CLK_HROW_TOP_R_CK_BUFG_CASCO23 -> CLK_BUFG_BUFGCTRL11_I1
|
||||
# CLK_HROW_BOT_R_CK_BUFG_CASCO27 -> CLK_BUFG_BUFGCTRL13_I1
|
||||
|
||||
x, y = BUFGCTRL_XY_FUN(site)
|
||||
assert x == 0
|
||||
y = y % 16
|
||||
|
||||
|
||||
assert i_wire in [0, 1], i_wire
|
||||
|
||||
casco_wire = '{tile_type}_CK_BUFG_CASCO{casco_idx}'.format(
|
||||
tile_type=tile_type.replace('BUFG', 'HROW'),
|
||||
casco_idx=(y*2+i_wire))
|
||||
|
||||
if casco_wire not in todos:
|
||||
return None
|
||||
|
||||
target_wires = []
|
||||
|
||||
need_bufr = False
|
||||
for src_wire in todos[casco_wire]:
|
||||
if 'BUFRCLK' in src_wire:
|
||||
need_bufr = True
|
||||
break
|
||||
|
||||
for cmt, wire in bufg_sources:
|
||||
if 'BUFR' in wire:
|
||||
if need_bufr:
|
||||
target_wires.append((cmt, wire))
|
||||
else:
|
||||
target_wires.append((cmt, wire))
|
||||
|
||||
random.shuffle(target_wires)
|
||||
for cmt, source in target_wires:
|
||||
if cmt == 'ANY':
|
||||
return source
|
||||
else:
|
||||
# Make sure to not try to import move than 14 sources from
|
||||
# the CMT, there is limited routing.
|
||||
if cmt not in self.used_sources_from_cmt:
|
||||
self.used_sources_from_cmt[cmt] = set()
|
||||
|
||||
if source in self.used_sources_from_cmt[cmt]:
|
||||
return source
|
||||
elif used_only:
|
||||
continue
|
||||
|
||||
if len(self.used_sources_from_cmt[cmt]) < 14:
|
||||
self.used_sources_from_cmt[cmt].add(source)
|
||||
return source
|
||||
else:
|
||||
continue
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def check_allowed(mmcm_pll_dir, cmt):
|
||||
""" Check whether the CMT specified is in the allowed direction.
|
||||
|
|
@ -140,6 +235,45 @@ def check_allowed(mmcm_pll_dir, cmt):
|
|||
else:
|
||||
assert False, mmcm_pll_dir
|
||||
|
||||
def read_todo():
|
||||
dsts = {}
|
||||
|
||||
with open(os.path.join('..', 'todo_all.txt')) as f:
|
||||
for l in f:
|
||||
tile_type, dst, src = l.strip().split('.')
|
||||
|
||||
if dst not in dsts:
|
||||
dsts[dst] = set()
|
||||
|
||||
dsts[dst].add(src)
|
||||
|
||||
return dsts
|
||||
|
||||
def need_int_connections(todos):
|
||||
for srcs in todos.values():
|
||||
for src in srcs:
|
||||
if re.search('INT_._.', src):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def bufhce_in_todo(todos, site):
|
||||
if 'BUFHCE' in site:
|
||||
# CLK_HROW_CK_MUX_OUT_R9 -> X1Y9
|
||||
# CLK_HROW_CK_MUX_OUT_L11 -> X0Y35
|
||||
x, y = BUFHCE_XY_FUN(site)
|
||||
y = y % 12
|
||||
|
||||
if x == 0:
|
||||
lr = 'L'
|
||||
elif x == 1:
|
||||
lr = 'R'
|
||||
else:
|
||||
assert False, x
|
||||
|
||||
return 'CLK_HROW_CK_MUX_OUT_{lr}{y}'.format(lr=lr, y=y) in todos
|
||||
else:
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""
|
||||
|
|
@ -166,26 +300,27 @@ module top();
|
|||
mmcm_pll_only = random.randint(0, 1)
|
||||
mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH', 'NONE'))
|
||||
|
||||
todos = read_todo()
|
||||
|
||||
if not mmcm_pll_only:
|
||||
for _ in range(2):
|
||||
clock_sources.add_clock_source('one', 'ANY')
|
||||
clock_sources.add_clock_source('zero', 'ANY')
|
||||
if need_int_connections(todos):
|
||||
for _ in range(10):
|
||||
clock_sources.add_clock_source('one', 'ANY')
|
||||
clock_sources.add_clock_source('zero', 'ANY')
|
||||
|
||||
print("""
|
||||
wire zero = 0;
|
||||
wire one = 1;""")
|
||||
|
||||
for site in gen_sites('MMCME2_ADV'):
|
||||
for loc, _, site in gen_sites('MMCME2_ADV'):
|
||||
mmcm_clocks = [
|
||||
'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx)
|
||||
for idx in range(13)
|
||||
]
|
||||
|
||||
if not check_allowed(mmcm_pll_dir, site_to_cmt[site]):
|
||||
continue
|
||||
|
||||
for clk in mmcm_clocks:
|
||||
clock_sources.add_clock_source(clk, site_to_cmt[site])
|
||||
if check_allowed(mmcm_pll_dir, site_to_cmt[site]):
|
||||
for clk in mmcm_clocks:
|
||||
clock_sources.add_clock_source(clk, site_to_cmt[site], loc)
|
||||
|
||||
print(
|
||||
"""
|
||||
|
|
@ -223,17 +358,15 @@ module top();
|
|||
c12=mmcm_clocks[12],
|
||||
))
|
||||
|
||||
for site in gen_sites('PLLE2_ADV'):
|
||||
for loc, _, site in gen_sites('PLLE2_ADV'):
|
||||
pll_clocks = [
|
||||
'pll_clock_{site}_{idx}'.format(site=site, idx=idx)
|
||||
for idx in range(6)
|
||||
]
|
||||
|
||||
if not check_allowed(mmcm_pll_dir, site_to_cmt[site]):
|
||||
continue
|
||||
|
||||
for clk in pll_clocks:
|
||||
clock_sources.add_clock_source(clk, site_to_cmt[site])
|
||||
if check_allowed(mmcm_pll_dir, site_to_cmt[site]):
|
||||
for clk in pll_clocks:
|
||||
clock_sources.add_clock_source(clk, site_to_cmt[site], loc)
|
||||
|
||||
print(
|
||||
"""
|
||||
|
|
@ -257,30 +390,65 @@ module top();
|
|||
c5=pll_clocks[5],
|
||||
))
|
||||
|
||||
for loc, _, site in gen_sites('BUFR'):
|
||||
clock_sources.add_bufg_clock_source('O_{site}'.format(site=site), site_to_cmt[site], loc)
|
||||
print("""
|
||||
wire O_{site};
|
||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||
BUFR bufr_{site} (
|
||||
.O(O_{site})
|
||||
);""".format(site=site))
|
||||
|
||||
luts = LutMaker()
|
||||
bufhs = StringIO()
|
||||
bufgs = StringIO()
|
||||
|
||||
gclks = []
|
||||
for site in sorted(gen_sites("BUFGCTRL"),
|
||||
key=util.create_xy_fun('BUFGCTRL_')):
|
||||
wire_name = 'clk_{}'.format(site)
|
||||
for _, _, site in sorted(gen_sites("BUFGCTRL"),
|
||||
key=lambda x: BUFGCTRL_XY_FUN(x[2])):
|
||||
wire_name = 'gclk_{}'.format(site)
|
||||
gclks.append(wire_name)
|
||||
|
||||
if not mmcm_pll_only:
|
||||
clock_sources.add_clock_source(wire_name, 'ANY')
|
||||
|
||||
print("""
|
||||
wire {wire_name};
|
||||
""".format(wire_name=wire_name))
|
||||
print(
|
||||
"""
|
||||
wire {wire_name};
|
||||
wire I1_{site};
|
||||
wire I0_{site};
|
||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||
BUFG bufg_{site} (
|
||||
.O({wire_name})
|
||||
BUFGCTRL bufg_{site} (
|
||||
.O({wire_name}),
|
||||
.S1({s1net}),
|
||||
.S0({s0net}),
|
||||
.IGNORE1({ignore1net}),
|
||||
.IGNORE0({ignore0net}),
|
||||
.I1(I1_{site}),
|
||||
.I0(I0_{site}),
|
||||
.CE1({ce1net}),
|
||||
.CE0({ce0net})
|
||||
);
|
||||
""".format(
|
||||
site=site,
|
||||
wire_name=wire_name,
|
||||
))
|
||||
s1net=luts.get_next_output_net(),
|
||||
s0net=luts.get_next_output_net(),
|
||||
ignore1net=luts.get_next_output_net(),
|
||||
ignore0net=luts.get_next_output_net(),
|
||||
ce1net=luts.get_next_output_net(),
|
||||
ce0net=luts.get_next_output_net(),
|
||||
), file=bufgs)
|
||||
|
||||
|
||||
any_bufhce = False
|
||||
for tile_name, sites in gen_bufhce_sites():
|
||||
for site in sites:
|
||||
if not bufhce_in_todo(todos, site):
|
||||
continue
|
||||
|
||||
any_bufhce = True
|
||||
print(
|
||||
"""
|
||||
|
|
@ -291,10 +459,11 @@ module top();
|
|||
);
|
||||
""".format(
|
||||
site=site,
|
||||
))
|
||||
), file=bufhs)
|
||||
|
||||
if random.random() > .05:
|
||||
wire_name = clock_sources.get_random_source(site_to_cmt[site])
|
||||
|
||||
if wire_name is None:
|
||||
continue
|
||||
|
||||
|
|
@ -302,7 +471,7 @@ module top();
|
|||
assign I_{site} = {wire_name};""".format(
|
||||
site=site,
|
||||
wire_name=wire_name,
|
||||
))
|
||||
), file=bufhs)
|
||||
|
||||
|
||||
if not any_bufhce:
|
||||
|
|
@ -311,16 +480,52 @@ module top();
|
|||
print(
|
||||
"""
|
||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||
BUFHCE buf_{site} (
|
||||
BUFHCE #(
|
||||
.INIT_OUT({INIT_OUT}),
|
||||
.CE_TYPE({CE_TYPE}),
|
||||
.IS_CE_INVERTED({IS_CE_INVERTED})
|
||||
) buf_{site} (
|
||||
.I({wire_name})
|
||||
);
|
||||
""".format(
|
||||
INIT_OUT=random.randint(0, 1),
|
||||
CE_TYPE=verilog.quote(
|
||||
random.choice(('SYNC', 'ASYNC'))),
|
||||
IS_CE_INVERTED = random.randint(0, 1),
|
||||
site=site,
|
||||
wire_name=gclks[0],
|
||||
))
|
||||
break
|
||||
break
|
||||
|
||||
for l in luts.create_wires_and_luts():
|
||||
print(l)
|
||||
|
||||
print(bufhs.getvalue())
|
||||
print(bufgs.getvalue())
|
||||
|
||||
used_only = random.random() < .25
|
||||
|
||||
for loc, tile_type, site in sorted(gen_sites("BUFGCTRL"),
|
||||
key=lambda x: BUFGCTRL_XY_FUN(x[2])):
|
||||
if random.randint(0, 1):
|
||||
wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 1, used_only)
|
||||
if wire_name is not None:
|
||||
print("""
|
||||
assign I1_{site} = {wire_name};""".format(
|
||||
site=site,
|
||||
wire_name=wire_name,
|
||||
))
|
||||
|
||||
if random.randint(0, 1):
|
||||
wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 0, used_only)
|
||||
if wire_name is not None:
|
||||
print("""
|
||||
assign I0_{site} = {wire_name};""".format(
|
||||
site=site,
|
||||
wire_name=wire_name,
|
||||
))
|
||||
|
||||
print("endmodule")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ def load_pipfile(pipfile, verbose=False):
|
|||
return todos, tile_type
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile, intre, not_endswith=None, verbose=False):
|
||||
def maketodo(pipfile, dbfile, intre, exclude_re=None, not_endswith=None, verbose=False):
|
||||
'''
|
||||
db files start with INT., but pipfile lines start with INT_L
|
||||
Normalize by removing before the first dot
|
||||
|
|
@ -75,8 +75,15 @@ def maketodo(pipfile, dbfile, intre, not_endswith=None, verbose=False):
|
|||
drops = 0
|
||||
lines = 0
|
||||
for line in todos:
|
||||
if re.match(intre, line) and (not_endswith is None
|
||||
or not line.endswith(not_endswith)):
|
||||
include = re.match(intre, line) is not None
|
||||
|
||||
if include and not_endswith is not None:
|
||||
include = not line.endswith(not_endswith)
|
||||
|
||||
if include and exclude_re is not None:
|
||||
include = re.match(exclude_re, line) is None
|
||||
|
||||
if include:
|
||||
print(line)
|
||||
else:
|
||||
drops += 1
|
||||
|
|
@ -94,6 +101,7 @@ def run(
|
|||
r,
|
||||
pip_type,
|
||||
seg_type,
|
||||
exclude_re=None,
|
||||
not_endswith=None,
|
||||
verbose=False):
|
||||
if db_dir is None:
|
||||
|
|
@ -117,7 +125,8 @@ def run(
|
|||
"%s/%s_%s.txt" % (pip_dir, pip_type, side),
|
||||
"%s/segbits_%s_%s.db" % (db_dir, seg_type, side),
|
||||
intre,
|
||||
not_endswith,
|
||||
exclude_re=exclude_re,
|
||||
not_endswith=not_endswith,
|
||||
verbose=verbose)
|
||||
|
||||
|
||||
|
|
@ -132,6 +141,7 @@ def main():
|
|||
parser.add_argument('--db-dir', default=None, help='')
|
||||
parser.add_argument('--pip-dir', default=None, help='')
|
||||
parser.add_argument('--re', required=True, help='')
|
||||
parser.add_argument('--exclude-re', required=False, default=None, help='')
|
||||
parser.add_argument('--pip-type', default="pips_int", help='')
|
||||
parser.add_argument('--seg-type', default="int", help='')
|
||||
parser.add_argument('--sides', default="l,r", help='')
|
||||
|
|
@ -146,6 +156,7 @@ def main():
|
|||
db_dir=args.db_dir,
|
||||
pip_dir=args.pip_dir,
|
||||
intre=args.re,
|
||||
exclude_re=args.exclude_re,
|
||||
sides=args.sides.split(','),
|
||||
l=args.l,
|
||||
r=args.r,
|
||||
|
|
|
|||
Loading…
Reference in New Issue