Isolate IMUX<x>.GFAN[01] pips into seperate fuzzer.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2019-02-19 07:43:56 -08:00
parent aa88f68da7
commit 72ffe32e33
11 changed files with 202 additions and 32 deletions

View File

@ -0,0 +1,4 @@
N = 5
MAKETODO_FLAGS=--re "^INT_[LR].IMUX[^\.]+\.GFAN[01]$$"
include ../int_loop.mk

View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
import re
import os
from prjxray.segmaker import Segmaker
from prjxray.bitfilter import get_bitfilter
segmk = Segmaker("design.bits")
tiledata = dict()
pipdata = dict()
ignpip = set()
print("Loading tags from design.txt.")
with open("design.txt", "r") as f:
for line in f:
tile, pip, src, dst, pnum, pdir = line.split()
if not tile.startswith('INT_'):
continue
_, pip = pip.split(".")
_, src = src.split("/")
_, dst = dst.split("/")
pnum = int(pnum)
pdir = int(pdir)
if tile not in tiledata:
tiledata[tile] = {"pips": set(), "srcs": set(), "dsts": set()}
if pip in pipdata:
assert pipdata[pip] == (src, dst)
else:
pipdata[pip] = (src, dst)
tiledata[tile]["pips"].add(pip)
tiledata[tile]["srcs"].add(src)
tiledata[tile]["dsts"].add(dst)
if pdir == 0:
tiledata[tile]["srcs"].add(dst)
tiledata[tile]["dsts"].add(src)
imux = re.match('^IMUX(_L)?[0-9]+$', dst) is not None
if not imux:
ignpip.add(pip)
for tile, pips_srcs_dsts in tiledata.items():
pips = pips_srcs_dsts["pips"]
srcs = pips_srcs_dsts["srcs"]
dsts = pips_srcs_dsts["dsts"]
for pip, src_dst in pipdata.items():
src, dst = src_dst
if pip in ignpip:
pass
else:
if re.match('^GFAN[01]', src):
print(tile, src, dst, pip in pips)
segmk.add_tile_tag(tile, "%s.%s" % (dst, src), pip in pips)
segmk.compile(bitfilter=get_bitfilter(os.getenv('XRAY_DATABASE'), 'INT'))
segmk.write()

View File

@ -0,0 +1,4 @@
source "$::env(XRAY_DIR)/utils/utils.tcl"
generate_top
write_pip_txtdata design.txt

View File

@ -0,0 +1,91 @@
import os
import random
import itertools
from prjxray import util
from prjxray.db import Database
random.seed(int(os.getenv("SEED"), 16))
def gen_sites(lr):
db = Database(util.get_db_root())
grid = db.grid()
for tile_name in grid.tiles():
loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc)
if gridinfo.tile_type[-1] != lr:
continue
sites = []
for site_name, site_type in gridinfo.sites.items():
if site_type in ['SLICEL', 'SLICEM']:
sites.append(site_name)
if not sites:
continue
print('// ', gridinfo.tile_type)
yield sorted(sites)
def yield_bits(bits, nvals):
for i in range(nvals):
mask = (1 << i)
yield int(bool(bits & mask))
NUM_IMUX_INPUTS = 2*6*4
NUM_TILES = 20
def emit_luts(choices, spec_idx, lr):
for idx, sites in enumerate(itertools.islice(gen_sites(lr), 0, NUM_TILES)):
cidx = idx+spec_idx*NUM_TILES
if cidx < len(choices):
bits = choices[cidx]
else:
bits = random.randint(0, 2**NUM_IMUX_INPUTS-1)
itr = yield_bits(bits, nvals=NUM_IMUX_INPUTS)
for site in sites:
for lut in range(4):
print('''
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
LUT6 {site}_lut{lut} (
.I0({I0}),
.I1({I1}),
.I2({I2}),
.I3({I3}),
.I4({I4}),
.I5({I5})
);'''.format(
site=site,
lut=lut,
I0=next(itr),
I1=next(itr),
I2=next(itr),
I3=next(itr),
I4=next(itr),
I5=next(itr),
))
def run():
print('''
module top();
''')
choices = util.gen_fuzz_choices(nvals=NUM_IMUX_INPUTS)
spec_idx = util.specn()-1
emit_luts(choices, spec_idx, 'L')
emit_luts(choices, spec_idx, 'R')
print("endmodule")
if __name__ == '__main__':
run()

View File

@ -84,7 +84,7 @@ run:
# Because 056 cannot solve IMUX and LOGIC_OUTS, force zero entries for the
# LOGIC_OUTS or IMUX entries.
XRAY_DIR=${XRAY_DIR} MAKE="$(MAKE)" QUICK=$(QUICK) $(XRAY_DIR)/fuzzers/int_loop.sh \
--check-args "--max-iters 12 --min-progress 50 --zero-entries --zero-entries-filter (IMUX.*GFAN)"
--check-args "--max-iters 12 --min-progress 50"
touch run.ok
clean:

View File

@ -42,7 +42,6 @@ with open("design.txt", "r") as f:
tiledata[tile]["srcs"].add(dst)
tiledata[tile]["dsts"].add(src)
fan_alt_dst = re.match('^FAN_ALT[0-9]$', dst) is not None
gfan_src = re.match('^GFAN', src) is not None
# Okay: BYP_ALT0.VCC_WIRE
@ -51,7 +50,7 @@ with open("design.txt", "r") as f:
src == "VCC_WIRE" or \
re.match(r"^(L[HV]B?|G?CLK)(_L)?(_B)?[0-9]", src) or \
re.match(r"^(L[HV]B?|G?CLK)(_L)?(_B)?[0-9]", dst) or \
(fan_alt_dst and gfan_src) or \
gfan_src or \
re.match(r"^(CTRL|GFAN)(_L)?[0-9]", dst):
ignpip.add(pip)

View File

@ -1,4 +1,4 @@
MAKETODO_FLAGS=--re "^INT_[LR].FAN_ALT.*GFAN"
MAKETODO_FLAGS=--re "^INT_[LR].(?!IMUX)[^\.]+.\.GFAN[0-9]$$"
GENERATE_FLAGS=--todo ../todo.txt
N = 48
SEGMATCH_FLAGS=-m 30 -M 45 -c 2

View File

@ -1,5 +1,5 @@
Fuzzer for the ALT_FAN.*GFAN PIPs
Fuzzer for the ALT_FAN.*GFAN PIPs and BYP_ALT.*GFAN PIPs
---------------------------------
This fuzzer solves the ALT_FAN.GFAN PIPs which had collisions with the GFAN PIPs.

View File

@ -1,6 +1,6 @@
MAKETODO_FLAGS=--re ".*" --not-endswith ".VCC_WIRE"
GENERATE_FLAGS=--todo ../todo.txt
N = 48
N = 24
SEGMATCH_FLAGS=-m 20 -M 45
include ../int_loop.mk

View File

@ -75,13 +75,14 @@ $(eval $(call fuzzer,041-clk-hrow-pips,005-tilegrid))
# 042 fuzzer is unstable, issue #657
#$(eval $(call fuzzer,042-clk-bufg-config,005-tilegrid))
$(eval $(call fuzzer,043-clk-rebuf-pips,005-tilegrid))
$(eval $(call fuzzer,049-int-imux-gfan,005-tilegrid))
$(eval $(call fuzzer,050-pip-seed,005-tilegrid))
$(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed))
$(eval $(call fuzzer,052-pip-clkin,050-pip-seed))
$(eval $(call fuzzer,053-pip-ctrlin,050-pip-seed))
$(eval $(call fuzzer,054-pip-fan-alt,050-pip-seed))
$(eval $(call fuzzer,055-pip-gnd,050-pip-seed))
$(eval $(call fuzzer,056-pip-rem,051-pip-imuxlout-bypalts 052-pip-clkin 053-pip-ctrlin 054-pip-fan-alt 055-pip-gnd))
$(eval $(call fuzzer,051-pip-imuxlout-bypalts,005-tilegrid))
$(eval $(call fuzzer,052-pip-clkin,005-tilegrid))
$(eval $(call fuzzer,053-pip-ctrlin,005-tilegrid))
$(eval $(call fuzzer,054-pip-fan-alt,005-tilegrid))
$(eval $(call fuzzer,055-pip-gnd,005-tilegrid))
$(eval $(call fuzzer,056-pip-rem,049-int-imux-gfan 050-pip-seed 051-pip-imuxlout-bypalts 052-pip-clkin 053-pip-ctrlin 054-pip-fan-alt 055-pip-gnd))
$(eval $(call fuzzer,057-pip-bi,056-pip-rem))
ifneq ($(QUICK),Y)
$(eval $(call fuzzer,058-pip-hclk,056-pip-rem))

View File

@ -215,26 +215,7 @@ def specn():
return int(re.match(".*specimen_([0-9]*)", specdir).group(1), 10)
def gen_fuzz_states(nvals):
'''
Generates an optimal encoding to solve single bits as quickly as possible
tilegrid's initial solve for 4 bits works like this:
Initial reference value of all 0s:
0000
Then one-hot for each:
0001
0010
0100
1000
Which requires 5 samples total to diff these
However, using correlation instead its possible to resolve n bits using ceil(log(n, 2)) + 1 samples
With 4 positions it takes only 3 samples:
0000
0101
1010
'''
def gen_fuzz_choices(nvals):
next_p2_states = 2**math.ceil(math.log(nvals, 2))
n = next_p2_states
@ -261,10 +242,35 @@ def gen_fuzz_states(nvals):
choices.extend(invert_choices)
return choices
def gen_fuzz_states(nvals):
'''
Generates an optimal encoding to solve single bits as quickly as possible
tilegrid's initial solve for 4 bits works like this:
Initial reference value of all 0s:
0000
Then one-hot for each:
0001
0010
0100
1000
Which requires 5 samples total to diff these
However, using correlation instead its possible to resolve n bits using ceil(log(n, 2)) + 1 samples
With 4 positions it takes only 3 samples:
0000
0101
1010
'''
choices = gen_fuzz_choices(nvals)
spec_idx = specn() - 1
if spec_idx < len(choices):
bits = choices[spec_idx]
else:
next_p2_states = 2**math.ceil(math.log(nvals, 2))
bits = random.randint(0, 2**next_p2_states)
for i in range(nvals):