mirror of https://github.com/openXC7/prjxray.git
Merge pull request #41 from kc8apf/code_format
Specify and enforce code style for C++ and Python
This commit is contained in:
commit
17985d1934
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: Chromium
|
||||
IndentWidth: 8
|
||||
UseTab: ForIndentation
|
||||
34
.travis.yml
34
.travis.yml
|
|
@ -2,24 +2,32 @@ language: cpp
|
|||
|
||||
matrix:
|
||||
include:
|
||||
# Job 1) Test C++ w/ GCC
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-6
|
||||
env:
|
||||
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
|
||||
|
||||
before_install:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
|
||||
script:
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- cmake -DPRJXRAY_BUILD_TESTING=ON ..
|
||||
- make -j 4
|
||||
- ctest
|
||||
script:
|
||||
- export CC=gcc-6
|
||||
- export CXX=g++-6
|
||||
- mkdir -p build
|
||||
- pushd build
|
||||
- cmake -DPRJXRAY_BUILD_TESTING=ON ..
|
||||
- make -j 4
|
||||
- ctest
|
||||
# Job 2) Lint checks on Python and C++
|
||||
- os: linux
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-format-3.9
|
||||
install:
|
||||
- pip install --user -r requirements.txt
|
||||
script:
|
||||
- make format
|
||||
- test $(git status --porcelain | wc -l) -eq 0 || { git diff; false; }
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -1,7 +1,13 @@
|
|||
JOBS ?= $(shell nproc)
|
||||
JOBS ?= 2
|
||||
CLANG_FORMAT ?= clang-format
|
||||
|
||||
go:
|
||||
git submodule update --init --recursive
|
||||
mkdir -p build
|
||||
cd build; cmake ..; make -j$(JOBS)
|
||||
|
||||
format:
|
||||
find . -name \*.cc -and -not -path './third_party/*' -exec $(CLANG_FORMAT) -style=file -i {} \;
|
||||
find . -name \*.h -and -not -path './third_party/*' -exec $(CLANG_FORMAT) -style=file -i {} \;
|
||||
find . -name \*.py -and -not -path './third_party/*' -exec autopep8 -i {} \;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -19,4 +20,3 @@ with open("design.txt", "r") as f:
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, json, re
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
|
||||
#################################################
|
||||
# Loading Raw Source Data
|
||||
|
|
@ -55,7 +57,8 @@ with open("carrydata.txt", "r") as f:
|
|||
for i, n in enumerate("CYINIT:ZRO:ONE:AX:CIN DI0:AX:O5 DI1:AX:O5 DI2:AX:O5 DI3:AX:O5".split()):
|
||||
n = n.split(":")
|
||||
for k in n[1:]:
|
||||
carry[line[0]]["CARRY_%s_MUX_%s" % (n[0], k)] = line[1+i].upper() == k
|
||||
carry[line[0]]["CARRY_%s_MUX_%s" %
|
||||
(n[0], k)] = line[1 + i].upper() == k
|
||||
|
||||
|
||||
#################################################
|
||||
|
|
@ -74,10 +77,11 @@ for tilename, tiledata in grid["tiles"].items():
|
|||
if not found_data:
|
||||
continue
|
||||
|
||||
segname = "%s_%02x" % (tiledata["cfgcol"]["BASE_FRAMEID"][2:], min(tiledata["cfgcol"]["WORDS"]))
|
||||
segname = "%s_%02x" % (
|
||||
tiledata["cfgcol"]["BASE_FRAMEID"][2:], min(tiledata["cfgcol"]["WORDS"]))
|
||||
|
||||
if not segname in segments:
|
||||
segments[segname] = { "bits": list(), "tags": dict() }
|
||||
segments[segname] = {"bits": list(), "tags": dict()}
|
||||
|
||||
for site in tiledata["sites"]:
|
||||
if site not in luts and site not in carry:
|
||||
|
|
@ -98,12 +102,14 @@ for tilename, tiledata in grid["tiles"].items():
|
|||
if re.match("^CLBL[LM]_[LR]", tile_type) and "LUT.INIT" in name:
|
||||
tile_type = "CLBLX_X"
|
||||
|
||||
segments[segname]["tags"]["%s.%s.%s" % (tile_type, sitekey, name)] = value
|
||||
segments[segname]["tags"]["%s.%s.%s" %
|
||||
(tile_type, sitekey, name)] = value
|
||||
|
||||
if site in carry:
|
||||
for name, value in carry[site].items():
|
||||
tile_type = tiledata["props"]["TYPE"]
|
||||
segments[segname]["tags"]["%s.%s.%s" % (tile_type, sitekey, name)] = value
|
||||
segments[segname]["tags"]["%s.%s.%s" %
|
||||
(tile_type, sitekey, name)] = value
|
||||
|
||||
base_frame = int(tiledata["cfgcol"]["BASE_FRAMEID"][2:], 16)
|
||||
for wordidx in tiledata["cfgcol"]["WORDS"]:
|
||||
|
|
@ -112,7 +118,8 @@ for tilename, tiledata in grid["tiles"].items():
|
|||
if wordidx not in bits[base_frame]:
|
||||
continue
|
||||
for bit_frame, bit_wordidx, bit_bitidx in bits[base_frame][wordidx]:
|
||||
segments[segname]["bits"].append("%02x_%02x_%02x" % (bit_frame - base_frame, bit_wordidx - min(tiledata["cfgcol"]["WORDS"]), bit_bitidx))
|
||||
segments[segname]["bits"].append("%02x_%02x_%02x" % (
|
||||
bit_frame - base_frame, bit_wordidx - min(tiledata["cfgcol"]["WORDS"]), bit_bitidx))
|
||||
|
||||
segments[segname]["bits"].sort()
|
||||
|
||||
|
|
@ -129,4 +136,3 @@ with open("segdata.txt", "w") as f:
|
|||
print("bit %s" % bitname, file=f)
|
||||
for tagname, tagval in sorted(segdata["tags"].items()):
|
||||
print("tag %s %d" % (tagname, tagval), file=f)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if line.endswith(".GND_WIRE") or line.endswith(".VCC_WIRE"):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -8,6 +9,7 @@ from segmaker import segmaker
|
|||
pipdata = dict()
|
||||
ignpip = set()
|
||||
|
||||
|
||||
def handle_design(prefix, second_pass):
|
||||
segmk = segmaker(prefix + ".bits")
|
||||
|
||||
|
|
@ -73,6 +75,7 @@ def handle_design(prefix, second_pass):
|
|||
segmk.compile()
|
||||
segmk.write(prefix[7:])
|
||||
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
prefix = arg[0:-4]
|
||||
handle_design(prefix, False)
|
||||
|
|
@ -80,4 +83,3 @@ for arg in sys.argv[1:]:
|
|||
for arg in sys.argv[1:]:
|
||||
prefix = arg[0:-4]
|
||||
handle_design(prefix, True)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -21,6 +23,8 @@ def maketodo(pipfile, dbfile):
|
|||
continue
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json, re
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
|
||||
|
||||
#######################################
|
||||
|
|
@ -18,7 +21,7 @@ for arg in sys.argv[1:]:
|
|||
with open(arg) as f:
|
||||
line = f.read().strip()
|
||||
site = arg[7:-6]
|
||||
frame = int(line[5:5+8], 16)
|
||||
frame = int(line[5:5 + 8], 16)
|
||||
site_baseaddr[site] = "0x%08x" % (frame & ~0x7f)
|
||||
|
||||
|
||||
|
|
@ -45,7 +48,7 @@ for record in tiles:
|
|||
|
||||
if len(record) > 4:
|
||||
for i in range(4, len(record), 2):
|
||||
site_type, site_name = record[i:i+2]
|
||||
site_type, site_name = record[i:i + 2]
|
||||
if site_name in site_baseaddr:
|
||||
framebaseaddr = site_baseaddr[site_name]
|
||||
database["tiles"][tile_name]["sites"][site_name] = site_type
|
||||
|
|
@ -64,15 +67,16 @@ for tile_name, tile_data in database["tiles"].items():
|
|||
|
||||
if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R"]:
|
||||
if tile_type in ["CLBLL_L", "CLBLM_L"]:
|
||||
int_tile_name = tiles_by_grid[(grid_x+1, grid_y)]
|
||||
int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
|
||||
else:
|
||||
int_tile_name = tiles_by_grid[(grid_x-1, grid_y)]
|
||||
int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
|
||||
|
||||
segment_name = "SEG_" + tile_name
|
||||
segtype = tile_type.lower()
|
||||
|
||||
database["segments"][segment_name] = dict()
|
||||
database["segments"][segment_name]["tiles"] = [tile_name, int_tile_name]
|
||||
database["segments"][segment_name]["tiles"] = [
|
||||
tile_name, int_tile_name]
|
||||
database["segments"][segment_name]["type"] = segtype
|
||||
database["segments"][segment_name]["frames"] = 36
|
||||
database["segments"][segment_name]["words"] = 2
|
||||
|
|
@ -97,11 +101,11 @@ for tile_name, tile_data in database["tiles"].items():
|
|||
if tile_type in ["BRAM_L", "DSP_L", "BRAM_R", "DSP_R"]:
|
||||
for k in range(5):
|
||||
if tile_type in ["BRAM_L", "DSP_L"]:
|
||||
interface_tile_name = tiles_by_grid[(grid_x+1, grid_y-k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x+2, grid_y-k)]
|
||||
interface_tile_name = tiles_by_grid[(grid_x + 1, grid_y - k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)]
|
||||
else:
|
||||
interface_tile_name = tiles_by_grid[(grid_x-1, grid_y-k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x-2, grid_y-k)]
|
||||
interface_tile_name = tiles_by_grid[(grid_x - 1, grid_y - k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)]
|
||||
|
||||
segment_name = "SEG_" + tile_name.replace("_", "%d_" % k, 1)
|
||||
segtype = tile_type.lower().replace("_", "%d_" % k, 1)
|
||||
|
|
@ -112,12 +116,14 @@ for tile_name, tile_data in database["tiles"].items():
|
|||
database["segments"][segment_name]["words"] = 2
|
||||
|
||||
if k == 0:
|
||||
database["segments"][segment_name]["tiles"] = [tile_name, interface_tile_name, int_tile_name]
|
||||
database["segments"][segment_name]["tiles"] = [
|
||||
tile_name, interface_tile_name, int_tile_name]
|
||||
database["tiles"][tile_name]["segment"] = segment_name
|
||||
database["tiles"][interface_tile_name]["segment"] = segment_name
|
||||
database["tiles"][int_tile_name]["segment"] = segment_name
|
||||
else:
|
||||
database["segments"][segment_name]["tiles"] = [interface_tile_name, int_tile_name]
|
||||
database["segments"][segment_name]["tiles"] = [
|
||||
interface_tile_name, int_tile_name]
|
||||
database["tiles"][interface_tile_name]["segment"] = segment_name
|
||||
database["tiles"][int_tile_name]["segment"] = segment_name
|
||||
|
||||
|
|
@ -128,7 +134,8 @@ for tile_name, tile_data in database["tiles"].items():
|
|||
for segment_name in database["segments"].keys():
|
||||
if "baseaddr" in database["segments"][segment_name]:
|
||||
framebase, wordbase = database["segments"][segment_name]["baseaddr"]
|
||||
inttile = [tile for tile in database["segments"][segment_name]["tiles"] if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
|
||||
inttile = [tile for tile in database["segments"][segment_name]["tiles"]
|
||||
if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
|
||||
grid_x = database["tiles"][inttile]["grid_x"]
|
||||
grid_y = database["tiles"][inttile]["grid_y"]
|
||||
|
||||
|
|
@ -156,7 +163,8 @@ for segment_name in database["segments"].keys():
|
|||
seg = database["tiles"][tile]["segment"]
|
||||
|
||||
if "baseaddr" in database["segments"][seg]:
|
||||
assert database["segments"][seg]["baseaddr"] == [framebase, wordbase]
|
||||
assert database["segments"][seg]["baseaddr"] == [
|
||||
framebase, wordbase]
|
||||
else:
|
||||
database["segments"][seg]["baseaddr"] = [framebase, wordbase]
|
||||
|
||||
|
|
@ -172,7 +180,8 @@ for segment_name in database["segments"].keys():
|
|||
|
||||
for segment_name in start_segments:
|
||||
framebase, wordbase = database["segments"][segment_name]["baseaddr"]
|
||||
inttile = [tile for tile in database["segments"][segment_name]["tiles"] if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
|
||||
inttile = [tile for tile in database["segments"][segment_name]["tiles"]
|
||||
if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
|
||||
grid_x = database["tiles"][inttile]["grid_x"]
|
||||
grid_y = database["tiles"][inttile]["grid_y"]
|
||||
|
||||
|
|
@ -192,4 +201,3 @@ for segment_name in start_segments:
|
|||
# Write
|
||||
|
||||
print(json.dumps(database, sort_keys=True, indent="\t"))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -22,4 +23,3 @@ with open("design_%s.txt" % sys.argv[1], "r") as f:
|
|||
|
||||
segmk.compile()
|
||||
segmk.write(sys.argv[1])
|
||||
|
||||
|
|
|
|||
|
|
@ -11,22 +11,25 @@ LDPE Primitive: Transparent Data Latch with Asynchronous Preset and Gate Enable
|
|||
|
||||
from prims import *
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
||||
segmk = segmaker("design.bits")
|
||||
|
||||
|
||||
def ones(l):
|
||||
#return l + [x + '_1' for x in l]
|
||||
#return sorted(l + [x + '_1' for x in l])
|
||||
# return l + [x + '_1' for x in l]
|
||||
# return sorted(l + [x + '_1' for x in l])
|
||||
ret = []
|
||||
for x in l:
|
||||
ret.append(x)
|
||||
ret.append(x + '_1')
|
||||
return ret
|
||||
|
||||
|
||||
def loadtop():
|
||||
'''
|
||||
i,prim,loc,bel
|
||||
|
|
@ -39,17 +42,20 @@ def loadtop():
|
|||
f.readline()
|
||||
ret = {}
|
||||
for l in f:
|
||||
i,prim,loc,bel,init = l.split(",")
|
||||
i, prim, loc, bel, init = l.split(",")
|
||||
i = int(i)
|
||||
init = int(init)
|
||||
ret[loc] = (i,prim,loc,bel,init)
|
||||
ret[loc] = (i, prim, loc, bel, init)
|
||||
return ret
|
||||
|
||||
|
||||
top = loadtop()
|
||||
|
||||
|
||||
def vs2i(s):
|
||||
return {"1'b0": 0, "1'b1": 1}[s]
|
||||
|
||||
|
||||
print("Loading tags from design.txt")
|
||||
with open("design.txt", "r") as f:
|
||||
for line in f:
|
||||
|
|
@ -99,7 +105,7 @@ with open("design.txt", "r") as f:
|
|||
# Synchronous vs asynchronous FF
|
||||
# Unlike most bits, shared between all CLB FFs
|
||||
segmk.addtag(site, "FFSYNC",
|
||||
cel_prim in ('FDSE', 'FDRE'))
|
||||
cel_prim in ('FDSE', 'FDRE'))
|
||||
|
||||
# Latch bit
|
||||
# Only applies to LUT6 (non-5) FF's
|
||||
|
|
@ -113,8 +119,7 @@ with open("design.txt", "r") as f:
|
|||
Z => inversion
|
||||
'''
|
||||
segmk.addtag(site, "%s.ZRST" % ff_name,
|
||||
cel_prim in ('FDRE', 'FDCE', 'LDCE'))
|
||||
cel_prim in ('FDRE', 'FDCE', 'LDCE'))
|
||||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,64 +1,67 @@
|
|||
def ones(l):
|
||||
#return l + [x + '_1' for x in l]
|
||||
#return sorted(l + [x + '_1' for x in l])
|
||||
# return l + [x + '_1' for x in l]
|
||||
# return sorted(l + [x + '_1' for x in l])
|
||||
ret = []
|
||||
for x in l:
|
||||
ret.append(x)
|
||||
ret.append(x + '_1')
|
||||
return ret
|
||||
|
||||
|
||||
# The complete primitive sets
|
||||
ffprims_fall = ones([
|
||||
'FD',
|
||||
'FDC',
|
||||
'FDCE',
|
||||
'FDE',
|
||||
'FDP',
|
||||
'FDPE',
|
||||
'FDR',
|
||||
'FDRE',
|
||||
'FDS',
|
||||
'FDSE',
|
||||
])
|
||||
'FD',
|
||||
'FDC',
|
||||
'FDCE',
|
||||
'FDE',
|
||||
'FDP',
|
||||
'FDPE',
|
||||
'FDR',
|
||||
'FDRE',
|
||||
'FDS',
|
||||
'FDSE',
|
||||
])
|
||||
ffprims_lall = ones([
|
||||
'LDC',
|
||||
'LDCE',
|
||||
'LDE',
|
||||
'LDPE',
|
||||
'LDP',
|
||||
])
|
||||
'LDC',
|
||||
'LDCE',
|
||||
'LDE',
|
||||
'LDPE',
|
||||
'LDP',
|
||||
])
|
||||
|
||||
# Base primitives
|
||||
ffprims_f = [
|
||||
'FDRE',
|
||||
'FDSE',
|
||||
'FDCE',
|
||||
'FDPE',
|
||||
]
|
||||
'FDRE',
|
||||
'FDSE',
|
||||
'FDCE',
|
||||
'FDPE',
|
||||
]
|
||||
ffprims_l = [
|
||||
'LDCE',
|
||||
'LDPE',
|
||||
]
|
||||
'LDCE',
|
||||
'LDPE',
|
||||
]
|
||||
ffprims = ffprims_f + ffprims_l
|
||||
|
||||
|
||||
def isff(prim):
|
||||
return prim.startswith("FD")
|
||||
|
||||
|
||||
def isl(prim):
|
||||
return prim.startswith("LD")
|
||||
|
||||
|
||||
ff_bels_5 = [
|
||||
'A5FF',
|
||||
'B5FF',
|
||||
'C5FF',
|
||||
'D5FF',
|
||||
]
|
||||
'A5FF',
|
||||
'B5FF',
|
||||
'C5FF',
|
||||
'D5FF',
|
||||
]
|
||||
ff_bels_ffl = [
|
||||
'AFF',
|
||||
'BFF',
|
||||
'CFF',
|
||||
'DFF',
|
||||
]
|
||||
'AFF',
|
||||
'BFF',
|
||||
'CFF',
|
||||
'DFF',
|
||||
]
|
||||
ff_bels = ff_bels_ffl + ff_bels_5
|
||||
#ff_bels = ff_bels_ffl
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@ import re
|
|||
|
||||
from prims import *
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 600
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -25,11 +28,13 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
f = open("top.txt", "w")
|
||||
f.write("i,prim,loc,bel,init\n")
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 4
|
||||
DOUT_N = CLBN * 1
|
||||
|
||||
|
|
@ -64,7 +69,8 @@ endmodule
|
|||
''' % (DIN_N, DOUT_N))
|
||||
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
ffprim = random.choice(ones(ffprims))
|
||||
# clb_FD clb_FD (.clk(clk), .din(din[ 0 +: 4]), .dout(dout[ 0]));
|
||||
|
|
@ -79,7 +85,8 @@ for i in range(CLBN):
|
|||
#bel = "AFF"
|
||||
print(' clb_%s' % ffprim)
|
||||
print(' #(.LOC("%s"), .BEL("%s"), .INIT(%d))' % (loc, bel, init))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
|
||||
f.write("%d,%s,%s,%s,%d\n" % (i, ffprim, loc, bel, init))
|
||||
print('''endmodule
|
||||
|
||||
|
|
@ -488,4 +495,3 @@ module clb_LDPE_1 (input clk, input [3:0] din, output dout);
|
|||
endmodule
|
||||
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -17,7 +18,7 @@ clb_N5FFMUX,SLICE_X14Y100,3,1
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
module,loc,n,def_a = l.split(',')
|
||||
module, loc, n, def_a = l.split(',')
|
||||
def_a = int(def_a)
|
||||
n = int(n)
|
||||
#which = chr(ord('A') + n)
|
||||
|
|
@ -30,4 +31,3 @@ for l in f:
|
|||
segmk.addtag(loc, "%c5FF.MUX.B" % which, 1 ^ def_a ^ inv)
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 40
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
|
|||
print('//SLICEN: %s' % str(SLICEN))
|
||||
print('//Requested CLBs: %s' % str(CLBN))
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 8
|
||||
DOUT_N = CLBN * 8
|
||||
|
||||
|
|
@ -61,7 +66,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,n,def_a\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
bel = ''
|
||||
|
||||
|
|
@ -72,7 +78,8 @@ for i in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s"), .N(%d), .DEF_A(%d))' % (loc, n, def_a))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
|
||||
f.write('%s,%s,%s,%s\n' % (module, loc, n, def_a))
|
||||
f.close()
|
||||
|
|
@ -203,4 +210,3 @@ module clb_N5FFMUX (input clk, input [7:0] din, output [7:0] dout);
|
|||
.D(ffds[0]));
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -17,7 +18,7 @@ clb_NCY0_O5,SLICE_X17Y100,A6LUT,2
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
module,loc,bel,n = l.split(',')
|
||||
module, loc, bel, n = l.split(',')
|
||||
n = int(n)
|
||||
# A, B, etc
|
||||
which = bel[0]
|
||||
|
|
@ -26,4 +27,3 @@ for l in f:
|
|||
segmk.addtag(loc, "CARRY4.%cCY0" % which, module == 'clb_NCY0_O5')
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 400
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
|
|||
print('//SLICEN: %s' % str(SLICEN))
|
||||
print('//Requested CLBs: %s' % str(CLBN))
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 8
|
||||
DOUT_N = CLBN * 8
|
||||
|
||||
|
|
@ -63,7 +68,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,bel,n\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
bel = ''
|
||||
|
||||
|
|
@ -77,7 +83,8 @@ for i in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s"), .BEL("%s"), .N(%d))' % (loc, bel, n))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
|
||||
f.write('%s,%s,%s,%s\n' % (module, loc, bel, n))
|
||||
f.close()
|
||||
|
|
@ -156,4 +163,3 @@ module clb_NCY0_O5 (input clk, input [7:0] din, output [7:0] dout);
|
|||
CARRY4 carry4(.O(o), .CO(), .DI(di), .S(s), .CYINIT(1'b0), .CI());
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -17,7 +18,7 @@ clb_FDRE,SLICE_X14Y100,1,1
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
name,site,ce,r = l.split(',')
|
||||
name, site, ce, r = l.split(',')
|
||||
ce = int(ce)
|
||||
r = int(r)
|
||||
|
||||
|
|
@ -30,4 +31,3 @@ for l in f:
|
|||
segmk.addtag(site, "SRUSEDMUX", r)
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 600
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -20,26 +23,28 @@ print('//SLICEY: %s' % str(SLICEY))
|
|||
print('//SLICEN: %s' % str(SLICEN))
|
||||
print('//Requested CLBs: %s' % str(CLBN))
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 4
|
||||
DOUT_N = CLBN * 1
|
||||
ffprims = (
|
||||
'FDRE',
|
||||
'FDRE',
|
||||
)
|
||||
ff_bels = (
|
||||
'AFF',
|
||||
'A5FF',
|
||||
'BFF',
|
||||
'B5FF',
|
||||
'CFF',
|
||||
'C5FF',
|
||||
'DFF',
|
||||
'D5FF',
|
||||
)
|
||||
'AFF',
|
||||
'A5FF',
|
||||
'BFF',
|
||||
'B5FF',
|
||||
'CFF',
|
||||
'C5FF',
|
||||
'DFF',
|
||||
'D5FF',
|
||||
)
|
||||
|
||||
print('''
|
||||
module top(input clk, stb, di, output do);
|
||||
|
|
@ -74,7 +79,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('name,loc,ce,r\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
ffprim = random.choice(ffprims)
|
||||
force_ce = random.randint(0, 1)
|
||||
|
|
@ -86,8 +92,10 @@ for i in range(CLBN):
|
|||
bel = "AFF"
|
||||
name = 'clb_%s' % ffprim
|
||||
print(' %s' % name)
|
||||
print(' #(.LOC("%s"), .BEL("%s"), .FORCE_CE1(%d), .nFORCE_R0(%d))' % (loc, bel, force_ce, force_r))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
|
||||
print(' #(.LOC("%s"), .BEL("%s"), .FORCE_CE1(%d), .nFORCE_R0(%d))' % (
|
||||
loc, bel, force_ce, force_r))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
|
||||
f.write('%s,%s,%s,%s\n' % (name, loc, force_ce, force_r))
|
||||
f.close()
|
||||
print('''endmodule
|
||||
|
|
@ -112,4 +120,3 @@ module clb_FDRE (input clk, input [3:0] din, output dout);
|
|||
);
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -18,7 +20,7 @@ clb_NFFMUX_O6,SLICE_X14Y100,3
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
module,loc,n = l.split(',')
|
||||
module, loc, n = l.split(',')
|
||||
n = int(n)
|
||||
which = chr(ord('A') + n)
|
||||
# clb_NFFMUX_AX => AX
|
||||
|
|
@ -63,17 +65,22 @@ for l in f:
|
|||
for loc, muxes in cache.items():
|
||||
for which in muxes:
|
||||
for src in "F7 F8 CY O5 AX XOR O6".split():
|
||||
if src == "F7" and which not in "AC": continue
|
||||
if src == "F8" and which not in "B": continue
|
||||
if src == "AX": src = which + "X"
|
||||
if src == "F7" and which not in "AC":
|
||||
continue
|
||||
if src == "F8" and which not in "B":
|
||||
continue
|
||||
if src == "AX":
|
||||
src = which + "X"
|
||||
tag = "%sFF.DMUX.%s" % (which, src)
|
||||
segmk.addtag(loc, tag, 0)
|
||||
|
||||
# we know that all bits for those MUXes are in frames 30 and 31, so filter all other bits
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") == "artix7"
|
||||
return frame_idx in [30, 31]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 400
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
|
|||
print('//SLICEN: %s' % str(SLICEN))
|
||||
print('//Requested CLBs: %s' % str(CLBN))
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 8
|
||||
DOUT_N = CLBN * 8
|
||||
|
||||
|
|
@ -61,9 +66,11 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,n\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
modules = ['clb_NFFMUX_' + x for x in ['AX', 'CY', 'F78', 'O5', 'O6', 'XOR']]
|
||||
modules = ['clb_NFFMUX_' +
|
||||
x for x in ['AX', 'CY', 'F78', 'O5', 'O6', 'XOR']]
|
||||
module = random.choice(modules)
|
||||
|
||||
if module == 'clb_NFFMUX_F78':
|
||||
|
|
@ -75,7 +82,8 @@ for i in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s"), .N(%d))' % (loc, n))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
|
||||
f.write('%s,%s,%s\n' % (module, loc, n))
|
||||
f.close()
|
||||
|
|
@ -330,4 +338,3 @@ module clb_NFFMUX_XOR (input clk, input [7:0] din, output [7:0] dout);
|
|||
.ff_d(caro));
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -18,7 +20,7 @@ clb_NFFMUX_O6,SLICE_X14Y100,3
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
module,loc,n = l.split(',')
|
||||
module, loc, n = l.split(',')
|
||||
n = int(n)
|
||||
which = chr(ord('A') + n)
|
||||
# clb_NFFMUX_AX => AX
|
||||
|
|
@ -63,12 +65,16 @@ for l in f:
|
|||
for loc, muxes in cache.items():
|
||||
for which in muxes:
|
||||
for src in "F7 F8 CY O5 XOR O6 5Q".split():
|
||||
if src == "F7" and which not in "AC": continue
|
||||
if src == "F8" and which not in "B": continue
|
||||
if src == "5Q": src = which + "5Q"
|
||||
if src == "F7" and which not in "AC":
|
||||
continue
|
||||
if src == "F8" and which not in "B":
|
||||
continue
|
||||
if src == "5Q":
|
||||
src = which + "5Q"
|
||||
tag = "%sMUX.%s" % (which, src)
|
||||
segmk.addtag(loc, tag, 0)
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") == "artix7"
|
||||
|
||||
|
|
@ -76,15 +82,16 @@ def bitfilter(frame_idx, bit_idx):
|
|||
# in this fuzzer we get some aliasing with those bits, so we have to manually exclude
|
||||
# them. (Maybe FIXME: read the bit locations from the database files)
|
||||
if (frame_idx, bit_idx) in [
|
||||
(30, 55), (31, 55), # D5MA
|
||||
(31, 44), (31, 45), # C5MA
|
||||
(30, 19), (31, 19), # B5MA
|
||||
(30, 9), (31, 8), # A5MA
|
||||
]: return False
|
||||
(30, 55), (31, 55), # D5MA
|
||||
(31, 44), (31, 45), # C5MA
|
||||
(30, 19), (31, 19), # B5MA
|
||||
(30, 9), (31, 8), # A5MA
|
||||
]:
|
||||
return False
|
||||
|
||||
# we know that all bits for those MUXes are in frames 30 and 31, so filter all other bits
|
||||
return frame_idx in [30, 31]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 400
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
|
|||
print('//SLICEN: %s' % str(SLICEN))
|
||||
print('//Requested CLBs: %s' % str(CLBN))
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicey in range(*SLICEY):
|
||||
for slicex in range(*SLICEX):
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
DIN_N = CLBN * 8
|
||||
DOUT_N = CLBN * 8
|
||||
|
||||
|
|
@ -61,7 +66,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,n\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
# Don't have an O6 example
|
||||
modules = ['clb_NOUTMUX_' + x for x in ['CY', 'F78', 'O5', 'XOR', 'B5Q']]
|
||||
|
|
@ -76,7 +82,8 @@ for i in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s"), .N(%d))' % (loc, n))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
|
||||
f.write('%s,%s,%s\n' % (module, loc, n))
|
||||
f.close()
|
||||
|
|
@ -305,4 +312,3 @@ module clb_NOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout);
|
|||
.ff_q(dout[0]));
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -11,7 +13,7 @@ print("Loading tags")
|
|||
f = open('params.csv', 'r')
|
||||
f.readline()
|
||||
for l in f:
|
||||
module,loc,loc2 = l.split(',')
|
||||
module, loc, loc2 = l.split(',')
|
||||
# clb_PRECYINIT_AX => AX
|
||||
src = module.replace('clb_PRECYINIT_', '')
|
||||
|
||||
|
|
@ -29,4 +31,3 @@ for l in f:
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 400
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -22,12 +25,15 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
# Rearranged to sweep Y so that carry logic is easy to allocate
|
||||
# XXX: careful...if odd number of Y in ROI will break carry
|
||||
|
||||
|
||||
def gen_slices():
|
||||
for slicex in range(*SLICEX):
|
||||
for slicey in range(*SLICEY):
|
||||
# caller may reject position if needs more room
|
||||
yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
|
||||
|
||||
|
||||
DIN_N = CLBN * 8
|
||||
DOUT_N = CLBN * 8
|
||||
|
||||
|
|
@ -64,7 +70,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,loc2\n')
|
||||
slices = gen_slices()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
for i in range(CLBN):
|
||||
# Don't have an O6 example
|
||||
modules = ['clb_PRECYINIT_' + x for x in ['0', '1', 'AX', 'CIN']]
|
||||
|
|
@ -88,7 +95,8 @@ for i in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(%s)' % (params))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
print(
|
||||
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
|
||||
|
||||
f.write('%s,%s\n' % (module, paramsc))
|
||||
f.close()
|
||||
|
|
@ -134,4 +142,3 @@ module clb_PRECYINIT_CIN (input clk, input [7:0] din, output [7:0] dout);
|
|||
CARRY4 carry4_ci(.O(), .CO(co), .DI(din[3:0]), .S(din[7:4]), .CYINIT(1'b0), .CI());
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re, os
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -12,12 +14,12 @@ segmk = segmaker("design.bits")
|
|||
multi_bels_by = [
|
||||
'SRL16E',
|
||||
'SRLC32E',
|
||||
]
|
||||
]
|
||||
# Not BELable
|
||||
multi_bels_bn = [
|
||||
'RAM32X1S',
|
||||
'RAM64X1S',
|
||||
]
|
||||
]
|
||||
|
||||
# Those requiring special resources
|
||||
# Just make one per module
|
||||
|
|
@ -25,7 +27,7 @@ greedy_modules = [
|
|||
'my_RAM128X1D',
|
||||
'my_RAM128X1S',
|
||||
'my_RAM256X1S',
|
||||
]
|
||||
]
|
||||
|
||||
print("Loading tags")
|
||||
'''
|
||||
|
|
@ -38,9 +40,10 @@ f = open('params.csv', 'r')
|
|||
f.readline()
|
||||
for l in f:
|
||||
l = l.strip()
|
||||
module,loc,p0,p1,p2,p3 = l.split(',')
|
||||
module, loc, p0, p1, p2, p3 = l.split(',')
|
||||
|
||||
segmk.addtag(loc, "WA7USED", module in ('my_RAM128X1D', 'my_RAM128X1S', 'my_RAM256X1S'))
|
||||
segmk.addtag(loc, "WA7USED", module in (
|
||||
'my_RAM128X1D', 'my_RAM128X1S', 'my_RAM256X1S'))
|
||||
segmk.addtag(loc, "WA8USED", module == 'my_RAM256X1S')
|
||||
|
||||
# (a, b, c, d)
|
||||
|
|
@ -53,7 +56,7 @@ for l in f:
|
|||
|
||||
if module == 'my_ram_N':
|
||||
# Each one of: SRL16E, SRLC32E, LUT6
|
||||
bels = [p0,p1,p2,p3]
|
||||
bels = [p0, p1, p2, p3]
|
||||
|
||||
# Clock Enable (CE) clock gate only enabled if we have clocked elements
|
||||
# A pure LUT6 does not, but everything else should
|
||||
|
|
@ -82,12 +85,12 @@ for l in f:
|
|||
(1, 0, 0, 1),
|
||||
(1, 1, 0, 1),
|
||||
(1, 1, 1, 1),
|
||||
]
|
||||
]
|
||||
# Uses CD first
|
||||
pack2 = [
|
||||
(0, 0, 1, 1),
|
||||
(1, 1, 1, 1),
|
||||
]
|
||||
]
|
||||
|
||||
# Always use all 4 sites
|
||||
if module in ('my_RAM32M', 'my_RAM64M', 'my_RAM128X1D', 'my_RAM256X1S'):
|
||||
|
|
@ -108,7 +111,7 @@ for l in f:
|
|||
assert(ram[3])
|
||||
|
||||
if module == 'my_RAM32X1D':
|
||||
# Occupies CD
|
||||
# Occupies CD
|
||||
size[2] = 1
|
||||
size[3] = 1
|
||||
elif module == 'my_RAM32M':
|
||||
|
|
@ -125,12 +128,13 @@ for l in f:
|
|||
# FIXME
|
||||
module == segmk.addtag(loc, "%sLUT.SMALL" % bel, size[beli])
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
# Hack to remove aliased PIP bits on CE
|
||||
# We should either mix up routing more or exclude previous DB entries
|
||||
assert os.getenv("XRAY_DATABASE") == "artix7"
|
||||
return (frame_idx, bit_idx) not in [(0, 27), (1, 25), (1, 26), (1, 29)]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -20,14 +20,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 50
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -39,6 +42,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
# Rearranged to sweep Y so that carry logic is easy to allocate
|
||||
# XXX: careful...if odd number of Y in ROI will break carry
|
||||
|
||||
|
||||
def gen_slicems():
|
||||
'''
|
||||
SLICEM at the following:
|
||||
|
|
@ -54,7 +59,7 @@ def gen_slicems():
|
|||
for slicex in (12, 14):
|
||||
for slicey in range(*SLICEY):
|
||||
# caller may reject position if needs more room
|
||||
#yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
|
||||
# yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
|
|
@ -94,7 +99,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,bela,belb,belc,beld\n')
|
||||
slices = gen_slicems()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
randluts = 0
|
||||
for clbi in range(CLBN):
|
||||
loc = next(slices)
|
||||
|
|
@ -113,7 +119,7 @@ for clbi in range(CLBN):
|
|||
'SRL16E',
|
||||
'SRLC32E',
|
||||
'LUT6',
|
||||
]
|
||||
]
|
||||
|
||||
bels = []
|
||||
for beli in range(4):
|
||||
|
|
@ -144,7 +150,7 @@ for clbi in range(CLBN):
|
|||
('my_RAM128X1S_N', 2, 1),
|
||||
('my_RAM128X1D', None, 1),
|
||||
('my_RAM256X1S', None, 1),
|
||||
]
|
||||
]
|
||||
|
||||
module, nmax, ff_param = random.choice(modules)
|
||||
|
||||
|
|
@ -165,7 +171,8 @@ for clbi in range(CLBN):
|
|||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s")%s)' % (loc, params))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (clbi, 8 * clbi, 8 * clbi))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (
|
||||
clbi, 8 * clbi, 8 * clbi))
|
||||
|
||||
f.write('%s,%s%s\n' % (module, loc, cparams))
|
||||
f.close()
|
||||
|
|
@ -510,4 +517,3 @@ module my_ram_N (input clk, input [7:0] din, output [7:0] dout);
|
|||
endmodule
|
||||
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
# Can we find instance where they are not aliased?
|
||||
WA7USED = 0
|
||||
|
||||
import sys, re, os
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -23,7 +25,7 @@ f = open('params.csv', 'r')
|
|||
f.readline()
|
||||
for l in f:
|
||||
l = l.strip()
|
||||
module,loc,c31,b31,a31 = l.split(',')
|
||||
module, loc, c31, b31, a31 = l.split(',')
|
||||
c31 = int(c31)
|
||||
b31 = int(b31)
|
||||
a31 = int(a31)
|
||||
|
|
@ -33,4 +35,3 @@ for l in f:
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ random.seed(0)
|
|||
import os
|
||||
import re
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
# Note XRAY_ROI_GRID_* is something else
|
||||
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
m = re.match(
|
||||
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
|
||||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
CLBN = 50
|
||||
SLICEX, SLICEY = slice_xy()
|
||||
# 800
|
||||
|
|
@ -22,6 +25,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
# Rearranged to sweep Y so that carry logic is easy to allocate
|
||||
# XXX: careful...if odd number of Y in ROI will break carry
|
||||
|
||||
|
||||
def gen_slicems():
|
||||
'''
|
||||
SLICEM at the following:
|
||||
|
|
@ -37,7 +42,7 @@ def gen_slicems():
|
|||
for slicex in (12, 14):
|
||||
for slicey in range(*SLICEY):
|
||||
# caller may reject position if needs more room
|
||||
#yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
|
||||
# yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
|
||||
yield "SLICE_X%dY%d" % (slicex, slicey)
|
||||
|
||||
|
||||
|
|
@ -77,7 +82,8 @@ endmodule
|
|||
f = open('params.csv', 'w')
|
||||
f.write('module,loc,c31,b31,a31\n')
|
||||
slices = gen_slicems()
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
|
||||
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
|
||||
DIN_N - 1, DOUT_N - 1))
|
||||
multis = 0
|
||||
for clbi in range(CLBN):
|
||||
loc = next(slices)
|
||||
|
|
@ -87,8 +93,10 @@ for clbi in range(CLBN):
|
|||
a31 = random.randint(0, 1)
|
||||
|
||||
print(' %s' % module)
|
||||
print(' #(.LOC("%s"), .C31(%d), .B31(%d), .A31(%d))' % (loc, c31, b31, a31))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (clbi, 8 * clbi, 8 * clbi))
|
||||
print(' #(.LOC("%s"), .C31(%d), .B31(%d), .A31(%d))' %
|
||||
(loc, c31, b31, a31))
|
||||
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (
|
||||
clbi, 8 * clbi, 8 * clbi))
|
||||
|
||||
f.write('%s,%s,%d,%d,%d\n' % (module, loc, c31, b31, a31))
|
||||
f.close()
|
||||
|
|
@ -159,4 +167,3 @@ module my_NDI1MUX_NI_NMC31 (input clk, input [7:0] din, output [7:0] dout);
|
|||
.D(lutd[0]));
|
||||
endmodule
|
||||
''')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -63,4 +64,3 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re, os
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -61,12 +63,13 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
elif src_dst[1] not in dsts:
|
||||
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
|
||||
if frame_idx in [30, 31]:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if re.match(r"^INT_[LR].IMUX(_L)?[0-9]+\.LOGIC_OUTS(_L)?[0-9]+$", line):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -58,6 +60,7 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
elif src_dst[1] not in dsts:
|
||||
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
|
||||
if frame_idx == 0 and bit_idx == 48:
|
||||
|
|
@ -66,6 +69,6 @@ def bitfilter(frame_idx, bit_idx):
|
|||
return False
|
||||
return frame_idx in [0, 1]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if re.match(r"^INT_[LR].CLK", line):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -58,12 +60,13 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
elif src_dst[1] not in dsts:
|
||||
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
|
||||
if (frame_idx, bit_idx) in [(0, 48), (1, 31), (0, 32), (1, 35)]:
|
||||
return False
|
||||
return frame_idx in [0, 1]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if re.match(r"^INT_[LR].CTRL", line):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if re.match(r"^INT_[LR].GFAN", line) and not line.endswith(".GND_WIRE"):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -70,4 +72,3 @@ for tile, pips_srcs_dsts in tiledata.items():
|
|||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
if not line.endswith(".VCC_WIRE"):
|
||||
print(line)
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -40,10 +42,11 @@ for tile, pips_nodes in tiledata.items():
|
|||
elif dst not in nodes and src not in nodes:
|
||||
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
|
||||
|
||||
|
||||
def bitfilter(frame_idx, bit_idx):
|
||||
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
|
||||
return frame_idx in [0, 1]
|
||||
|
||||
|
||||
segmk.compile(bitfilter=bitfilter)
|
||||
segmk.write()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, re
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def maketodo(pipfile, dbfile):
|
||||
todos = set()
|
||||
|
|
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
|
|||
for line in todos:
|
||||
print(line)
|
||||
|
||||
maketodo("bipips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("bipips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
||||
maketodo("bipips_int_l.txt", "%s/%s/segbits_int_l.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
maketodo("bipips_int_r.txt", "%s/%s/segbits_int_r.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
sys.path.append("../../../utils/")
|
||||
from segmaker import segmaker
|
||||
|
|
@ -50,4 +52,3 @@ for arg in sys.argv[1:]:
|
|||
|
||||
segmk.compile()
|
||||
segmk.write(arg)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json, re
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
|
||||
tilenodes = dict()
|
||||
grid2tile = dict()
|
||||
|
|
@ -24,38 +27,56 @@ with open("nodewires.txt") as f:
|
|||
tilenodes[wire_tile] = dict()
|
||||
tilenodes[wire_tile][node] = wire_name
|
||||
|
||||
|
||||
def filter_pair(type1, type2, wire1, wire2, delta_x, delta_y):
|
||||
if type1 in ["HCLK_L", "HCLK_R"]:
|
||||
is_vertical_wire = False
|
||||
if wire1.startswith("HCLK_S"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_N"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_W"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_E"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_LV"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_BYP"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_FAN"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_LEAF_CLK_"): is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_S"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_N"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_W"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_E"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_LV"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_BYP"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_FAN"):
|
||||
is_vertical_wire = True
|
||||
if wire1.startswith("HCLK_LEAF_CLK_"):
|
||||
is_vertical_wire = True
|
||||
|
||||
is_horizontal_wire = False
|
||||
if wire1.startswith("HCLK_CK_"): is_horizontal_wire = True
|
||||
if wire1.startswith("HCLK_INT_"): is_horizontal_wire = True
|
||||
if wire1.startswith("HCLK_CK_"):
|
||||
is_horizontal_wire = True
|
||||
if wire1.startswith("HCLK_INT_"):
|
||||
is_horizontal_wire = True
|
||||
|
||||
assert is_vertical_wire != is_horizontal_wire
|
||||
if is_vertical_wire and delta_y == 0: return True
|
||||
if is_horizontal_wire and delta_x == 0: return True
|
||||
if is_vertical_wire and delta_y == 0:
|
||||
return True
|
||||
if is_horizontal_wire and delta_x == 0:
|
||||
return True
|
||||
|
||||
if type1 in ["INT_L", "INT_R"]:
|
||||
# the wires with underscore after BEG/END all connect vertically
|
||||
if (("BEG_" in wire1) or ("END_" in wire1)) and delta_y == 0: return True
|
||||
if (("BEG_" in wire1) or ("END_" in wire1)) and delta_y == 0:
|
||||
return True
|
||||
|
||||
if type1 in ["BRKH_INT", "BRKH_B_TERM_INT", "T_TERM_INT"]:
|
||||
if delta_y == 0: return True
|
||||
if delta_y == 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def handle_pair(tile1, tile2):
|
||||
if tile1 not in tilenodes: return
|
||||
if tile2 not in tilenodes: return
|
||||
if tile1 not in tilenodes:
|
||||
return
|
||||
if tile2 not in tilenodes:
|
||||
return
|
||||
|
||||
tile1data = grid["tiles"][tile1]
|
||||
tile2data = grid["tiles"][tile2]
|
||||
|
|
@ -66,7 +87,8 @@ def handle_pair(tile1, tile2):
|
|||
if grid1_xy > grid2_xy:
|
||||
return handle_pair(tile2, tile1)
|
||||
|
||||
key = (tile1data["type"], tile2data["type"], grid2_xy[0] - grid1_xy[0], grid2_xy[1] - grid1_xy[1])
|
||||
key = (tile1data["type"], tile2data["type"],
|
||||
grid2_xy[0] - grid1_xy[0], grid2_xy[1] - grid1_xy[1])
|
||||
|
||||
wire_pairs = set()
|
||||
|
||||
|
|
@ -84,9 +106,10 @@ def handle_pair(tile1, tile2):
|
|||
else:
|
||||
database[key] &= wire_pairs
|
||||
|
||||
|
||||
for tile, tiledata in grid["tiles"].items():
|
||||
grid_right_xy = (tiledata["grid_x"]+1, tiledata["grid_y"])
|
||||
grid_below_xy = (tiledata["grid_x"], tiledata["grid_y"]+1)
|
||||
grid_right_xy = (tiledata["grid_x"] + 1, tiledata["grid_y"])
|
||||
grid_below_xy = (tiledata["grid_x"], tiledata["grid_y"] + 1)
|
||||
|
||||
if grid_right_xy in grid2tile:
|
||||
handle_pair(tile, grid2tile[grid_right_xy])
|
||||
|
|
@ -108,4 +131,3 @@ for key in sorted(database.keys()):
|
|||
print("Writing tileconn.json.")
|
||||
with open("tileconn.json", "w") as f:
|
||||
print(json.dumps(json_db, sort_keys=True, indent="\t"), file=f)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,20 @@ db_site_prop = dict()
|
|||
db_site_tile = dict()
|
||||
db_site_bit = dict()
|
||||
|
||||
|
||||
def add_tile(tile):
|
||||
if tile not in db_tiles:
|
||||
db_tiles.add(tile)
|
||||
db_tile_prop[tile] = dict()
|
||||
db_tile_sites[tile] = list()
|
||||
|
||||
|
||||
def add_site(site):
|
||||
if site not in db_sites:
|
||||
db_sites.add(site)
|
||||
db_site_prop[site] = dict()
|
||||
|
||||
|
||||
with open("%s.txt" % sys.argv[1]) as f:
|
||||
for line in f:
|
||||
line = line.split()
|
||||
|
|
@ -89,34 +92,36 @@ for site, bit in db_site_bit.items():
|
|||
|
||||
for i in range(50):
|
||||
m = re.match("(.*)Y([0-9]+)", site)
|
||||
this_site = "%sY%d" % (m.group(1), int(m.group(2))+i)
|
||||
this_site = "%sY%d" % (m.group(1), int(m.group(2)) + i)
|
||||
|
||||
tile = db_site_tile[this_site]
|
||||
|
||||
word = bit_word + 2*i
|
||||
if word >= 50: word += 1
|
||||
word = bit_word + 2 * i
|
||||
if word >= 50:
|
||||
word += 1
|
||||
|
||||
entry = dict()
|
||||
entry["BASE_FRAMEID"] = "0x%08x" % ((bit_type << 23) | (bit_half << 22) | (bit_row << 17) | (bit_col << 7))
|
||||
entry["BASE_FRAMEID"] = "0x%08x" % ((bit_type << 23) | (
|
||||
bit_half << 22) | (bit_row << 17) | (bit_col << 7))
|
||||
entry["FRAME_TYPE"] = bit_type
|
||||
entry["FRAME_HALF"] = bit_half
|
||||
entry["FRAME_ROW"] = bit_row
|
||||
entry["FRAME_COLUMN"] = bit_col
|
||||
entry["WORDS"] = [word, word+1]
|
||||
entry["WORDS"] = [word, word + 1]
|
||||
|
||||
database["tiles"][tile]["cfgcol"] = entry
|
||||
|
||||
if database["tiles"][tile]["props"]["TILE_TYPE"] in ("CLBLL_L", "CLBLM_L"):
|
||||
col = int(db_tile_prop[tile]["COLUMN"])
|
||||
row = int(db_tile_prop[tile]["ROW"])
|
||||
right_tile = loc_to_tile[(col+1, row)]
|
||||
right_tile = loc_to_tile[(col + 1, row)]
|
||||
|
||||
database["tiles"][right_tile]["cfgcol"] = entry
|
||||
|
||||
if database["tiles"][tile]["props"]["TILE_TYPE"] in ("CLBLL_R", "CLBLM_R"):
|
||||
col = int(db_tile_prop[tile]["COLUMN"])
|
||||
row = int(db_tile_prop[tile]["ROW"])
|
||||
left_tile = loc_to_tile[(col-1, row)]
|
||||
left_tile = loc_to_tile[(col - 1, row)]
|
||||
|
||||
database["tiles"][left_tile]["cfgcol"] = entry
|
||||
|
||||
|
|
@ -133,4 +138,3 @@ print("Number of tiles with assigned column: %d" % tile_cfgcol_count)
|
|||
|
||||
with open("%s.json" % sys.argv[1], "w") as f:
|
||||
print(json.dumps(database, sort_keys=True, indent="\t"), file=f)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json, re
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
from io import StringIO
|
||||
|
||||
import argparse
|
||||
|
|
@ -37,13 +40,17 @@ else:
|
|||
def get_setting(name):
|
||||
return os.getenv(name)
|
||||
|
||||
db_dir = os.path.join(get_setting("XRAY_DATABASE_DIR"), get_setting("XRAY_DATABASE"))
|
||||
db_dir = os.path.join(get_setting("XRAY_DATABASE_DIR"),
|
||||
get_setting("XRAY_DATABASE"))
|
||||
|
||||
|
||||
def db_open(fn):
|
||||
filename = os.path.join(db_dir, fn)
|
||||
if not os.path.exists(filename):
|
||||
return StringIO("")
|
||||
return open(os.path.join(db_dir, fn))
|
||||
|
||||
|
||||
def out_open(fn):
|
||||
out_dir = os.path.join(args.output, get_setting("XRAY_DATABASE"))
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
|
@ -51,6 +58,7 @@ def out_open(fn):
|
|||
print("Writing %s" % fp)
|
||||
return open(fp, "w")
|
||||
|
||||
|
||||
clb_bitgroups_db = [
|
||||
# copy&paste from zero_db in dbfixup.py
|
||||
"00_21 00_22 00_26 01_28|00_25 01_20 01_21 01_24",
|
||||
|
|
@ -84,9 +92,9 @@ hclk_bitgroups_db = [
|
|||
# groupings for SNWE bits in frames 2..7
|
||||
for i in range(0, 64, 4):
|
||||
clb_bitgroups_db.append("02_%02d 03_%02d 05_%02d 06_%02d 07_%02d|05_%02d 03_%02d 04_%02d 04_%02d" %
|
||||
(i+1, i, i, i, i+1, i+3, i+1, i+1, i+2))
|
||||
(i + 1, i, i, i, i + 1, i + 3, i + 1, i + 1, i + 2))
|
||||
clb_bitgroups_db.append("02_%02d 04_%02d 05_%02d 05_%02d 06_%02d|02_%02d 03_%02d 04_%02d 07_%02d" %
|
||||
(i+2, i, i+1, i+2, i+2, i+3, i+2, i+3, i+3))
|
||||
(i + 2, i, i + 1, i + 2, i + 2, i + 3, i + 2, i + 3, i + 3))
|
||||
|
||||
clb_left_bits = set()
|
||||
clb_right_bits = set()
|
||||
|
|
@ -108,6 +116,7 @@ for entry in hclk_bitgroups_db:
|
|||
for bit in b.split():
|
||||
hclk_right_bits.add(bit)
|
||||
|
||||
|
||||
class UnionFind:
|
||||
def __init__(self):
|
||||
self.parents = dict()
|
||||
|
|
@ -152,8 +161,8 @@ with db_open("tilegrid.json") as f:
|
|||
"tiles": {
|
||||
"NULL": {
|
||||
"grid_x": 0,
|
||||
"grid_y":0,
|
||||
"type":"NULL",
|
||||
"grid_y": 0,
|
||||
"type": "NULL",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,10 +237,13 @@ grid_range = None
|
|||
grid_map = dict()
|
||||
|
||||
with out_open("index.html") as f:
|
||||
print("<html><title>X-Ray %s Database</title><body>" % get_setting("XRAY_DATABASE").upper(), file=f)
|
||||
print("<h3>X-Ray %s Database</h3>" % get_setting("XRAY_DATABASE").upper(), file=f)
|
||||
print("<html><title>X-Ray %s Database</title><body>" %
|
||||
get_setting("XRAY_DATABASE").upper(), file=f)
|
||||
print("<h3>X-Ray %s Database</h3>" %
|
||||
get_setting("XRAY_DATABASE").upper(), file=f)
|
||||
|
||||
print("<p><b>Part: %s<br/>ROI: %s<br/>ROI Frames: %s</b></p>" % (get_setting("XRAY_PART"), get_setting("XRAY_ROI"), get_setting("XRAY_ROI_FRAMES")), file=f)
|
||||
print("<p><b>Part: %s<br/>ROI: %s<br/>ROI Frames: %s</b></p>" %
|
||||
(get_setting("XRAY_PART"), get_setting("XRAY_ROI"), get_setting("XRAY_ROI_FRAMES")), file=f)
|
||||
|
||||
for tilename, tiledata in grid["tiles"].items():
|
||||
grid_x = tiledata["grid_x"]
|
||||
|
|
@ -248,25 +260,33 @@ with out_open("index.html") as f:
|
|||
|
||||
print("<table border>", file=f)
|
||||
|
||||
for grid_y in range(grid_range[1], grid_range[3]+1):
|
||||
for grid_y in range(grid_range[1], grid_range[3] + 1):
|
||||
print("<tr>", file=f)
|
||||
|
||||
for grid_x in range(grid_range[0], grid_range[2]+1):
|
||||
for grid_x in range(grid_range[0], grid_range[2] + 1):
|
||||
tilename = grid_map[(grid_x, grid_y)]
|
||||
tiledata = grid["tiles"][tilename]
|
||||
segdata = None
|
||||
|
||||
bgcolor = "#aaaaaa"
|
||||
if tiledata["type"] in ["INT_L", "INT_R"]: bgcolor="#aaaaff"
|
||||
if tiledata["type"] in ["CLBLL_L", "CLBLL_R"]: bgcolor="#ffffaa"
|
||||
if tiledata["type"] in ["CLBLM_L", "CLBLM_R"]: bgcolor="#ffaaaa"
|
||||
if tiledata["type"] in ["HCLK_L", "HCLK_R"]: bgcolor="#aaffaa"
|
||||
if tiledata["type"] in ["INT_L", "INT_R"]:
|
||||
bgcolor = "#aaaaff"
|
||||
if tiledata["type"] in ["CLBLL_L", "CLBLL_R"]:
|
||||
bgcolor = "#ffffaa"
|
||||
if tiledata["type"] in ["CLBLM_L", "CLBLM_R"]:
|
||||
bgcolor = "#ffaaaa"
|
||||
if tiledata["type"] in ["HCLK_L", "HCLK_R"]:
|
||||
bgcolor = "#aaffaa"
|
||||
|
||||
if tiledata["type"] in ["BRAM_INT_INTERFACE_L", "BRAM_L"]: bgcolor="#aaffff"
|
||||
if tiledata["type"] in ["BRAM_INT_INTERFACE_R", "BRAM_R"]: bgcolor="#aaffff"
|
||||
if tiledata["type"] in ["BRAM_INT_INTERFACE_L", "BRAM_L"]:
|
||||
bgcolor = "#aaffff"
|
||||
if tiledata["type"] in ["BRAM_INT_INTERFACE_R", "BRAM_R"]:
|
||||
bgcolor = "#aaffff"
|
||||
|
||||
if tiledata["type"] in ["INT_INTERFACE_L", "DSP_L"]: bgcolor="#ffaaff"
|
||||
if tiledata["type"] in ["INT_INTERFACE_R", "DSP_R"]: bgcolor="#ffaaff"
|
||||
if tiledata["type"] in ["INT_INTERFACE_L", "DSP_L"]:
|
||||
bgcolor = "#ffaaff"
|
||||
if tiledata["type"] in ["INT_INTERFACE_R", "DSP_R"]:
|
||||
bgcolor = "#ffaaff"
|
||||
|
||||
title = [tilename]
|
||||
|
||||
|
|
@ -282,21 +302,25 @@ with out_open("index.html") as f:
|
|||
|
||||
if "segment" in tiledata:
|
||||
if "baseaddr" in segdata:
|
||||
title.append("Baseaddr: %s %d" % tuple(segdata["baseaddr"]))
|
||||
title.append("Baseaddr: %s %d" %
|
||||
tuple(segdata["baseaddr"]))
|
||||
else:
|
||||
print("Warning: no baseaddr in segment %s (via tile %s)." % (tiledata["segment"], tilename))
|
||||
print("Warning: no baseaddr in segment %s (via tile %s)." %
|
||||
(tiledata["segment"], tilename))
|
||||
|
||||
tilename = tilename.replace("INT_INTERFACE_", "INTF_")
|
||||
tilename = tilename.replace("_X", "<br/>X")
|
||||
tilename = tilename.replace("B_TERM", "B<br/>TERM")
|
||||
|
||||
print("<td bgcolor=\"%s\" align=\"center\" title=\"%s\"><span style=\"font-size:10px\">" % (bgcolor, "\n".join(title)), file=f)
|
||||
print("<td bgcolor=\"%s\" align=\"center\" title=\"%s\"><span style=\"font-size:10px\">" %
|
||||
(bgcolor, "\n".join(title)), file=f)
|
||||
if "segment" in tiledata:
|
||||
segtype = segdata["type"].lower()
|
||||
print("<a style=\"text-decoration: none; color: black\" href=\"seg_%s.html\">%s</a></span></td>" %
|
||||
(segtype, tilename.replace("_X", "<br/>X")), file=f)
|
||||
(segtype, tilename.replace("_X", "<br/>X")), file=f)
|
||||
else:
|
||||
print("%s</span></td>" % tilename.replace("_X", "<br/>X").replace("B_TERM", "B<br/>TERM"), file=f)
|
||||
print("%s</span></td>" % tilename.replace("_X",
|
||||
"<br/>X").replace("B_TERM", "B<br/>TERM"), file=f)
|
||||
|
||||
print("</tr>", file=f)
|
||||
|
||||
|
|
@ -309,12 +333,14 @@ with out_open("index.html") as f:
|
|||
|
||||
for segtype in sorted(segbits.keys()):
|
||||
with out_open("seg_%s.html" % segtype) as f:
|
||||
print("<html><title>X-Ray %s Database: %s</title><body>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
|
||||
print("<html><title>X-Ray %s Database: %s</title><body>" %
|
||||
(get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
|
||||
if segtype in ["hclk_l", "hclk_r"]:
|
||||
print("<h3>X-Ray %s Database: %s Segment</h3>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
|
||||
print("<h3>X-Ray %s Database: %s Segment</h3>" %
|
||||
(get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
|
||||
else:
|
||||
print("<h3>X-Ray %s Database: %s Segment (%s Tile + %s Tile)</h3>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper(),
|
||||
segtype.upper(), re.sub("clbl[lm]|bram[0-4]|dsp[0-4]", "int", segtype).upper()), file=f)
|
||||
segtype.upper(), re.sub("clbl[lm]|bram[0-4]|dsp[0-4]", "int", segtype).upper()), file=f)
|
||||
|
||||
print("""
|
||||
<script><!--
|
||||
|
|
@ -364,12 +390,14 @@ function oml() {
|
|||
print("<tr>", file=f)
|
||||
print("<th width=\"30\"></th>", file=f)
|
||||
for frameidx in range(segframes[segtype]):
|
||||
print("<th width=\"30\"><span style=\"font-size:10px\">%d</span></th>" % frameidx, file=f)
|
||||
print("<th width=\"30\"><span style=\"font-size:10px\">%d</span></th>" %
|
||||
frameidx, file=f)
|
||||
print("</tr>", file=f)
|
||||
|
||||
for bitidx in range(31 if (segtype in ["hclk_l", "hclk_r"]) else 63, -1, -1):
|
||||
print("<tr>", file=f)
|
||||
print("<th align=\"right\"><span style=\"font-size:10px\">%d</span></th>" % bitidx, file=f)
|
||||
print(
|
||||
"<th align=\"right\"><span style=\"font-size:10px\">%d</span></th>" % bitidx, file=f)
|
||||
for frameidx in range(segframes[segtype]):
|
||||
bit_pos = "%02d_%02d" % (frameidx, bitidx)
|
||||
bit_name = segbits_r[segtype][bit_pos] if bit_pos in segbits_r[segtype] else None
|
||||
|
|
@ -420,7 +448,8 @@ function oml() {
|
|||
else:
|
||||
bgcolor = "#ff0000"
|
||||
|
||||
m = re.search(r"\.([ABCD]5?)FF\.([A-Z]+(\.A|\.B)?)$", bit_name)
|
||||
m = re.search(
|
||||
r"\.([ABCD]5?)FF\.([A-Z]+(\.A|\.B)?)$", bit_name)
|
||||
if m:
|
||||
bgcolor = "#aaffaa"
|
||||
if m.group(2) == "ZINI":
|
||||
|
|
@ -478,64 +507,64 @@ function oml() {
|
|||
label = "BUF"
|
||||
|
||||
elif bit_pos in routebits[segtype]:
|
||||
bgcolor = "#0000ff"
|
||||
label = "R"
|
||||
for bn in sorted(routebits[segtype][bit_pos]):
|
||||
if re.match("^INT_[LR].[SNWE][SNWERL]", bn):
|
||||
if bn[8] == "1":
|
||||
bgcolor = "#4466bb"
|
||||
elif bn[8] == "2":
|
||||
bgcolor = "#aa88ff"
|
||||
elif bn[6:9] in "SS6 SE6 NN6 NW6".split():
|
||||
bgcolor = "#7755ff"
|
||||
else:
|
||||
bgcolor = "#88aaff"
|
||||
label = bn[6:9]
|
||||
elif re.match("^INT_[LR].IMUX", bn):
|
||||
m = re.match("^INT_[LR].IMUX(_L)?(\d+)", bn)
|
||||
bgcolor = "#88aaff"
|
||||
label = "IM" + m.group(2)
|
||||
elif re.match("^INT_[LR].BYP_ALT", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "BA" + bn[13]
|
||||
elif re.match("^INT_[LR].FAN_ALT", bn):
|
||||
bgcolor = "#0000ff"
|
||||
label = "R"
|
||||
for bn in sorted(routebits[segtype][bit_pos]):
|
||||
if re.match("^INT_[LR].[SNWE][SNWERL]", bn):
|
||||
if bn[8] == "1":
|
||||
bgcolor = "#4466bb"
|
||||
label = "FA" + bn[13]
|
||||
elif re.match("^INT_[LR].CLK", bn):
|
||||
bgcolor = "#4466bb"
|
||||
label = "CLK"
|
||||
elif re.match("^INT_[LR].CTRL", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "CTRL"
|
||||
elif re.match("^INT_[LR].GFAN", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "GFAN"
|
||||
elif re.match("^INT_[LR].LVB", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "LVB"
|
||||
elif re.match("^INT_[LR].LV", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "LV"
|
||||
elif re.match("^INT_[LR].LH", bn):
|
||||
bgcolor = "#4466bb"
|
||||
label = "LH"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]FF.DMUX", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "DMX"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]MUX", bn):
|
||||
elif bn[8] == "2":
|
||||
bgcolor = "#aa88ff"
|
||||
label = "OMX"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].PRECYINIT", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "CYI"
|
||||
elif re.match("^HCLK_[LR]", bn) and "_B_BOT" in bn:
|
||||
bgcolor = "#4466bb"
|
||||
label = "BOT"
|
||||
elif re.match("^HCLK_[LR]", bn) and "_B_TOP" in bn:
|
||||
elif bn[6:9] in "SS6 SE6 NN6 NW6".split():
|
||||
bgcolor = "#7755ff"
|
||||
label = "TOP"
|
||||
piptypes[bit_pos] = label
|
||||
title.append(bn)
|
||||
else:
|
||||
bgcolor = "#88aaff"
|
||||
label = bn[6:9]
|
||||
elif re.match("^INT_[LR].IMUX", bn):
|
||||
m = re.match("^INT_[LR].IMUX(_L)?(\d+)", bn)
|
||||
bgcolor = "#88aaff"
|
||||
label = "IM" + m.group(2)
|
||||
elif re.match("^INT_[LR].BYP_ALT", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "BA" + bn[13]
|
||||
elif re.match("^INT_[LR].FAN_ALT", bn):
|
||||
bgcolor = "#4466bb"
|
||||
label = "FA" + bn[13]
|
||||
elif re.match("^INT_[LR].CLK", bn):
|
||||
bgcolor = "#4466bb"
|
||||
label = "CLK"
|
||||
elif re.match("^INT_[LR].CTRL", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "CTRL"
|
||||
elif re.match("^INT_[LR].GFAN", bn):
|
||||
bgcolor = "#7755ff"
|
||||
label = "GFAN"
|
||||
elif re.match("^INT_[LR].LVB", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "LVB"
|
||||
elif re.match("^INT_[LR].LV", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "LV"
|
||||
elif re.match("^INT_[LR].LH", bn):
|
||||
bgcolor = "#4466bb"
|
||||
label = "LH"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]FF.DMUX", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "DMX"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].[ABCD]MUX", bn):
|
||||
bgcolor = "#aa88ff"
|
||||
label = "OMX"
|
||||
elif re.match("^CLBL[LM]_[LR].SLICE[LM]_X[01].PRECYINIT", bn):
|
||||
bgcolor = "#88aaff"
|
||||
label = "CYI"
|
||||
elif re.match("^HCLK_[LR]", bn) and "_B_BOT" in bn:
|
||||
bgcolor = "#4466bb"
|
||||
label = "BOT"
|
||||
elif re.match("^HCLK_[LR]", bn) and "_B_TOP" in bn:
|
||||
bgcolor = "#7755ff"
|
||||
label = "TOP"
|
||||
piptypes[bit_pos] = label
|
||||
title.append(bn)
|
||||
|
||||
if label is None:
|
||||
label = " "
|
||||
|
|
@ -552,7 +581,7 @@ function oml() {
|
|||
known_bits += 1
|
||||
|
||||
print("<td id=\"bit%s\" onmouseenter=\"ome('%s');\" onmouseleave=\"oml();\" bgcolor=\"%s\" align=\"center\" title=\"%s\"%s><span style=\"font-size:10px\">%s</span></td>" %
|
||||
(bit_pos, bit_pos, bgcolor, "\n".join(title), onclick, label), file=f)
|
||||
(bit_pos, bit_pos, bgcolor, "\n".join(title), onclick, label), file=f)
|
||||
print("</tr>", file=f)
|
||||
print("</table>", file=f)
|
||||
|
||||
|
|
@ -562,9 +591,9 @@ function oml() {
|
|||
|
||||
if True:
|
||||
print(" unused: %d, unknown: %d, known: %d, total: %d, percentage: %.2f%% (%.2f%%)" % (
|
||||
unused_bits, unknown_bits, known_bits, unused_bits + unknown_bits + known_bits,
|
||||
100 * known_bits / (unknown_bits + unused_bits + known_bits),
|
||||
100 * (known_bits + unused_bits) / (unknown_bits + unused_bits + known_bits)))
|
||||
unused_bits, unknown_bits, known_bits, unused_bits + unknown_bits + known_bits,
|
||||
100 * known_bits / (unknown_bits + unused_bits + known_bits),
|
||||
100 * (known_bits + unused_bits) / (unknown_bits + unused_bits + known_bits)))
|
||||
|
||||
bits_by_prefix = dict()
|
||||
|
||||
|
|
@ -583,12 +612,14 @@ function oml() {
|
|||
print("<p/>", file=f)
|
||||
print("<h4>%s</h4>" % prefix, file=f)
|
||||
print("<table cellspacing=0>", file=f)
|
||||
print("<tr><th width=\"400\" align=\"left\">Bit Name</th><th>Position</th></tr>", file=f)
|
||||
print(
|
||||
"<tr><th width=\"400\" align=\"left\">Bit Name</th><th>Position</th></tr>", file=f)
|
||||
|
||||
trstyle = ""
|
||||
for bit_name, bit_pos in sorted(bits):
|
||||
trstyle = " bgcolor=\"#dddddd\"" if trstyle == "" else ""
|
||||
print("<tr%s><td>%s</td><td>%s</td></tr>" % (trstyle, bit_name, bit_pos), file=f)
|
||||
print("<tr%s><td>%s</td><td>%s</td></tr>" %
|
||||
(trstyle, bit_name, bit_pos), file=f)
|
||||
|
||||
print("</table>", file=f)
|
||||
|
||||
|
|
@ -663,7 +694,8 @@ function oml() {
|
|||
print("<a id=\"b%s\"/>" % bit, file=f)
|
||||
|
||||
print("<script><!--", file=f)
|
||||
print("grp2bits['%s'] = ['%s'];" % (grp_bits[0], "', '".join(grp_bits)), file=f)
|
||||
print("grp2bits['%s'] = ['%s'];" %
|
||||
(grp_bits[0], "', '".join(grp_bits)), file=f)
|
||||
for bit in grp_bits:
|
||||
print("bit2grp['%s'] = '%s';" % (bit, grp_bits[0]), file=f)
|
||||
print("//--></script>", file=f)
|
||||
|
|
@ -682,8 +714,10 @@ function oml() {
|
|||
line = " --><td>%s</td>" % (pip)
|
||||
for bit in grp_bits:
|
||||
c = "-"
|
||||
if bit in routebits[segtype] and pip in routebits[segtype][bit]: c = "1"
|
||||
if bit in routezbits[segtype] and pip in routezbits[segtype][bit]: c = "0"
|
||||
if bit in routebits[segtype] and pip in routebits[segtype][bit]:
|
||||
c = "1"
|
||||
if bit in routezbits[segtype] and pip in routezbits[segtype][bit]:
|
||||
c = "0"
|
||||
line = "%s%s<td align=\"center\">%s</td>" % (c, line, c)
|
||||
lines.append(line)
|
||||
|
||||
|
|
@ -699,8 +733,10 @@ function oml() {
|
|||
if len(shared_bits[bit]) > 1:
|
||||
if first_note:
|
||||
print("<p><b>Note(s):</b><br/>", file=f)
|
||||
print("Warning: Groups sharing bit %s: %s." % (bit, ", ".join(sorted(shared_bits[bit]))))
|
||||
print("Groups sharing bit <b>%s</b>: %s.<br/>" % (bit, ", ".join(sorted(shared_bits[bit]))), file=f)
|
||||
print("Warning: Groups sharing bit %s: %s." %
|
||||
(bit, ", ".join(sorted(shared_bits[bit]))))
|
||||
print("Groups sharing bit <b>%s</b>: %s.<br/>" %
|
||||
(bit, ", ".join(sorted(shared_bits[bit]))), file=f)
|
||||
first_note = False
|
||||
if not first_note:
|
||||
print("</p>", file=f)
|
||||
|
|
@ -708,13 +744,15 @@ function oml() {
|
|||
for tile_type in segtiles[segtype]:
|
||||
print("<h3>Tile %s Pseudo PIPs</h3>" % tile_type, file=f)
|
||||
print("<table cellspacing=0>", file=f)
|
||||
print("<tr><th width=\"500\" align=\"left\">PIP</th><th>Type</th></tr>", file=f)
|
||||
print(
|
||||
"<tr><th width=\"500\" align=\"left\">PIP</th><th>Type</th></tr>", file=f)
|
||||
trstyle = ""
|
||||
with db_open("ppips_%s.db" % tile_type.lower()) as fi:
|
||||
for line in fi:
|
||||
pip_name, pip_type = line.split()
|
||||
trstyle = " bgcolor=\"#dddddd\"" if trstyle == "" else ""
|
||||
print("<tr%s><td>%s</td><td>%s</td></tr>" % (trstyle, pip_name, pip_type), file=f)
|
||||
print("<tr%s><td>%s</td><td>%s</td></tr>" %
|
||||
(trstyle, pip_name, pip_type), file=f)
|
||||
print("</table>", file=f)
|
||||
|
||||
print("</div>", file=f)
|
||||
|
|
|
|||
|
|
@ -44,28 +44,24 @@ TEST(BitFieldGetTest, SelectMidway) {
|
|||
|
||||
TEST(BitFieldSetTest, WriteOneBit) {
|
||||
uint32_t actual = prjxray::bit_field_set(
|
||||
static_cast<uint32_t>(0x0), 23, 23,
|
||||
static_cast<uint32_t>(0x1));
|
||||
static_cast<uint32_t>(0x0), 23, 23, static_cast<uint32_t>(0x1));
|
||||
EXPECT_EQ(actual, static_cast<uint32_t>(0x800000));
|
||||
}
|
||||
|
||||
TEST(BitFieldSetTest, WriteOneBitWithOutOfRangeValue) {
|
||||
uint32_t actual = prjxray::bit_field_set(
|
||||
static_cast<uint32_t>(0x0), 23, 23,
|
||||
static_cast<uint32_t>(0x3));
|
||||
static_cast<uint32_t>(0x0), 23, 23, static_cast<uint32_t>(0x3));
|
||||
EXPECT_EQ(actual, static_cast<uint32_t>(0x800000));
|
||||
}
|
||||
|
||||
TEST(BitFieldSetTest, WriteMultipleBits) {
|
||||
uint32_t actual = prjxray::bit_field_set(
|
||||
static_cast<uint32_t>(0x0), 18, 8,
|
||||
static_cast<uint32_t>(0x123));
|
||||
static_cast<uint32_t>(0x0), 18, 8, static_cast<uint32_t>(0x123));
|
||||
EXPECT_EQ(actual, static_cast<uint32_t>(0x12300));
|
||||
}
|
||||
|
||||
TEST(BitFieldSetTest, WriteMultipleBitsWithOutOfRangeValue) {
|
||||
uint32_t actual = prjxray::bit_field_set(
|
||||
static_cast<uint32_t>(0x0), 18, 8,
|
||||
static_cast<uint32_t>(0x1234));
|
||||
static_cast<uint32_t>(0x0), 18, 8, static_cast<uint32_t>(0x1234));
|
||||
EXPECT_EQ(actual, static_cast<uint32_t>(0x23400));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@ namespace prjxray {
|
|||
|
||||
static constexpr const char kSegbitsGlobPattern[] = "segbits_*.db";
|
||||
|
||||
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> Database::segbits() const {
|
||||
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> Database::segbits()
|
||||
const {
|
||||
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> segbits;
|
||||
|
||||
glob_t segbits_glob_results;
|
||||
int ret = glob(absl::StrCat(db_path_, "/", kSegbitsGlobPattern).c_str(),
|
||||
GLOB_NOSORT | GLOB_TILDE,
|
||||
NULL, &segbits_glob_results);
|
||||
GLOB_NOSORT | GLOB_TILDE, NULL, &segbits_glob_results);
|
||||
if (ret < 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
for(size_t idx = 0; idx < segbits_glob_results.gl_pathc; idx++) {
|
||||
for (size_t idx = 0; idx < segbits_glob_results.gl_pathc; idx++) {
|
||||
auto this_segbit = SegbitsFileReader::InitWithFile(
|
||||
segbits_glob_results.gl_pathv[idx]);
|
||||
segbits_glob_results.gl_pathv[idx]);
|
||||
if (this_segbit) {
|
||||
segbits.emplace_back(std::move(this_segbit));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
namespace prjxray {
|
||||
|
||||
template<typename WordType, typename ByteType>
|
||||
template <typename WordType, typename ByteType>
|
||||
class BigEndianSpan {
|
||||
public:
|
||||
public:
|
||||
constexpr static size_t kBytesPerElement = sizeof(WordType);
|
||||
|
||||
using byte_type = ByteType;
|
||||
|
|
@ -18,43 +18,45 @@ class BigEndianSpan {
|
|||
using size_type = std::size_t;
|
||||
|
||||
class value_type {
|
||||
public:
|
||||
public:
|
||||
operator WordType() const {
|
||||
WordType word = 0;
|
||||
for(size_t ii = 0; ii < kBytesPerElement; ++ii) {
|
||||
word |= (static_cast<WordType>(bytes_[ii]) << ((kBytesPerElement - 1 - ii) * 8));
|
||||
for (size_t ii = 0; ii < kBytesPerElement; ++ii) {
|
||||
word |= (static_cast<WordType>(bytes_[ii])
|
||||
<< ((kBytesPerElement - 1 - ii) * 8));
|
||||
}
|
||||
return word;
|
||||
}
|
||||
|
||||
value_type& operator=(WordType word) {
|
||||
for (size_t ii = 0; ii < kBytesPerElement; ++ii) {
|
||||
bytes_[ii] = ((word >> ((kBytesPerElement - 1 - ii) * 8)) & 0xFF);
|
||||
bytes_[ii] =
|
||||
((word >>
|
||||
((kBytesPerElement - 1 - ii) * 8)) &
|
||||
0xFF);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
friend class BigEndianSpan<WordType, ByteType>;
|
||||
|
||||
value_type(absl::Span<ByteType> bytes) : bytes_(bytes) {};
|
||||
value_type(absl::Span<ByteType> bytes) : bytes_(bytes){};
|
||||
|
||||
private:
|
||||
private:
|
||||
absl::Span<ByteType> bytes_;
|
||||
};
|
||||
|
||||
class iterator
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
value_type operator*() const {
|
||||
return value_type(bytes_);
|
||||
}
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
value_type operator*() const { return value_type(bytes_); }
|
||||
|
||||
bool operator==(const iterator &other) const {
|
||||
bool operator==(const iterator& other) const {
|
||||
return bytes_ == other.bytes_;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator &other) const {
|
||||
bool operator!=(const iterator& other) const {
|
||||
return bytes_ != other.bytes_;
|
||||
}
|
||||
|
||||
|
|
@ -63,20 +65,19 @@ class BigEndianSpan {
|
|||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
friend class BigEndianSpan<WordType, ByteType>;
|
||||
|
||||
iterator(absl::Span<ByteType> bytes) : bytes_(bytes) {};
|
||||
iterator(absl::Span<ByteType> bytes) : bytes_(bytes){};
|
||||
|
||||
private:
|
||||
private:
|
||||
absl::Span<ByteType> bytes_;
|
||||
};
|
||||
|
||||
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
BigEndianSpan(absl::Span<ByteType> bytes) : bytes_(bytes) {};
|
||||
BigEndianSpan(absl::Span<ByteType> bytes) : bytes_(bytes){};
|
||||
|
||||
constexpr size_type size() const noexcept {
|
||||
return bytes_.size() / kBytesPerElement;
|
||||
|
|
@ -88,7 +89,7 @@ class BigEndianSpan {
|
|||
|
||||
value_type operator[](size_type pos) const {
|
||||
assert(pos >= 0 && pos < size());
|
||||
return value_type(bytes_.subspan((pos*kBytesPerElement)));
|
||||
return value_type(bytes_.subspan((pos * kBytesPerElement)));
|
||||
}
|
||||
|
||||
constexpr reference at(size_type pos) const {
|
||||
|
|
@ -98,16 +99,15 @@ class BigEndianSpan {
|
|||
iterator begin() const { return iterator(bytes_); }
|
||||
iterator end() const { return iterator({}); }
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
absl::Span<ByteType> bytes_;
|
||||
};
|
||||
|
||||
template<typename WordType, typename Container>
|
||||
template <typename WordType, typename Container>
|
||||
BigEndianSpan<WordType, typename Container::value_type> make_big_endian_span(
|
||||
Container &bytes) {
|
||||
Container& bytes) {
|
||||
return BigEndianSpan<WordType, typename Container::value_type>(
|
||||
absl::Span<typename Container::value_type>(bytes));
|
||||
absl::Span<typename Container::value_type>(bytes));
|
||||
}
|
||||
|
||||
} // namespace prjxray
|
||||
|
|
|
|||
|
|
@ -3,41 +3,44 @@
|
|||
|
||||
namespace prjxray {
|
||||
|
||||
template<typename UInt>
|
||||
template <typename UInt>
|
||||
constexpr UInt bit_mask(const int bit) {
|
||||
return (static_cast<UInt>(1) << bit);
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
template <typename UInt>
|
||||
constexpr UInt bit_sizeof() {
|
||||
return sizeof(UInt) * 8;
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
template <typename UInt>
|
||||
constexpr UInt bit_all_ones() {
|
||||
return ~static_cast<UInt>(0);
|
||||
}
|
||||
|
||||
template<typename UInt>
|
||||
template <typename UInt>
|
||||
constexpr UInt bit_mask_range(const int top_bit, const int bottom_bit) {
|
||||
return ((bit_all_ones<UInt>() >> (bit_sizeof<UInt>() - 1 - top_bit)) &
|
||||
(bit_all_ones<UInt>() - bit_mask<UInt>(bottom_bit) +
|
||||
static_cast<UInt>(1)));
|
||||
(bit_all_ones<UInt>() - bit_mask<UInt>(bottom_bit) +
|
||||
static_cast<UInt>(1)));
|
||||
}
|
||||
|
||||
|
||||
template<typename UInt>
|
||||
constexpr UInt bit_field_get(UInt value, const int top_bit, const int bottom_bit) {
|
||||
return (value & bit_mask_range<UInt>(top_bit, bottom_bit)) >> bottom_bit;
|
||||
template <typename UInt>
|
||||
constexpr UInt bit_field_get(UInt value,
|
||||
const int top_bit,
|
||||
const int bottom_bit) {
|
||||
return (value & bit_mask_range<UInt>(top_bit, bottom_bit)) >>
|
||||
bottom_bit;
|
||||
}
|
||||
|
||||
template<typename UInt, typename ValueType>
|
||||
template <typename UInt, typename ValueType>
|
||||
constexpr UInt bit_field_set(const UInt reg_value,
|
||||
const int top_bit, const int bottom_bit,
|
||||
const ValueType field_value) {
|
||||
const int top_bit,
|
||||
const int bottom_bit,
|
||||
const ValueType field_value) {
|
||||
return ((reg_value & ~bit_mask_range<UInt>(top_bit, bottom_bit)) |
|
||||
((static_cast<UInt>(field_value) << bottom_bit) &
|
||||
bit_mask_range<UInt>(top_bit, bottom_bit)));
|
||||
((static_cast<UInt>(field_value) << bottom_bit) &
|
||||
bit_mask_range<UInt>(top_bit, bottom_bit)));
|
||||
}
|
||||
|
||||
} // namespace prjxray
|
||||
|
|
|
|||
|
|
@ -10,16 +10,15 @@
|
|||
namespace prjxray {
|
||||
|
||||
class Database {
|
||||
public:
|
||||
Database(const std::string &path)
|
||||
: db_path_(path) {}
|
||||
public:
|
||||
Database(const std::string& path) : db_path_(path) {}
|
||||
|
||||
std::vector<std::unique_ptr<SegbitsFileReader>> segbits() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string db_path_;
|
||||
};
|
||||
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_DATABASE_H
|
||||
#endif // PRJXRAY_LIB_DATABASE_H
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
namespace prjxray {
|
||||
|
||||
class MemoryMappedFile {
|
||||
public:
|
||||
public:
|
||||
~MemoryMappedFile();
|
||||
|
||||
static std::unique_ptr<MemoryMappedFile> InitWithFile(
|
||||
const std::string &path);
|
||||
const std::string& path);
|
||||
|
||||
void* const data() const { return data_; }
|
||||
const size_t size() const { return size_; }
|
||||
|
|
@ -22,14 +22,13 @@ class MemoryMappedFile {
|
|||
return {static_cast<uint8_t*>(data_), size_};
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryMappedFile(void *data, size_t size)
|
||||
: data_(data), size_(size) {};
|
||||
private:
|
||||
MemoryMappedFile(void* data, size_t size) : data_(data), size_(size){};
|
||||
|
||||
void *data_;
|
||||
void* data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace prjxray
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_MEMORY_MAPPED_FILE
|
||||
|
|
|
|||
|
|
@ -10,39 +10,41 @@
|
|||
namespace prjxray {
|
||||
|
||||
class SegbitsFileReader {
|
||||
public:
|
||||
public:
|
||||
class value_type {
|
||||
public:
|
||||
public:
|
||||
absl::string_view tag() const { return tag_; }
|
||||
absl::string_view bit() const { return bit_; }
|
||||
|
||||
private:
|
||||
private:
|
||||
friend SegbitsFileReader;
|
||||
|
||||
value_type(const absl::string_view &view);
|
||||
value_type(const absl::string_view& view);
|
||||
|
||||
absl::string_view tag_;
|
||||
absl::string_view bit_;
|
||||
};
|
||||
|
||||
class iterator
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
iterator& operator++();
|
||||
|
||||
bool operator==(iterator other) const {
|
||||
return view_ == other.view_; }
|
||||
return view_ == other.view_;
|
||||
}
|
||||
bool operator!=(iterator other) const {
|
||||
return !(*this == other);}
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const value_type& operator*() const { return value_; }
|
||||
const value_type* operator->() const { return &value_; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
explicit iterator(absl::string_view view)
|
||||
: view_(view), value_(view) {}
|
||||
: view_(view), value_(view) {}
|
||||
|
||||
private:
|
||||
private:
|
||||
friend SegbitsFileReader;
|
||||
|
||||
absl::string_view view_;
|
||||
|
|
@ -50,18 +52,18 @@ class SegbitsFileReader {
|
|||
};
|
||||
|
||||
static std::unique_ptr<SegbitsFileReader> InitWithFile(
|
||||
const std::string &path);
|
||||
const std::string& path);
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
|
||||
private:
|
||||
SegbitsFileReader(std::unique_ptr<MemoryMappedFile> &&mapped_file)
|
||||
: mapped_file_(std::move(mapped_file)) {};
|
||||
private:
|
||||
SegbitsFileReader(std::unique_ptr<MemoryMappedFile>&& mapped_file)
|
||||
: mapped_file_(std::move(mapped_file)){};
|
||||
|
||||
std::unique_ptr<MemoryMappedFile> mapped_file_;
|
||||
};
|
||||
|
||||
} // namespace prjxray
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_SEGBITS_FILE_READER_H
|
||||
|
|
|
|||
|
|
@ -16,24 +16,24 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
class BitstreamReader {
|
||||
public:
|
||||
public:
|
||||
using value_type = ConfigurationPacket;
|
||||
|
||||
class iterator
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
: public std::iterator<std::input_iterator_tag, value_type> {
|
||||
public:
|
||||
iterator& operator++();
|
||||
|
||||
bool operator==(const iterator &other) const;
|
||||
bool operator!=(const iterator &other) const;
|
||||
bool operator==(const iterator& other) const;
|
||||
bool operator!=(const iterator& other) const;
|
||||
|
||||
const value_type& operator*() const;
|
||||
const value_type* operator->() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
explicit iterator(absl::Span<uint32_t> words);
|
||||
|
||||
private:
|
||||
private:
|
||||
friend BitstreamReader;
|
||||
|
||||
ConfigurationPacket::ParseResult parse_result_;
|
||||
|
|
@ -42,31 +42,32 @@ class BitstreamReader {
|
|||
|
||||
// Construct a reader from a collection of 32-bit, big-endian words.
|
||||
// Assumes that any sync word has already been removed.
|
||||
BitstreamReader(std::vector<uint32_t> &&words);
|
||||
BitstreamReader(std::vector<uint32_t>&& words);
|
||||
|
||||
// Construct a `BitstreamReader` from a Container of bytes.
|
||||
// Any bytes preceding an initial sync word are ignored.
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
static absl::optional<BitstreamReader> InitWithBytes(T bitstream);
|
||||
|
||||
const std::vector<uint32_t> &words() { return words_; };
|
||||
const std::vector<uint32_t>& words() { return words_; };
|
||||
|
||||
// Returns an iterator that yields `ConfigurationPackets`
|
||||
// as read from the bitstream.
|
||||
iterator begin();
|
||||
iterator end();
|
||||
private:
|
||||
|
||||
private:
|
||||
static std::array<uint8_t, 4> kSyncWord;
|
||||
|
||||
std::vector<uint32_t> words_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T bitstream) {
|
||||
// If this is really a Xilinx 7-Series bitstream, there will be a sync
|
||||
// word somewhere toward the beginning.
|
||||
auto sync_pos = std::search(bitstream.begin(), bitstream.end(),
|
||||
kSyncWord.begin(), kSyncWord.end());
|
||||
kSyncWord.begin(), kSyncWord.end());
|
||||
if (sync_pos == bitstream.end()) {
|
||||
return absl::optional<BitstreamReader>();
|
||||
}
|
||||
|
|
@ -74,13 +75,13 @@ absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T bitstream) {
|
|||
|
||||
// Wrap the provided container in a span that strips off the preamble.
|
||||
absl::Span<typename T::value_type> bitstream_span(bitstream);
|
||||
auto config_packets = bitstream_span.subspan(
|
||||
sync_pos - bitstream.begin());
|
||||
auto config_packets =
|
||||
bitstream_span.subspan(sync_pos - bitstream.begin());
|
||||
|
||||
// Convert the bytes into 32-bit, big-endian words.
|
||||
auto big_endian_reader = make_big_endian_span<uint32_t>(config_packets);
|
||||
std::vector<uint32_t> words{big_endian_reader.begin(),
|
||||
big_endian_reader.end()};
|
||||
big_endian_reader.end()};
|
||||
|
||||
return BitstreamReader(std::move(words));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,18 +16,18 @@ enum class BlockType : unsigned int {
|
|||
/* reserved = 0x3, */
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, BlockType value);
|
||||
std::ostream& operator<<(std::ostream& o, BlockType value);
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
template <>
|
||||
struct convert<prjxray::xilinx::xc7series::BlockType> {
|
||||
static Node encode(const prjxray::xilinx::xc7series::BlockType &rhs);
|
||||
static Node encode(const prjxray::xilinx::xc7series::BlockType& rhs);
|
||||
static bool decode(const Node& node,
|
||||
prjxray::xilinx::xc7series::BlockType &lhs);
|
||||
prjxray::xilinx::xc7series::BlockType& lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
|
|
|
|||
|
|
@ -14,30 +14,31 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
class Configuration {
|
||||
public:
|
||||
using FrameMap = std::map<FrameAddress,
|
||||
absl::Span<uint32_t>>;
|
||||
public:
|
||||
using FrameMap = std::map<FrameAddress, absl::Span<uint32_t>>;
|
||||
|
||||
template<typename Collection>
|
||||
template <typename Collection>
|
||||
static absl::optional<Configuration> InitWithPackets(
|
||||
const Part& part, Collection &packets);
|
||||
const Part& part,
|
||||
Collection& packets);
|
||||
|
||||
Configuration(const Part& part, const FrameMap &frames)
|
||||
: part_(part), frames_(std::move(frames)) {}
|
||||
Configuration(const Part& part, const FrameMap& frames)
|
||||
: part_(part), frames_(std::move(frames)) {}
|
||||
|
||||
const Part& part() const { return part_; }
|
||||
const FrameMap& frames() const { return frames_; }
|
||||
|
||||
private:
|
||||
private:
|
||||
static constexpr int kWordsPerFrame = 101;
|
||||
|
||||
Part part_;
|
||||
FrameMap frames_;
|
||||
};
|
||||
|
||||
template<typename Collection>
|
||||
template <typename Collection>
|
||||
absl::optional<Configuration> Configuration::InitWithPackets(
|
||||
const Part& part, Collection &packets) {
|
||||
const Part& part,
|
||||
Collection& packets) {
|
||||
// Registers that can be directly written to.
|
||||
uint32_t command_register = 0;
|
||||
uint32_t frame_address_register = 0;
|
||||
|
|
@ -55,95 +56,106 @@ absl::optional<Configuration> Configuration::InitWithPackets(
|
|||
}
|
||||
|
||||
switch (packet.address()) {
|
||||
case ConfigurationRegister::MASK:
|
||||
if (packet.data().size() < 1) continue;
|
||||
mask_register = packet.data()[0];
|
||||
break;
|
||||
case ConfigurationRegister::CTL1:
|
||||
if (packet.data().size() < 1) continue;
|
||||
ctl1_register = packet.data()[0] & mask_register;
|
||||
break;
|
||||
case ConfigurationRegister::CMD:
|
||||
if (packet.data().size() < 1) continue;
|
||||
command_register = packet.data()[0];
|
||||
// Writes to CMD trigger an immediate action. In the case of
|
||||
// WCFG, that is just setting a flag for the next FDIR.
|
||||
if (command_register == 0x1) {
|
||||
start_new_write = true;
|
||||
}
|
||||
break;
|
||||
case ConfigurationRegister::IDCODE:
|
||||
// This really should be a one-word write.
|
||||
if (packet.data().size() < 1) continue;
|
||||
|
||||
// If the IDCODE doesn't match our expected part,
|
||||
// consider the bitstream invalid.
|
||||
if (packet.data()[0] != part.idcode()) {
|
||||
return {};
|
||||
}
|
||||
break;
|
||||
case ConfigurationRegister::FAR:
|
||||
// This really should be a one-word write.
|
||||
if (packet.data().size() < 1) continue;
|
||||
frame_address_register = packet.data()[0];
|
||||
|
||||
// Per UG470, the command present in the CMD register
|
||||
// is executed each time the FAR register is laoded
|
||||
// with a new value. As we only care about WCFG
|
||||
// commands, just check that here. CTRL1 is completely
|
||||
// undocumented but looking at generated bitstreams, bit 21
|
||||
// is used when per-frame CRC is enabled. Setting this
|
||||
// bit seems to inhibit the re-execution of CMD during a
|
||||
// FAR write. In practice, this is used so FAR writes
|
||||
// can be added in the bitstream to show progress
|
||||
// markers without impacting the actual write
|
||||
// operation.
|
||||
if (bit_field_get(ctl1_register, 21, 21) == 0 &&
|
||||
command_register == 0x1) {
|
||||
start_new_write = true;
|
||||
}
|
||||
break;
|
||||
case ConfigurationRegister::FDRI: {
|
||||
if (start_new_write) {
|
||||
current_frame_address = frame_address_register;
|
||||
start_new_write = false;
|
||||
}
|
||||
|
||||
// 7-series frames are 101-words long. Writes to this
|
||||
// register can be multiples of that to do
|
||||
// auto-incrementing block writes.
|
||||
for (size_t ii = 0;
|
||||
ii < packet.data().size();
|
||||
ii += kWordsPerFrame) {
|
||||
frames[current_frame_address] =
|
||||
packet.data().subspan(
|
||||
ii, kWordsPerFrame);
|
||||
|
||||
auto next_address = part.GetNextFrameAddress(
|
||||
current_frame_address);
|
||||
if (!next_address) break;
|
||||
|
||||
// Bitstreams appear to have 2 frames of
|
||||
// padding between rows.
|
||||
if (next_address->row_address() !=
|
||||
current_frame_address.row_address()) {
|
||||
ii += 2 * kWordsPerFrame;
|
||||
case ConfigurationRegister::MASK:
|
||||
if (packet.data().size() < 1)
|
||||
continue;
|
||||
mask_register = packet.data()[0];
|
||||
break;
|
||||
case ConfigurationRegister::CTL1:
|
||||
if (packet.data().size() < 1)
|
||||
continue;
|
||||
ctl1_register =
|
||||
packet.data()[0] & mask_register;
|
||||
break;
|
||||
case ConfigurationRegister::CMD:
|
||||
if (packet.data().size() < 1)
|
||||
continue;
|
||||
command_register = packet.data()[0];
|
||||
// Writes to CMD trigger an immediate action. In
|
||||
// the case of WCFG, that is just setting a flag
|
||||
// for the next FDIR.
|
||||
if (command_register == 0x1) {
|
||||
start_new_write = true;
|
||||
}
|
||||
current_frame_address = *next_address;
|
||||
break;
|
||||
case ConfigurationRegister::IDCODE:
|
||||
// This really should be a one-word write.
|
||||
if (packet.data().size() < 1)
|
||||
continue;
|
||||
|
||||
// If the IDCODE doesn't match our expected
|
||||
// part, consider the bitstream invalid.
|
||||
if (packet.data()[0] != part.idcode()) {
|
||||
return {};
|
||||
}
|
||||
break;
|
||||
case ConfigurationRegister::FAR:
|
||||
// This really should be a one-word write.
|
||||
if (packet.data().size() < 1)
|
||||
continue;
|
||||
frame_address_register = packet.data()[0];
|
||||
|
||||
// Per UG470, the command present in the CMD
|
||||
// register is executed each time the FAR
|
||||
// register is laoded with a new value. As we
|
||||
// only care about WCFG commands, just check
|
||||
// that here. CTRL1 is completely undocumented
|
||||
// but looking at generated bitstreams, bit 21
|
||||
// is used when per-frame CRC is enabled.
|
||||
// Setting this bit seems to inhibit the
|
||||
// re-execution of CMD during a FAR write. In
|
||||
// practice, this is used so FAR writes can be
|
||||
// added in the bitstream to show progress
|
||||
// markers without impacting the actual write
|
||||
// operation.
|
||||
if (bit_field_get(ctl1_register, 21, 21) == 0 &&
|
||||
command_register == 0x1) {
|
||||
start_new_write = true;
|
||||
}
|
||||
break;
|
||||
case ConfigurationRegister::FDRI: {
|
||||
if (start_new_write) {
|
||||
current_frame_address =
|
||||
frame_address_register;
|
||||
start_new_write = false;
|
||||
}
|
||||
|
||||
// 7-series frames are 101-words long. Writes
|
||||
// to this register can be multiples of that to
|
||||
// do auto-incrementing block writes.
|
||||
for (size_t ii = 0; ii < packet.data().size();
|
||||
ii += kWordsPerFrame) {
|
||||
frames[current_frame_address] =
|
||||
packet.data().subspan(
|
||||
ii, kWordsPerFrame);
|
||||
|
||||
auto next_address =
|
||||
part.GetNextFrameAddress(
|
||||
current_frame_address);
|
||||
if (!next_address)
|
||||
break;
|
||||
|
||||
// Bitstreams appear to have 2 frames of
|
||||
// padding between rows.
|
||||
if (next_address->row_address() !=
|
||||
current_frame_address
|
||||
.row_address()) {
|
||||
ii += 2 * kWordsPerFrame;
|
||||
}
|
||||
current_frame_address = *next_address;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Configuration(part, frames);
|
||||
}
|
||||
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_H_
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_H_
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
class ConfigurationFrameRange {
|
||||
public:
|
||||
public:
|
||||
ConfigurationFrameRange() : begin_(0), end_(0) {}
|
||||
|
||||
ConfigurationFrameRange(FrameAddress begin, FrameAddress end)
|
||||
: begin_(begin), end_(end) {};
|
||||
: begin_(begin), end_(end){};
|
||||
|
||||
FrameAddress begin() const { return begin_; }
|
||||
FrameAddress end() const { return end_; }
|
||||
|
|
@ -25,7 +25,7 @@ class ConfigurationFrameRange {
|
|||
|
||||
bool Contains(FrameAddress address) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
FrameAddress begin_;
|
||||
FrameAddress end_;
|
||||
};
|
||||
|
|
@ -35,13 +35,13 @@ class ConfigurationFrameRange {
|
|||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
template <>
|
||||
struct convert<prjxray::xilinx::xc7series::ConfigurationFrameRange> {
|
||||
static Node encode(
|
||||
const prjxray::xilinx::xc7series::ConfigurationFrameRange &rhs);
|
||||
const prjxray::xilinx::xc7series::ConfigurationFrameRange& rhs);
|
||||
static bool decode(
|
||||
const Node& node,
|
||||
prjxray::xilinx::xc7series::ConfigurationFrameRange &lhs);
|
||||
const Node& node,
|
||||
prjxray::xilinx::xc7series::ConfigurationFrameRange& lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
} // namespace YAML
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_RANGE_H_
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
class ConfigurationPacket {
|
||||
public:
|
||||
public:
|
||||
typedef std::pair<absl::Span<uint32_t>,
|
||||
absl::optional<ConfigurationPacket>>
|
||||
ParseResult;
|
||||
absl::optional<ConfigurationPacket>>
|
||||
ParseResult;
|
||||
|
||||
enum Opcode {
|
||||
NOP = 0,
|
||||
|
|
@ -24,11 +24,14 @@ class ConfigurationPacket {
|
|||
/* reserved = 3 */
|
||||
};
|
||||
|
||||
ConfigurationPacket(unsigned int header_type, Opcode opcode,
|
||||
ConfigurationRegister address,
|
||||
const absl::Span<uint32_t> &data)
|
||||
: header_type_(header_type), opcode_(opcode),
|
||||
address_(address), data_(std::move(data)) {}
|
||||
ConfigurationPacket(unsigned int header_type,
|
||||
Opcode opcode,
|
||||
ConfigurationRegister address,
|
||||
const absl::Span<uint32_t>& data)
|
||||
: header_type_(header_type),
|
||||
opcode_(opcode),
|
||||
address_(address),
|
||||
data_(std::move(data)) {}
|
||||
|
||||
// Attempt to read a configuration packet from a sequence of
|
||||
// 32-bit, big-endian words. If successful, returns the packet read and
|
||||
|
|
@ -38,22 +41,22 @@ class ConfigurationPacket {
|
|||
// packet is produced. If no valid header is found, an empty span is
|
||||
// returned.
|
||||
static ParseResult InitWithWords(
|
||||
absl::Span<uint32_t> words,
|
||||
const ConfigurationPacket *previous_packet = nullptr);
|
||||
absl::Span<uint32_t> words,
|
||||
const ConfigurationPacket* previous_packet = nullptr);
|
||||
|
||||
unsigned int header_type() const { return header_type_; }
|
||||
const Opcode opcode() const { return opcode_; }
|
||||
const ConfigurationRegister address() const { return address_; }
|
||||
const absl::Span<uint32_t> &data() const { return data_; }
|
||||
const absl::Span<uint32_t>& data() const { return data_; }
|
||||
|
||||
private:
|
||||
private:
|
||||
unsigned int header_type_;
|
||||
Opcode opcode_;
|
||||
ConfigurationRegister address_;
|
||||
absl::Span<uint32_t> data_;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet);
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket& packet);
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
|
|
|
|||
|
|
@ -8,29 +8,29 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
enum class ConfigurationRegister : unsigned int {
|
||||
CRC = 0x00,
|
||||
FAR = 0x01,
|
||||
FDRI = 0x02,
|
||||
FDRO = 0x03,
|
||||
CMD = 0x04,
|
||||
CTL0 = 0x05,
|
||||
MASK = 0x06,
|
||||
STAT = 0x07,
|
||||
LOUT = 0x08,
|
||||
COR0 = 0x09,
|
||||
MFWR = 0x0a,
|
||||
CBC = 0x0b,
|
||||
IDCODE = 0x0c,
|
||||
AXSS = 0x0d,
|
||||
COR1 = 0x0e,
|
||||
WBSTAR = 0x10,
|
||||
TIMER = 0x11,
|
||||
CRC = 0x00,
|
||||
FAR = 0x01,
|
||||
FDRI = 0x02,
|
||||
FDRO = 0x03,
|
||||
CMD = 0x04,
|
||||
CTL0 = 0x05,
|
||||
MASK = 0x06,
|
||||
STAT = 0x07,
|
||||
LOUT = 0x08,
|
||||
COR0 = 0x09,
|
||||
MFWR = 0x0a,
|
||||
CBC = 0x0b,
|
||||
IDCODE = 0x0c,
|
||||
AXSS = 0x0d,
|
||||
COR1 = 0x0e,
|
||||
WBSTAR = 0x10,
|
||||
TIMER = 0x11,
|
||||
BOOTSTS = 0x16,
|
||||
CTL1 = 0x18,
|
||||
BSPI = 0x1F,
|
||||
CTL1 = 0x18,
|
||||
BSPI = 0x1F,
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value);
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationRegister& value);
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
|
|
|
|||
|
|
@ -12,14 +12,16 @@ namespace xilinx {
|
|||
namespace xc7series {
|
||||
|
||||
class FrameAddress {
|
||||
public:
|
||||
public:
|
||||
FrameAddress() : address_(0) {}
|
||||
|
||||
FrameAddress(uint32_t address)
|
||||
: address_(address) {};
|
||||
FrameAddress(uint32_t address) : address_(address){};
|
||||
|
||||
FrameAddress(BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor);
|
||||
FrameAddress(BlockType block_type,
|
||||
bool is_bottom_half_rows,
|
||||
uint8_t row,
|
||||
uint16_t column,
|
||||
uint8_t minor);
|
||||
|
||||
operator uint32_t() const { return address_; }
|
||||
|
||||
|
|
@ -29,22 +31,22 @@ class FrameAddress {
|
|||
uint16_t column_address() const;
|
||||
uint8_t minor_address() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32_t address_;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr);
|
||||
std::ostream& operator<<(std::ostream& o, const FrameAddress& addr);
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
template <>
|
||||
struct convert<prjxray::xilinx::xc7series::FrameAddress> {
|
||||
static Node encode(const prjxray::xilinx::xc7series::FrameAddress &rhs);
|
||||
static Node encode(const prjxray::xilinx::xc7series::FrameAddress& rhs);
|
||||
static bool decode(const Node& node,
|
||||
prjxray::xilinx::xc7series::FrameAddress &lhs);
|
||||
prjxray::xilinx::xc7series::FrameAddress& lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
} // namespace YAML
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_
|
||||
|
|
|
|||
|
|
@ -4,38 +4,40 @@
|
|||
#include <vector>
|
||||
|
||||
#include <absl/types/optional.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
#include <prjxray/xilinx/xc7series/configuration_frame_range.h>
|
||||
#include <prjxray/xilinx/xc7series/frame_address.h>
|
||||
|
||||
namespace prjxray {
|
||||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
class Part {
|
||||
public:
|
||||
static absl::optional<Part> FromFile(const std::string &path);
|
||||
public:
|
||||
static absl::optional<Part> FromFile(const std::string& path);
|
||||
|
||||
// Constructs an invalid part with a zero IDCODE. Required for YAML
|
||||
// conversion but shouldn't be used otherwise.
|
||||
Part() : idcode_(0), frame_ranges_() {}
|
||||
|
||||
Part(uint32_t idcode,
|
||||
const std::vector<ConfigurationFrameRange> &ranges)
|
||||
: idcode_(idcode), frame_ranges_(std::move(ranges)) {}
|
||||
const std::vector<ConfigurationFrameRange>& ranges)
|
||||
: idcode_(idcode), frame_ranges_(std::move(ranges)) {}
|
||||
|
||||
uint32_t idcode() const { return idcode_; }
|
||||
|
||||
const std::vector<ConfigurationFrameRange>&
|
||||
configuration_frame_ranges() const { return frame_ranges_; }
|
||||
const std::vector<ConfigurationFrameRange>& configuration_frame_ranges()
|
||||
const {
|
||||
return frame_ranges_;
|
||||
}
|
||||
|
||||
absl::optional<FrameAddress>
|
||||
GetNextFrameAddress(FrameAddress address) const;
|
||||
absl::optional<FrameAddress> GetNextFrameAddress(
|
||||
FrameAddress address) const;
|
||||
|
||||
private:
|
||||
uint32_t idcode_;
|
||||
private:
|
||||
uint32_t idcode_;
|
||||
|
||||
// Ranges are expected to be non-overlapping.
|
||||
std::vector<ConfigurationFrameRange> frame_ranges_;
|
||||
// Ranges are expected to be non-overlapping.
|
||||
std::vector<ConfigurationFrameRange> frame_ranges_;
|
||||
};
|
||||
|
||||
} // namespace xc7series
|
||||
|
|
@ -43,12 +45,12 @@ class Part {
|
|||
} // namespace prjxray
|
||||
|
||||
namespace YAML {
|
||||
template<>
|
||||
template <>
|
||||
struct convert<prjxray::xilinx::xc7series::Part> {
|
||||
static Node encode(const prjxray::xilinx::xc7series::Part &rhs);
|
||||
static Node encode(const prjxray::xilinx::xc7series::Part& rhs);
|
||||
static bool decode(const Node& node,
|
||||
prjxray::xilinx::xc7series::Part &lhs);
|
||||
prjxray::xilinx::xc7series::Part& lhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
} // namespace YAML
|
||||
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_PART_H_
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_PART_H_
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
||||
std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
|
||||
const std::string &path) {
|
||||
|
||||
const std::string& path) {
|
||||
int fd = open(path.c_str(), O_RDONLY, 0);
|
||||
if (fd == -1) return nullptr;
|
||||
if (fd == -1)
|
||||
return nullptr;
|
||||
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
|
|
@ -26,25 +26,26 @@ std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
|
|||
if (statbuf.st_size == 0) {
|
||||
close(fd);
|
||||
return std::unique_ptr<MemoryMappedFile>(
|
||||
new MemoryMappedFile(nullptr, 0));
|
||||
new MemoryMappedFile(nullptr, 0));
|
||||
}
|
||||
|
||||
void *file_map = mmap(NULL, statbuf.st_size, PROT_READ,
|
||||
MAP_PRIVATE | MAP_POPULATE, fd, 0);
|
||||
void* file_map = mmap(NULL, statbuf.st_size, PROT_READ,
|
||||
MAP_PRIVATE | MAP_POPULATE, fd, 0);
|
||||
|
||||
// If mmap() succeeded, the fd is no longer needed as the mapping will
|
||||
// keep the file open. If mmap() failed, the fd needs to be closed
|
||||
// anyway.
|
||||
close(fd);
|
||||
|
||||
if (file_map == MAP_FAILED) return nullptr;
|
||||
if (file_map == MAP_FAILED)
|
||||
return nullptr;
|
||||
|
||||
return std::unique_ptr<MemoryMappedFile>(
|
||||
new MemoryMappedFile(file_map, statbuf.st_size));
|
||||
new MemoryMappedFile(file_map, statbuf.st_size));
|
||||
}
|
||||
|
||||
MemoryMappedFile::~MemoryMappedFile() {
|
||||
munmap(data_, size_);
|
||||
}
|
||||
|
||||
} // namepsace prjxray
|
||||
} // namespace prjxray
|
||||
|
|
|
|||
|
|
@ -3,26 +3,26 @@
|
|||
namespace prjxray {
|
||||
|
||||
std::unique_ptr<SegbitsFileReader> SegbitsFileReader::InitWithFile(
|
||||
const std::string &path) {
|
||||
|
||||
const std::string& path) {
|
||||
auto mapped_file = MemoryMappedFile::InitWithFile(path);
|
||||
if (!mapped_file) return nullptr;
|
||||
if (!mapped_file)
|
||||
return nullptr;
|
||||
|
||||
return std::unique_ptr<SegbitsFileReader>(
|
||||
new SegbitsFileReader(std::move(mapped_file)));
|
||||
new SegbitsFileReader(std::move(mapped_file)));
|
||||
}
|
||||
|
||||
SegbitsFileReader::iterator SegbitsFileReader::begin() {
|
||||
return iterator(absl::string_view(
|
||||
static_cast<const char*>(mapped_file_->data()),
|
||||
mapped_file_->size()));
|
||||
return iterator(
|
||||
absl::string_view(static_cast<const char*>(mapped_file_->data()),
|
||||
mapped_file_->size()));
|
||||
}
|
||||
|
||||
SegbitsFileReader::iterator SegbitsFileReader::end() {
|
||||
return iterator(absl::string_view());
|
||||
}
|
||||
|
||||
SegbitsFileReader::value_type::value_type(const absl::string_view &view) {
|
||||
SegbitsFileReader::value_type::value_type(const absl::string_view& view) {
|
||||
size_t separator_start = view.find_first_of(" \t");
|
||||
if (separator_start == absl::string_view::npos) {
|
||||
tag_ = view;
|
||||
|
|
@ -55,5 +55,4 @@ SegbitsFileReader::iterator& SegbitsFileReader::iterator::operator++() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace prjxray
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(SegbitsFileReaderTest, NonExistantFileReturnsNull) {
|
||||
EXPECT_FALSE(prjxray::SegbitsFileReader::InitWithFile("does_not_exist"));
|
||||
EXPECT_FALSE(
|
||||
prjxray::SegbitsFileReader::InitWithFile("does_not_exist"));
|
||||
}
|
||||
|
||||
TEST(SegbitsFileReaderTest, ZeroLengthFileYieldsNoItems) {
|
||||
auto segbits_reader =
|
||||
prjxray::SegbitsFileReader::InitWithFile("empty_file");
|
||||
prjxray::SegbitsFileReader::InitWithFile("empty_file");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
EXPECT_EQ(segbits_reader->begin(), segbits_reader->end());
|
||||
|
|
@ -19,7 +20,7 @@ TEST(SegbitsFileReaderTest, ZeroLengthFileYieldsNoItems) {
|
|||
|
||||
TEST(SegbitsFileReaderTest, FileWithOneEntry) {
|
||||
auto segbits_reader =
|
||||
prjxray::SegbitsFileReader::InitWithFile("one_entry.segbits");
|
||||
prjxray::SegbitsFileReader::InitWithFile("one_entry.segbits");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
auto begin_iter = segbits_reader->begin();
|
||||
|
|
@ -31,7 +32,7 @@ TEST(SegbitsFileReaderTest, FileWithOneEntry) {
|
|||
|
||||
TEST(SegbitsFileReaderTest, FileWithOneEntryWithEmptyTag) {
|
||||
auto segbits_reader = prjxray::SegbitsFileReader::InitWithFile(
|
||||
"one_entry_empty_tag.segbits");
|
||||
"one_entry_empty_tag.segbits");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
auto begin_iter = segbits_reader->begin();
|
||||
|
|
@ -43,7 +44,7 @@ TEST(SegbitsFileReaderTest, FileWithOneEntryWithEmptyTag) {
|
|||
|
||||
TEST(SegbitsFileReaderTest, FileWithOneEntryMissingBit) {
|
||||
auto segbits_reader = prjxray::SegbitsFileReader::InitWithFile(
|
||||
"one_entry_missing_bit.segbits");
|
||||
"one_entry_missing_bit.segbits");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
auto begin_iter = segbits_reader->begin();
|
||||
|
|
@ -55,7 +56,7 @@ TEST(SegbitsFileReaderTest, FileWithOneEntryMissingBit) {
|
|||
|
||||
TEST(SegbitsFileReaderTest, FileWithOneEntryWithExtraWhitespace) {
|
||||
auto segbits_reader = prjxray::SegbitsFileReader::InitWithFile(
|
||||
"one_entry_extra_whitespace.segbits");
|
||||
"one_entry_extra_whitespace.segbits");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
auto begin_iter = segbits_reader->begin();
|
||||
|
|
@ -66,8 +67,8 @@ TEST(SegbitsFileReaderTest, FileWithOneEntryWithExtraWhitespace) {
|
|||
}
|
||||
|
||||
TEST(SegbitsFileReaderTest, FileWithTwoEntries) {
|
||||
auto segbits_reader = prjxray::SegbitsFileReader::InitWithFile(
|
||||
"two_entries.segbits");
|
||||
auto segbits_reader =
|
||||
prjxray::SegbitsFileReader::InitWithFile("two_entries.segbits");
|
||||
ASSERT_TRUE(segbits_reader);
|
||||
|
||||
auto iter = segbits_reader->begin();
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ namespace xc7series {
|
|||
|
||||
std::array<uint8_t, 4> BitstreamReader::kSyncWord{0xAA, 0x99, 0x55, 0x66};
|
||||
|
||||
BitstreamReader::BitstreamReader(std::vector<uint32_t> &&words)
|
||||
: words_(std::move(words)) {}
|
||||
BitstreamReader::BitstreamReader(std::vector<uint32_t>&& words)
|
||||
: words_(std::move(words)) {}
|
||||
|
||||
BitstreamReader::iterator BitstreamReader::begin() {
|
||||
return iterator(absl::MakeSpan(words_));
|
||||
|
|
@ -23,14 +23,12 @@ BitstreamReader::iterator::iterator(absl::Span<uint32_t> words) {
|
|||
++(*this);
|
||||
}
|
||||
|
||||
BitstreamReader::iterator&
|
||||
BitstreamReader::iterator::operator++() {
|
||||
BitstreamReader::iterator& BitstreamReader::iterator::operator++() {
|
||||
do {
|
||||
auto new_result = ConfigurationPacket::InitWithWords(
|
||||
parse_result_.first,
|
||||
parse_result_.second.has_value() ?
|
||||
parse_result_.second.operator->() :
|
||||
nullptr);
|
||||
parse_result_.first, parse_result_.second.has_value()
|
||||
? parse_result_.second.operator->()
|
||||
: nullptr);
|
||||
|
||||
// If the a valid header is being found but there are
|
||||
// insufficient words to yield a packet, consider it the end.
|
||||
|
|
@ -41,8 +39,7 @@ BitstreamReader::iterator::operator++() {
|
|||
|
||||
words_ = parse_result_.first;
|
||||
parse_result_ = new_result;
|
||||
} while (!parse_result_.first.empty() &&
|
||||
!parse_result_.second);
|
||||
} while (!parse_result_.first.empty() && !parse_result_.second);
|
||||
|
||||
if (!parse_result_.second) {
|
||||
words_ = absl::Span<uint32_t>();
|
||||
|
|
@ -51,21 +48,21 @@ BitstreamReader::iterator::operator++() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool BitstreamReader::iterator::operator==(const iterator &other) const {
|
||||
bool BitstreamReader::iterator::operator==(const iterator& other) const {
|
||||
return words_ == other.words_;
|
||||
}
|
||||
|
||||
bool BitstreamReader::iterator::operator!=(const iterator &other) const {
|
||||
bool BitstreamReader::iterator::operator!=(const iterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const BitstreamReader::value_type&
|
||||
BitstreamReader::iterator::operator*() const {
|
||||
const BitstreamReader::value_type& BitstreamReader::iterator::operator*()
|
||||
const {
|
||||
return *(parse_result_.second);
|
||||
}
|
||||
|
||||
const BitstreamReader::value_type*
|
||||
BitstreamReader::iterator::operator->() const {
|
||||
const BitstreamReader::value_type* BitstreamReader::iterator::operator->()
|
||||
const {
|
||||
return parse_result_.second.operator->();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,30 +19,23 @@ TEST(BitstreamReaderTest, InitWithOnlySyncReturnsObject) {
|
|||
EXPECT_TRUE(reader);
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest,
|
||||
InitWithSyncAfterNonWordSizedPaddingReturnsObject) {
|
||||
std::vector<uint8_t> bitstream{
|
||||
0xFF, 0xFE,
|
||||
0xAA, 0x99, 0x55, 0x66
|
||||
};
|
||||
TEST(BitstreamReaderTest, InitWithSyncAfterNonWordSizedPaddingReturnsObject) {
|
||||
std::vector<uint8_t> bitstream{0xFF, 0xFE, 0xAA, 0x99, 0x55, 0x66};
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
|
||||
EXPECT_TRUE(reader);
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest,
|
||||
InitWithSyncAfterWordSizedPaddingReturnsObject) {
|
||||
std::vector<uint8_t> bitstream{
|
||||
0xFF, 0xFE, 0xFD, 0xFC,
|
||||
0xAA, 0x99, 0x55, 0x66
|
||||
};
|
||||
TEST(BitstreamReaderTest, InitWithSyncAfterWordSizedPaddingReturnsObject) {
|
||||
std::vector<uint8_t> bitstream{0xFF, 0xFE, 0xFD, 0xFC,
|
||||
0xAA, 0x99, 0x55, 0x66};
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
|
||||
EXPECT_TRUE(reader);
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, ParsesType1Packet) {
|
||||
std::vector<uint8_t> bitstream{
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x20, 0x00, 0x00, 0x00, // NOP
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x20, 0x00, 0x00, 0x00, // NOP
|
||||
};
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
|
||||
ASSERT_TRUE(reader);
|
||||
|
|
@ -50,34 +43,31 @@ TEST(BitstreamReaderTest, ParsesType1Packet) {
|
|||
|
||||
auto first_packet = reader->begin();
|
||||
EXPECT_EQ(first_packet->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::NOP);
|
||||
xc7series::ConfigurationPacket::Opcode::NOP);
|
||||
|
||||
EXPECT_EQ(++first_packet, reader->end());
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, ParseType2PacketWithoutType1Fails) {
|
||||
std::vector<uint8_t> bitstream{
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x40, 0x00, 0x00, 0x00, // Type 2 NOP
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x40, 0x00, 0x00, 0x00, // Type 2 NOP
|
||||
};
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
|
||||
ASSERT_TRUE(reader);
|
||||
EXPECT_EQ(reader->begin(), reader->end());
|
||||
}
|
||||
|
||||
|
||||
TEST(BitstreamReaderTest, ParsesType2AfterType1Packet) {
|
||||
std::vector<uint8_t> bitstream{
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x28, 0x00, 0x60, 0x00, // Type 1 Read zero bytes from 6
|
||||
0x48, 0x00, 0x00, 0x04, // Type 2 write of 4 words
|
||||
0x1, 0x2, 0x3, 0x4,
|
||||
0x5, 0x6, 0x7, 0x8,
|
||||
0x9, 0xA, 0xB, 0xC,
|
||||
0xD, 0xE, 0xF, 0x10,
|
||||
0xAA, 0x99, 0x55, 0x66, // sync
|
||||
0x28, 0x00, 0x60, 0x00, // Type 1 Read zero bytes from 6
|
||||
0x48, 0x00, 0x00, 0x04, // Type 2 write of 4 words
|
||||
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
|
||||
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
|
||||
};
|
||||
std::vector<uint32_t> data_words{
|
||||
0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10};
|
||||
std::vector<uint32_t> data_words{0x01020304, 0x05060708, 0x090A0B0C,
|
||||
0x0D0E0F10};
|
||||
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
|
||||
ASSERT_TRUE(reader);
|
||||
|
|
@ -85,17 +75,17 @@ TEST(BitstreamReaderTest, ParsesType2AfterType1Packet) {
|
|||
|
||||
auto first_packet = reader->begin();
|
||||
EXPECT_EQ(first_packet->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
EXPECT_EQ(first_packet->address(),
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
EXPECT_EQ(first_packet->data(), absl::Span<uint32_t>());
|
||||
|
||||
auto second_packet = ++first_packet;
|
||||
ASSERT_NE(second_packet, reader->end());
|
||||
EXPECT_EQ(second_packet->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
EXPECT_EQ(second_packet->address(),
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
EXPECT_EQ(first_packet->data(), absl::Span<uint32_t>(data_words));
|
||||
|
||||
EXPECT_EQ(++first_packet, reader->end());
|
||||
|
|
|
|||
|
|
@ -4,17 +4,17 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, BlockType value) {
|
||||
std::ostream& operator<<(std::ostream& o, BlockType value) {
|
||||
switch (value) {
|
||||
case BlockType::CLB_IO_CLK:
|
||||
o << "CLB/IO/CLK";
|
||||
break;
|
||||
case BlockType::BLOCK_RAM:
|
||||
o << "Block RAM";
|
||||
break;
|
||||
case BlockType::CFG_CLB:
|
||||
o << "Config CLB";
|
||||
break;
|
||||
case BlockType::CLB_IO_CLK:
|
||||
o << "CLB/IO/CLK";
|
||||
break;
|
||||
case BlockType::BLOCK_RAM:
|
||||
o << "Block RAM";
|
||||
break;
|
||||
case BlockType::CFG_CLB:
|
||||
o << "Config CLB";
|
||||
break;
|
||||
}
|
||||
|
||||
return o;
|
||||
|
|
@ -27,7 +27,7 @@ std::ostream &operator<<(std::ostream &o, BlockType value) {
|
|||
namespace YAML {
|
||||
|
||||
Node convert<prjxray::xilinx::xc7series::BlockType>::encode(
|
||||
const prjxray::xilinx::xc7series::BlockType &rhs) {
|
||||
const prjxray::xilinx::xc7series::BlockType& rhs) {
|
||||
switch (rhs) {
|
||||
case prjxray::xilinx::xc7series::BlockType::CLB_IO_CLK:
|
||||
return Node("CLB_IO_CLK");
|
||||
|
|
@ -41,7 +41,8 @@ Node convert<prjxray::xilinx::xc7series::BlockType>::encode(
|
|||
}
|
||||
|
||||
bool YAML::convert<prjxray::xilinx::xc7series::BlockType>::decode(
|
||||
const Node &node, prjxray::xilinx::xc7series::BlockType &lhs) {
|
||||
const Node& node,
|
||||
prjxray::xilinx::xc7series::BlockType& lhs) {
|
||||
auto type_str = node.as<std::string>();
|
||||
|
||||
if (type_str == "CLB_IO_CLK") {
|
||||
|
|
@ -58,4 +59,4 @@ bool YAML::convert<prjxray::xilinx::xc7series::BlockType>::decode(
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace YAML;
|
||||
} // namespace YAML
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ TEST(BlockTypeTest, YamlDecode) {
|
|||
node.push_back("CLB_IO_CLK");
|
||||
|
||||
EXPECT_EQ(node[0].as<xc7series::BlockType>(),
|
||||
xc7series::BlockType::CFG_CLB);
|
||||
xc7series::BlockType::CFG_CLB);
|
||||
EXPECT_EQ(node[1].as<xc7series::BlockType>(),
|
||||
xc7series::BlockType::BLOCK_RAM);
|
||||
xc7series::BlockType::BLOCK_RAM);
|
||||
EXPECT_EQ(node[2].as<xc7series::BlockType>(),
|
||||
xc7series::BlockType::CLB_IO_CLK);
|
||||
xc7series::BlockType::CLB_IO_CLK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace xc7series = prjxray::xilinx::xc7series;
|
|||
namespace YAML {
|
||||
|
||||
Node convert<xc7series::ConfigurationFrameRange>::encode(
|
||||
const xc7series::ConfigurationFrameRange &rhs) {
|
||||
const xc7series::ConfigurationFrameRange& rhs) {
|
||||
Node node;
|
||||
node.SetTag("xilinx/xc7series/configuration_frame_range");
|
||||
node["begin"] = rhs.begin();
|
||||
|
|
@ -26,16 +26,16 @@ Node convert<xc7series::ConfigurationFrameRange>::encode(
|
|||
}
|
||||
|
||||
bool convert<xc7series::ConfigurationFrameRange>::decode(
|
||||
const Node &node,
|
||||
xc7series::ConfigurationFrameRange &lhs) {
|
||||
const Node& node,
|
||||
xc7series::ConfigurationFrameRange& lhs) {
|
||||
if (node.Tag() != "xilinx/xc7series/configuration_frame_range" ||
|
||||
!node["begin"] ||
|
||||
!node["end"]) return false;
|
||||
!node["begin"] || !node["end"])
|
||||
return false;
|
||||
|
||||
lhs = xc7series::ConfigurationFrameRange(
|
||||
node["begin"].as<xc7series::FrameAddress>(),
|
||||
node["end"].as<xc7series::FrameAddress>());
|
||||
node["begin"].as<xc7series::FrameAddress>(),
|
||||
node["end"].as<xc7series::FrameAddress>());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML;
|
||||
} // namespace YAML
|
||||
|
|
|
|||
|
|
@ -11,65 +11,68 @@ namespace xc7series {
|
|||
|
||||
std::pair<absl::Span<uint32_t>, absl::optional<ConfigurationPacket>>
|
||||
ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
|
||||
const ConfigurationPacket *previous_packet) {
|
||||
const ConfigurationPacket* previous_packet) {
|
||||
// Need at least one 32-bit word to have a valid packet header.
|
||||
if (words.size() < 1) return {words, {}};
|
||||
if (words.size() < 1)
|
||||
return {words, {}};
|
||||
|
||||
uint32_t header_type = bit_field_get(words[0], 31, 29);
|
||||
switch (header_type) {
|
||||
case 0x0:
|
||||
// Type 0 is emitted at the end of a configuration row when
|
||||
// BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES. These seem
|
||||
// to be padding that are interepreted as NOPs. Since Type 0
|
||||
// packets don't exist according to UG470 and they seem to be
|
||||
// zero-filled, just consume the bytes without generating a
|
||||
// packet.
|
||||
return {words.subspan(1), {}};
|
||||
case 0x1: {
|
||||
Opcode opcode = static_cast<Opcode>(
|
||||
bit_field_get(words[0], 28, 27));
|
||||
ConfigurationRegister address =
|
||||
static_cast<ConfigurationRegister>(
|
||||
bit_field_get(words[0], 26, 13));
|
||||
uint32_t data_word_count = bit_field_get(words[0], 10, 0);
|
||||
case 0x0:
|
||||
// Type 0 is emitted at the end of a configuration row
|
||||
// when BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES.
|
||||
// These seem to be padding that are interepreted as
|
||||
// NOPs. Since Type 0 packets don't exist according to
|
||||
// UG470 and they seem to be zero-filled, just consume
|
||||
// the bytes without generating a packet.
|
||||
return {words.subspan(1), {}};
|
||||
case 0x1: {
|
||||
Opcode opcode = static_cast<Opcode>(
|
||||
bit_field_get(words[0], 28, 27));
|
||||
ConfigurationRegister address =
|
||||
static_cast<ConfigurationRegister>(
|
||||
bit_field_get(words[0], 26, 13));
|
||||
uint32_t data_word_count =
|
||||
bit_field_get(words[0], 10, 0);
|
||||
|
||||
// If the full packet has not been received, return as though
|
||||
// no valid packet was found.
|
||||
if (data_word_count > words.size() - 1) {
|
||||
return {words, {}};
|
||||
// If the full packet has not been received, return as
|
||||
// though no valid packet was found.
|
||||
if (data_word_count > words.size() - 1) {
|
||||
return {words, {}};
|
||||
}
|
||||
|
||||
return {words.subspan(data_word_count + 1),
|
||||
{{header_type, opcode, address,
|
||||
words.subspan(1, data_word_count)}}};
|
||||
}
|
||||
case 0x2: {
|
||||
absl::optional<ConfigurationPacket> packet;
|
||||
Opcode opcode = static_cast<Opcode>(
|
||||
bit_field_get(words[0], 28, 27));
|
||||
uint32_t data_word_count =
|
||||
bit_field_get(words[0], 26, 0);
|
||||
|
||||
return {words.subspan(data_word_count+1),
|
||||
{{header_type, opcode, address,
|
||||
words.subspan(1, data_word_count)}}};
|
||||
}
|
||||
case 0x2: {
|
||||
absl::optional<ConfigurationPacket> packet;
|
||||
Opcode opcode = static_cast<Opcode>(
|
||||
bit_field_get(words[0], 28, 27));
|
||||
uint32_t data_word_count = bit_field_get(words[0], 26, 0);
|
||||
// If the full packet has not been received, return as
|
||||
// though no valid packet was found.
|
||||
if (data_word_count > words.size() - 1) {
|
||||
return {words, {}};
|
||||
}
|
||||
|
||||
// If the full packet has not been received, return as though
|
||||
// no valid packet was found.
|
||||
if (data_word_count > words.size() - 1) {
|
||||
return {words, {}};
|
||||
if (previous_packet) {
|
||||
packet = ConfigurationPacket(
|
||||
header_type, opcode,
|
||||
previous_packet->address(),
|
||||
words.subspan(1, data_word_count));
|
||||
}
|
||||
|
||||
return {words.subspan(data_word_count + 1), packet};
|
||||
}
|
||||
|
||||
if (previous_packet) {
|
||||
packet = ConfigurationPacket(
|
||||
header_type, opcode,
|
||||
previous_packet->address(),
|
||||
words.subspan(1, data_word_count));
|
||||
}
|
||||
|
||||
return {words.subspan(data_word_count + 1), packet};
|
||||
}
|
||||
default:
|
||||
return {{}, {}};
|
||||
default:
|
||||
return {{}, {}};
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet) {
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket& packet) {
|
||||
switch (packet.opcode()) {
|
||||
case ConfigurationPacket::Opcode::NOP:
|
||||
o << "[NOP]" << std::endl;
|
||||
|
|
@ -101,7 +104,7 @@ std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet) {
|
|||
o << std::setw(8) << std::hex;
|
||||
o << packet.data()[ii] << " ";
|
||||
|
||||
if ((ii+1) % 4 == 0) {
|
||||
if ((ii + 1) % 4 == 0) {
|
||||
o << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,26 @@ namespace xc7series = prjxray::xilinx::xc7series;
|
|||
|
||||
constexpr uint32_t kType1NOP = prjxray::bit_field_set<uint32_t>(0, 31, 29, 0x1);
|
||||
|
||||
constexpr uint32_t MakeType1(const int opcode, const int address,
|
||||
const int word_count) {
|
||||
constexpr uint32_t MakeType1(const int opcode,
|
||||
const int address,
|
||||
const int word_count) {
|
||||
return prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x1),
|
||||
28, 27, opcode),
|
||||
26, 13, address),
|
||||
10, 0, word_count);
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x1), 28, 27,
|
||||
opcode),
|
||||
26, 13, address),
|
||||
10, 0, word_count);
|
||||
}
|
||||
|
||||
constexpr uint32_t MakeType2(const int opcode, const int word_count) {
|
||||
return prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x2),
|
||||
28, 27, opcode),
|
||||
26, 0, word_count);
|
||||
prjxray::bit_field_set<uint32_t>(
|
||||
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x2), 28, 27,
|
||||
opcode),
|
||||
26, 0, word_count);
|
||||
}
|
||||
|
||||
|
||||
TEST(ConfigPacket, InitWithZeroBytes) {
|
||||
auto packet = xc7series::ConfigurationPacket::InitWithWords({});
|
||||
|
||||
|
|
@ -44,9 +44,9 @@ TEST(ConfigPacket, InitWithType1Nop) {
|
|||
EXPECT_EQ(packet.first, absl::Span<uint32_t>());
|
||||
ASSERT_TRUE(packet.second);
|
||||
EXPECT_EQ(packet.second->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::NOP);
|
||||
xc7series::ConfigurationPacket::Opcode::NOP);
|
||||
EXPECT_EQ(packet.second->address(),
|
||||
xc7series::ConfigurationRegister::CRC);
|
||||
xc7series::ConfigurationRegister::CRC);
|
||||
EXPECT_EQ(packet.second->data(), absl::Span<uint32_t>());
|
||||
}
|
||||
|
||||
|
|
@ -57,9 +57,9 @@ TEST(ConfigPacket, InitWithType1Read) {
|
|||
EXPECT_EQ(packet.first, absl::Span<uint32_t>());
|
||||
ASSERT_TRUE(packet.second);
|
||||
EXPECT_EQ(packet.second->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
EXPECT_EQ(packet.second->address(),
|
||||
xc7series::ConfigurationRegister::FDRI);
|
||||
xc7series::ConfigurationRegister::FDRI);
|
||||
EXPECT_EQ(packet.second->data(), word_span.subspan(1));
|
||||
}
|
||||
|
||||
|
|
@ -70,9 +70,9 @@ TEST(ConfigPacket, InitWithType1Write) {
|
|||
EXPECT_EQ(packet.first, absl::Span<uint32_t>());
|
||||
ASSERT_TRUE(packet.second);
|
||||
EXPECT_EQ(packet.second->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::Write);
|
||||
xc7series::ConfigurationPacket::Opcode::Write);
|
||||
EXPECT_EQ(packet.second->address(),
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
xc7series::ConfigurationRegister::FDRO);
|
||||
EXPECT_EQ(packet.second->data(), word_span.subspan(1));
|
||||
}
|
||||
|
||||
|
|
@ -86,20 +86,19 @@ TEST(ConfigPacket, InitWithType2WithoutPreviousPacketFails) {
|
|||
|
||||
TEST(ConfigPacket, InitWithType2WithPreviousPacket) {
|
||||
xc7series::ConfigurationPacket previous_packet(
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Read,
|
||||
xc7series::ConfigurationRegister::MFWR,
|
||||
absl::Span<uint32_t>());
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Read,
|
||||
xc7series::ConfigurationRegister::MFWR, absl::Span<uint32_t>());
|
||||
std::vector<uint32_t> words{
|
||||
MakeType2(0x01, 12), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
MakeType2(0x01, 12), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
absl::Span<uint32_t> word_span(words);
|
||||
auto packet = xc7series::ConfigurationPacket::InitWithWords(
|
||||
word_span, &previous_packet);
|
||||
word_span, &previous_packet);
|
||||
EXPECT_EQ(packet.first, absl::Span<uint32_t>());
|
||||
ASSERT_TRUE(packet.second);
|
||||
EXPECT_EQ(packet.second->opcode(),
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
xc7series::ConfigurationPacket::Opcode::Read);
|
||||
EXPECT_EQ(packet.second->address(),
|
||||
xc7series::ConfigurationRegister::MFWR);
|
||||
xc7series::ConfigurationRegister::MFWR);
|
||||
EXPECT_EQ(packet.second->data(), word_span.subspan(1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value) {
|
||||
std::ostream& operator<<(std::ostream& o, const ConfigurationRegister& value) {
|
||||
switch (value) {
|
||||
case ConfigurationRegister::CRC:
|
||||
return o << "CRC";
|
||||
|
|
@ -51,7 +51,6 @@ std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace xc7series = prjxray::xilinx::xc7series;
|
|||
TEST(ConfigurationTest, ConstructFromPacketsWithSingleFrame) {
|
||||
std::vector<xc7series::ConfigurationFrameRange> test_part_ranges;
|
||||
test_part_ranges.push_back(
|
||||
xc7series::ConfigurationFrameRange(0x4567, 0x4568));
|
||||
xc7series::ConfigurationFrameRange(0x4567, 0x4568));
|
||||
|
||||
xc7series::Part test_part(0x1234, test_part_ranges);
|
||||
|
||||
|
|
@ -25,33 +25,34 @@ TEST(ConfigurationTest, ConstructFromPacketsWithSingleFrame) {
|
|||
std::vector<uint32_t> frame(101, 0xAA);
|
||||
|
||||
std::vector<xc7series::ConfigurationPacket> packets{
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::IDCODE,
|
||||
absl::MakeSpan(idcode),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FAR,
|
||||
absl::MakeSpan(frame_address),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::CMD,
|
||||
absl::MakeSpan(cmd),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FDRI,
|
||||
absl::MakeSpan(frame),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::IDCODE,
|
||||
absl::MakeSpan(idcode),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FAR,
|
||||
absl::MakeSpan(frame_address),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::CMD,
|
||||
absl::MakeSpan(cmd),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FDRI,
|
||||
absl::MakeSpan(frame),
|
||||
},
|
||||
};
|
||||
|
||||
auto test_config = xc7series::Configuration::InitWithPackets(test_part, packets);
|
||||
auto test_config =
|
||||
xc7series::Configuration::InitWithPackets(test_part, packets);
|
||||
ASSERT_TRUE(test_config);
|
||||
|
||||
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
|
||||
|
|
@ -62,9 +63,9 @@ TEST(ConfigurationTest, ConstructFromPacketsWithSingleFrame) {
|
|||
TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) {
|
||||
std::vector<xc7series::ConfigurationFrameRange> test_part_ranges;
|
||||
test_part_ranges.push_back(
|
||||
xc7series::ConfigurationFrameRange(0x4560, 0x4570));
|
||||
xc7series::ConfigurationFrameRange(0x4560, 0x4570));
|
||||
test_part_ranges.push_back(
|
||||
xc7series::ConfigurationFrameRange(0x4580, 0x4590));
|
||||
xc7series::ConfigurationFrameRange(0x4580, 0x4590));
|
||||
|
||||
xc7series::Part test_part(0x1234, test_part_ranges);
|
||||
|
||||
|
|
@ -75,88 +76,99 @@ TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) {
|
|||
std::fill_n(frame.begin() + 101, 101, 0xBB);
|
||||
|
||||
std::vector<xc7series::ConfigurationPacket> packets{
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::IDCODE,
|
||||
absl::MakeSpan(idcode),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FAR,
|
||||
absl::MakeSpan(frame_address),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::CMD,
|
||||
absl::MakeSpan(cmd),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FDRI,
|
||||
absl::MakeSpan(frame),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::IDCODE,
|
||||
absl::MakeSpan(idcode),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FAR,
|
||||
absl::MakeSpan(frame_address),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::CMD,
|
||||
absl::MakeSpan(cmd),
|
||||
},
|
||||
{
|
||||
static_cast<unsigned int>(0x1),
|
||||
xc7series::ConfigurationPacket::Opcode::Write,
|
||||
xc7series::ConfigurationRegister::FDRI,
|
||||
absl::MakeSpan(frame),
|
||||
},
|
||||
};
|
||||
|
||||
auto test_config = xc7series::Configuration::InitWithPackets(test_part, packets);
|
||||
auto test_config =
|
||||
xc7series::Configuration::InitWithPackets(test_part, packets);
|
||||
ASSERT_TRUE(test_config);
|
||||
|
||||
absl::Span<uint32_t> frame_span(frame);
|
||||
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
|
||||
EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(2));
|
||||
EXPECT_EQ(test_config->frames().at(0x456F), std::vector<uint32_t>(101, 0xAA));
|
||||
EXPECT_EQ(test_config->frames().at(0x4580), std::vector<uint32_t>(101, 0xBB));
|
||||
EXPECT_EQ(test_config->frames().at(0x456F),
|
||||
std::vector<uint32_t>(101, 0xAA));
|
||||
EXPECT_EQ(test_config->frames().at(0x4580),
|
||||
std::vector<uint32_t>(101, 0xBB));
|
||||
}
|
||||
|
||||
TEST(ConfigurationTest, DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations) {
|
||||
TEST(ConfigurationTest,
|
||||
DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations) {
|
||||
auto part = xc7series::Part::FromFile("configuration_test.yaml");
|
||||
ASSERT_TRUE(part);
|
||||
|
||||
auto debug_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.debug.bit");
|
||||
"configuration_test.debug.bit");
|
||||
ASSERT_TRUE(debug_bitstream);
|
||||
|
||||
auto debug_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
debug_bitstream->as_bytes());
|
||||
debug_bitstream->as_bytes());
|
||||
ASSERT_TRUE(debug_reader);
|
||||
|
||||
auto debug_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *debug_reader);
|
||||
auto debug_configuration =
|
||||
xc7series::Configuration::InitWithPackets(*part, *debug_reader);
|
||||
ASSERT_TRUE(debug_configuration);
|
||||
|
||||
auto perframecrc_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.perframecrc.bit");
|
||||
"configuration_test.perframecrc.bit");
|
||||
ASSERT_TRUE(perframecrc_bitstream);
|
||||
|
||||
auto perframecrc_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
perframecrc_bitstream->as_bytes());
|
||||
perframecrc_bitstream->as_bytes());
|
||||
ASSERT_TRUE(perframecrc_reader);
|
||||
|
||||
auto perframecrc_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *perframecrc_reader);
|
||||
auto perframecrc_configuration =
|
||||
xc7series::Configuration::InitWithPackets(*part,
|
||||
*perframecrc_reader);
|
||||
ASSERT_TRUE(perframecrc_configuration);
|
||||
|
||||
for (auto debug_frame : debug_configuration->frames()) {
|
||||
auto perframecrc_frame = perframecrc_configuration->frames().find(debug_frame.first);
|
||||
if (perframecrc_frame == perframecrc_configuration->frames().end()) {
|
||||
ADD_FAILURE() << debug_frame.first << ": missing in perframecrc bitstream";
|
||||
auto perframecrc_frame =
|
||||
perframecrc_configuration->frames().find(debug_frame.first);
|
||||
if (perframecrc_frame ==
|
||||
perframecrc_configuration->frames().end()) {
|
||||
ADD_FAILURE() << debug_frame.first
|
||||
<< ": missing in perframecrc bitstream";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 101; ++ii) {
|
||||
EXPECT_EQ(perframecrc_frame->second[ii], debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
EXPECT_EQ(perframecrc_frame->second[ii],
|
||||
debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto perframecrc_frame : perframecrc_configuration->frames()) {
|
||||
auto debug_frame = debug_configuration->frames().find(perframecrc_frame.first);
|
||||
auto debug_frame =
|
||||
debug_configuration->frames().find(perframecrc_frame.first);
|
||||
if (debug_frame == debug_configuration->frames().end()) {
|
||||
ADD_FAILURE() << perframecrc_frame.first
|
||||
<< ": unexpectedly present in perframecrc bitstream";
|
||||
<< ": unexpectedly present in "
|
||||
"perframecrc bitstream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,47 +178,52 @@ TEST(ConfigurationTest, DebugAndNormalBitstreamsProduceEqualConfigurations) {
|
|||
ASSERT_TRUE(part);
|
||||
|
||||
auto debug_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.debug.bit");
|
||||
"configuration_test.debug.bit");
|
||||
ASSERT_TRUE(debug_bitstream);
|
||||
|
||||
auto debug_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
debug_bitstream->as_bytes());
|
||||
debug_bitstream->as_bytes());
|
||||
ASSERT_TRUE(debug_reader);
|
||||
|
||||
auto debug_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *debug_reader);
|
||||
auto debug_configuration =
|
||||
xc7series::Configuration::InitWithPackets(*part, *debug_reader);
|
||||
ASSERT_TRUE(debug_configuration);
|
||||
|
||||
auto normal_bitstream = prjxray::MemoryMappedFile::InitWithFile(
|
||||
"configuration_test.bit");
|
||||
auto normal_bitstream =
|
||||
prjxray::MemoryMappedFile::InitWithFile("configuration_test.bit");
|
||||
ASSERT_TRUE(normal_bitstream);
|
||||
|
||||
auto normal_reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
normal_bitstream->as_bytes());
|
||||
normal_bitstream->as_bytes());
|
||||
ASSERT_TRUE(normal_reader);
|
||||
|
||||
auto normal_configuration = xc7series::Configuration::InitWithPackets(
|
||||
*part, *normal_reader);
|
||||
auto normal_configuration =
|
||||
xc7series::Configuration::InitWithPackets(*part, *normal_reader);
|
||||
ASSERT_TRUE(normal_configuration);
|
||||
|
||||
for (auto debug_frame : debug_configuration->frames()) {
|
||||
auto normal_frame = normal_configuration->frames().find(debug_frame.first);
|
||||
auto normal_frame =
|
||||
normal_configuration->frames().find(debug_frame.first);
|
||||
if (normal_frame == normal_configuration->frames().end()) {
|
||||
ADD_FAILURE() << debug_frame.first << ": missing in normal bitstream";
|
||||
ADD_FAILURE() << debug_frame.first
|
||||
<< ": missing in normal bitstream";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < 101; ++ii) {
|
||||
EXPECT_EQ(normal_frame->second[ii], debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
EXPECT_EQ(normal_frame->second[ii],
|
||||
debug_frame.second[ii])
|
||||
<< debug_frame.first << ": word " << ii;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto normal_frame : normal_configuration->frames()) {
|
||||
auto debug_frame = debug_configuration->frames().find(normal_frame.first);
|
||||
auto debug_frame =
|
||||
debug_configuration->frames().find(normal_frame.first);
|
||||
if (debug_frame == debug_configuration->frames().end()) {
|
||||
ADD_FAILURE() << normal_frame.first
|
||||
<< ": unexpectedly present in normal bitstream";
|
||||
ADD_FAILURE()
|
||||
<< normal_frame.first
|
||||
<< ": unexpectedly present in normal bitstream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
FrameAddress::FrameAddress(BlockType block_type, bool is_bottom_half_rows,
|
||||
uint8_t row, uint16_t column, uint8_t minor) {
|
||||
FrameAddress::FrameAddress(BlockType block_type,
|
||||
bool is_bottom_half_rows,
|
||||
uint8_t row,
|
||||
uint16_t column,
|
||||
uint8_t minor) {
|
||||
address_ = bit_field_set(0, 25, 23, block_type);
|
||||
address_ = bit_field_set(address_, 22, 22, is_bottom_half_rows);
|
||||
address_ = bit_field_set(address_, 21, 17, row);
|
||||
|
|
@ -37,23 +40,16 @@ uint8_t FrameAddress::minor_address() const {
|
|||
return bit_field_get(address_, 6, 0);
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr) {
|
||||
o << "["
|
||||
<< std::hex << std::showbase << std::setw(10)
|
||||
<< static_cast<uint32_t>(addr)
|
||||
<< "] "
|
||||
<< (addr.is_bottom_half_rows() ? "BOTTOM" : "TOP")
|
||||
<< " Row="
|
||||
<< std::setw(2) << std::dec
|
||||
std::ostream& operator<<(std::ostream& o, const FrameAddress& addr) {
|
||||
o << "[" << std::hex << std::showbase << std::setw(10)
|
||||
<< static_cast<uint32_t>(addr) << "] "
|
||||
<< (addr.is_bottom_half_rows() ? "BOTTOM" : "TOP")
|
||||
<< " Row=" << std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(addr.row_address())
|
||||
<< " Column="
|
||||
<< std::setw(2) << std::dec
|
||||
<< addr.column_address()
|
||||
<< " Minor="
|
||||
<< std::setw(2) << std::dec
|
||||
<< " Column=" << std::setw(2) << std::dec << addr.column_address()
|
||||
<< " Minor=" << std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(addr.minor_address())
|
||||
<< " Type="
|
||||
<< addr.block_type();
|
||||
<< " Type=" << addr.block_type();
|
||||
return o;
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +62,7 @@ namespace YAML {
|
|||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
Node convert<xc7series::FrameAddress>::encode(
|
||||
const xc7series::FrameAddress &rhs) {
|
||||
const xc7series::FrameAddress& rhs) {
|
||||
Node node;
|
||||
node.SetTag("xilinx/xc7series/frame_address");
|
||||
node["block_type"] = rhs.block_type();
|
||||
|
|
@ -77,15 +73,13 @@ Node convert<xc7series::FrameAddress>::encode(
|
|||
return node;
|
||||
}
|
||||
|
||||
bool convert<xc7series::FrameAddress>::decode(
|
||||
const Node &node, xc7series::FrameAddress &lhs) {
|
||||
bool convert<xc7series::FrameAddress>::decode(const Node& node,
|
||||
xc7series::FrameAddress& lhs) {
|
||||
if (!(node.Tag() == "xilinx/xc7series/frame_address" ||
|
||||
node.Tag() == "xilinx/xc7series/configuration_frame_address") ||
|
||||
!node["block_type"] ||
|
||||
!node["row_half"] ||
|
||||
!node["row"] ||
|
||||
!node["column"] ||
|
||||
!node["minor"]) return false;
|
||||
!node["block_type"] || !node["row_half"] || !node["row"] ||
|
||||
!node["column"] || !node["minor"])
|
||||
return false;
|
||||
|
||||
bool row_half;
|
||||
if (node["row_half"].as<std::string>() == "top") {
|
||||
|
|
@ -97,12 +91,10 @@ bool convert<xc7series::FrameAddress>::decode(
|
|||
}
|
||||
|
||||
lhs = prjxray::xilinx::xc7series::FrameAddress(
|
||||
node["block_type"].as<xc7series::BlockType>(),
|
||||
row_half,
|
||||
node["row"].as<unsigned int>(),
|
||||
node["column"].as<unsigned int>(),
|
||||
node["minor"].as<unsigned int>());
|
||||
node["block_type"].as<xc7series::BlockType>(), row_half,
|
||||
node["row"].as<unsigned int>(), node["column"].as<unsigned int>(),
|
||||
node["minor"].as<unsigned int>());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML;
|
||||
} // namespace YAML
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
TEST(FrameAddressTest, YamlEncode) {
|
||||
xc7series::FrameAddress address(xc7series::BlockType::BLOCK_RAM,
|
||||
false, 10, 0, 5);
|
||||
xc7series::FrameAddress address(xc7series::BlockType::BLOCK_RAM, false,
|
||||
10, 0, 5);
|
||||
|
||||
YAML::Node node(address);
|
||||
|
||||
|
|
@ -27,8 +27,7 @@ TEST(FrameAddressTest, YamlDecode) {
|
|||
node["column"] = "5";
|
||||
node["minor"] = "11";
|
||||
|
||||
xc7series::FrameAddress address =
|
||||
node.as<xc7series::FrameAddress>();
|
||||
xc7series::FrameAddress address = node.as<xc7series::FrameAddress>();
|
||||
EXPECT_EQ(address.block_type(), xc7series::BlockType::BLOCK_RAM);
|
||||
EXPECT_TRUE(address.is_bottom_half_rows());
|
||||
EXPECT_EQ(address.row_address(), 0);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace prjxray {
|
|||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
absl::optional<Part> Part::FromFile(const std::string &path) {
|
||||
absl::optional<Part> Part::FromFile(const std::string& path) {
|
||||
try {
|
||||
YAML::Node yaml = YAML::LoadFile(path);
|
||||
return yaml.as<Part>();
|
||||
|
|
@ -16,8 +16,8 @@ absl::optional<Part> Part::FromFile(const std::string &path) {
|
|||
}
|
||||
}
|
||||
|
||||
absl::optional<FrameAddress>
|
||||
Part::GetNextFrameAddress(FrameAddress address) const {
|
||||
absl::optional<FrameAddress> Part::GetNextFrameAddress(
|
||||
FrameAddress address) const {
|
||||
// Start with the next linear address.
|
||||
FrameAddress target_address(address + 1);
|
||||
|
||||
|
|
@ -27,8 +27,7 @@ Part::GetNextFrameAddress(FrameAddress address) const {
|
|||
// address.
|
||||
absl::optional<FrameAddress> closest_address;
|
||||
int32_t closest_distance;
|
||||
for (auto iter = frame_ranges_.begin();
|
||||
iter != frame_ranges_.end();
|
||||
for (auto iter = frame_ranges_.begin(); iter != frame_ranges_.end();
|
||||
++iter) {
|
||||
if (iter->Contains(target_address)) {
|
||||
return target_address;
|
||||
|
|
@ -36,8 +35,7 @@ Part::GetNextFrameAddress(FrameAddress address) const {
|
|||
|
||||
int32_t distance = iter->begin() - target_address;
|
||||
if (distance > 0 &&
|
||||
(!closest_address ||
|
||||
distance < closest_distance)) {
|
||||
(!closest_address || distance < closest_distance)) {
|
||||
closest_address = iter->begin();
|
||||
closest_distance = distance;
|
||||
}
|
||||
|
|
@ -54,7 +52,7 @@ namespace xc7series = prjxray::xilinx::xc7series;
|
|||
|
||||
namespace YAML {
|
||||
|
||||
Node convert<xc7series::Part>::encode(const xc7series::Part &rhs) {
|
||||
Node convert<xc7series::Part>::encode(const xc7series::Part& rhs) {
|
||||
Node node;
|
||||
node.SetTag("xilinx/xc7series/part");
|
||||
|
||||
|
|
@ -66,17 +64,16 @@ Node convert<xc7series::Part>::encode(const xc7series::Part &rhs) {
|
|||
return node;
|
||||
}
|
||||
|
||||
bool convert<xc7series::Part>::decode(const Node &node, xc7series::Part &lhs) {
|
||||
if (node.Tag() != "xilinx/xc7series/part" ||
|
||||
!node["idcode"] ||
|
||||
!node["configuration_ranges"]) return false;
|
||||
bool convert<xc7series::Part>::decode(const Node& node, xc7series::Part& lhs) {
|
||||
if (node.Tag() != "xilinx/xc7series/part" || !node["idcode"] ||
|
||||
!node["configuration_ranges"])
|
||||
return false;
|
||||
|
||||
lhs = xc7series::Part(
|
||||
node["idcode"].as<uint32_t>(),
|
||||
node["configuration_ranges"].as<
|
||||
std::vector<xc7series::ConfigurationFrameRange>>());
|
||||
node["idcode"].as<uint32_t>(),
|
||||
node["configuration_ranges"]
|
||||
.as<std::vector<xc7series::ConfigurationFrameRange>>());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML;
|
||||
|
||||
} // namespace YAML
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
autopep8
|
||||
182
tools/bitread.cc
182
tools/bitread.cc
|
|
@ -1,10 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <absl/strings/numbers.h>
|
||||
|
|
@ -19,20 +19,27 @@
|
|||
|
||||
DEFINE_bool(c, false, "output '*' for repeating patterns");
|
||||
DEFINE_bool(C, false, "do not ignore the checksum in each frame");
|
||||
DEFINE_int32(f, -1, "only dump the specified frame (might be used more than once)");
|
||||
DEFINE_string(F, "", "<first_frame_address>:<last_frame_address> only dump frame in the specified range");
|
||||
DEFINE_int32(f,
|
||||
-1,
|
||||
"only dump the specified frame (might be used more than once)");
|
||||
DEFINE_string(F,
|
||||
"",
|
||||
"<first_frame_address>:<last_frame_address> only dump frame in "
|
||||
"the specified range");
|
||||
DEFINE_string(o, "", "write machine-readable output file with config frames");
|
||||
DEFINE_bool(p, false, "output a binary netpgm image");
|
||||
DEFINE_bool(x, false, "use format 'bit_%%08x_%%03d_%%02d_t%%d_h%%d_r%%d_c%%d_m%%d'\n"
|
||||
"The fields have the following meaning:\n"
|
||||
" - complete 32 bit hex frame id\n"
|
||||
" - word index with that frame (decimal)\n"
|
||||
" - bit index with that word (decimal)\n"
|
||||
" - decoded frame type from frame id\n"
|
||||
" - decoded top/botttom from frame id (top=0)\n"
|
||||
" - decoded row address from frame id\n"
|
||||
" - decoded column address from frame id\n"
|
||||
" - decoded minor address from frame id\n");
|
||||
DEFINE_bool(x,
|
||||
false,
|
||||
"use format 'bit_%%08x_%%03d_%%02d_t%%d_h%%d_r%%d_c%%d_m%%d'\n"
|
||||
"The fields have the following meaning:\n"
|
||||
" - complete 32 bit hex frame id\n"
|
||||
" - word index with that frame (decimal)\n"
|
||||
" - bit index with that word (decimal)\n"
|
||||
" - decoded frame type from frame id\n"
|
||||
" - decoded top/botttom from frame id (top=0)\n"
|
||||
" - decoded row address from frame id\n"
|
||||
" - decoded column address from frame id\n"
|
||||
" - decoded minor address from frame id\n");
|
||||
DEFINE_bool(y, false, "use format 'bit_%%08x_%%03d_%%02d'");
|
||||
DEFINE_bool(z, false, "skip zero frames (frames with all bits cleared) in o");
|
||||
DEFINE_string(part_file, "", "YAML file describing a Xilinx 7-Series part");
|
||||
|
|
@ -44,9 +51,9 @@ uint32_t frame_range_begin = 0, frame_range_end = 0;
|
|||
|
||||
std::vector<uint32_t> zero_frame(101);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main(int argc, char** argv) {
|
||||
gflags::SetUsageMessage(
|
||||
absl::StrCat("Usage: ", argv[0], " [options] [bitfile]"));
|
||||
absl::StrCat("Usage: ", argv[0], " [options] [bitfile]"));
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
auto part = xc7series::Part::FromFile(FLAGS_part_file);
|
||||
|
|
@ -60,7 +67,8 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (!FLAGS_F.empty()) {
|
||||
std::pair<std::string, std::string> p = absl::StrSplit(FLAGS_F, ":");
|
||||
std::pair<std::string, std::string> p =
|
||||
absl::StrSplit(FLAGS_F, ":");
|
||||
frame_range_begin = strtol(p.first.c_str(), nullptr, 0);
|
||||
frame_range_end = strtol(p.second.c_str(), nullptr, 0) + 1;
|
||||
}
|
||||
|
|
@ -68,59 +76,61 @@ int main(int argc, char **argv) {
|
|||
absl::optional<xc7series::BitstreamReader> reader;
|
||||
if (argc == 2) {
|
||||
auto in_file_name = argv[1];
|
||||
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
auto in_file =
|
||||
prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
if (!in_file) {
|
||||
std::cerr << "Can't open input file '" << in_file_name
|
||||
<< "' for reading!" << std::endl;
|
||||
<< "' for reading!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Bitstream size: " << in_file->size() << " bytes"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
|
||||
reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
in_file->as_bytes());
|
||||
} else {
|
||||
std::vector<uint8_t> bitdata;
|
||||
while (1) {
|
||||
int c = getchar();
|
||||
if (c == EOF) break;
|
||||
if (c == EOF)
|
||||
break;
|
||||
bitdata.push_back(c);
|
||||
}
|
||||
|
||||
std::cout << "Bitstream size: " << bitdata.size() << " bytes"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
|
||||
reader = xc7series::BitstreamReader::InitWithBytes(bitdata);
|
||||
}
|
||||
|
||||
if (!reader) {
|
||||
std::cerr << "Bitstream does not appear to be a Xilinx "
|
||||
<< "7-series bitstream!" << std::endl;
|
||||
<< "7-series bitstream!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Config size: " << reader->words().size()
|
||||
<< " words" << std::endl;
|
||||
std::cout << "Config size: " << reader->words().size() << " words"
|
||||
<< std::endl;
|
||||
|
||||
auto config = xc7series::Configuration::InitWithPackets(*part, *reader);
|
||||
if (!config) {
|
||||
std::cerr << "Bitstream does not appear to be for this part"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Number of configuration frames: "
|
||||
<< config->frames().size() << std::endl;
|
||||
<< config->frames().size() << std::endl;
|
||||
|
||||
FILE *f = stdout;
|
||||
FILE* f = stdout;
|
||||
|
||||
if (!FLAGS_o.empty())
|
||||
{
|
||||
if (!FLAGS_o.empty()) {
|
||||
f = fopen(FLAGS_o.c_str(), "w");
|
||||
|
||||
if (f == nullptr) {
|
||||
printf("Can't open output file '%s' for writing!\n", FLAGS_o.c_str());
|
||||
printf("Can't open output file '%s' for writing!\n",
|
||||
FLAGS_o.c_str());
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -130,8 +140,7 @@ int main(int argc, char **argv) {
|
|||
std::vector<std::vector<bool>> pgmdata;
|
||||
std::vector<int> pgmsep;
|
||||
|
||||
for (auto &it : config->frames())
|
||||
{
|
||||
for (auto& it : config->frames()) {
|
||||
if (FLAGS_z && it.second == zero_frame)
|
||||
continue;
|
||||
|
||||
|
|
@ -139,67 +148,95 @@ int main(int argc, char **argv) {
|
|||
continue;
|
||||
|
||||
if (frame_range_begin != frame_range_end &&
|
||||
(it.first < frame_range_begin || frame_range_end <= it.first))
|
||||
(it.first < frame_range_begin ||
|
||||
frame_range_end <= it.first))
|
||||
continue;
|
||||
|
||||
if (FLAGS_o.empty())
|
||||
printf("Frame 0x%08x (Type=%d Top=%d Row=%d Column=%d Minor=%d):\n",
|
||||
static_cast<uint32_t>(it.first), static_cast<unsigned int>(it.first.block_type()),
|
||||
it.first.is_bottom_half_rows() ? 1 : 0,
|
||||
it.first.row_address(), it.first.column_address(), it.first.minor_address());
|
||||
printf(
|
||||
"Frame 0x%08x (Type=%d Top=%d Row=%d Column=%d "
|
||||
"Minor=%d):\n",
|
||||
static_cast<uint32_t>(it.first),
|
||||
static_cast<unsigned int>(it.first.block_type()),
|
||||
it.first.is_bottom_half_rows() ? 1 : 0,
|
||||
it.first.row_address(), it.first.column_address(),
|
||||
it.first.minor_address());
|
||||
|
||||
if (FLAGS_p)
|
||||
{
|
||||
if (FLAGS_p) {
|
||||
if (it.first.minor_address() == 0 && !pgmdata.empty())
|
||||
pgmsep.push_back(pgmdata.size());
|
||||
|
||||
pgmdata.push_back(std::vector<bool>());
|
||||
|
||||
for (int i = 0; i < 101; i++)
|
||||
for (int k = 0; k < 32; k++)
|
||||
pgmdata.back().push_back((it.second.at(i) & (1 << k)) != 0);
|
||||
}
|
||||
else
|
||||
if (FLAGS_x || FLAGS_y)
|
||||
{
|
||||
for (int k = 0; k < 32; k++)
|
||||
pgmdata.back().push_back(
|
||||
(it.second.at(i) & (1 << k)) != 0);
|
||||
} else if (FLAGS_x || FLAGS_y) {
|
||||
for (int i = 0; i < 101; i++)
|
||||
for (int k = 0; k < 32; k++)
|
||||
if ((i != 50 || k > 12 || FLAGS_C) && ((it.second.at(i) & (1 << k)) != 0)) {
|
||||
if (FLAGS_x)
|
||||
fprintf(f, "bit_%08x_%03d_%02d_t%d_h%d_r%d_c%d_m%d\n",
|
||||
static_cast<uint32_t>(it.first),
|
||||
i, k,
|
||||
static_cast<unsigned int>(it.first.block_type()),
|
||||
it.first.is_bottom_half_rows() ? 1 : 0,
|
||||
it.first.row_address(), it.first.column_address(), it.first.minor_address());
|
||||
else
|
||||
fprintf(f, "bit_%08x_%03d_%02d\n", static_cast<uint32_t>(it.first), i, k);
|
||||
}
|
||||
for (int k = 0; k < 32; k++)
|
||||
if ((i != 50 || k > 12 || FLAGS_C) &&
|
||||
((it.second.at(i) & (1 << k)) !=
|
||||
0)) {
|
||||
if (FLAGS_x)
|
||||
fprintf(
|
||||
f,
|
||||
"bit_%08x_%03d_%"
|
||||
"02d_t%d_h%d_r%d_c%"
|
||||
"d_m%d\n",
|
||||
static_cast<
|
||||
uint32_t>(
|
||||
it.first),
|
||||
i, k,
|
||||
static_cast<
|
||||
unsigned int>(
|
||||
it.first
|
||||
.block_type()),
|
||||
it.first.is_bottom_half_rows()
|
||||
? 1
|
||||
: 0,
|
||||
it.first
|
||||
.row_address(),
|
||||
it.first
|
||||
.column_address(),
|
||||
it.first
|
||||
.minor_address());
|
||||
else
|
||||
fprintf(f,
|
||||
"bit_%08x_%03d_"
|
||||
"%02d\n",
|
||||
static_cast<
|
||||
uint32_t>(
|
||||
it.first),
|
||||
i, k);
|
||||
}
|
||||
if (FLAGS_o.empty())
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!FLAGS_o.empty())
|
||||
fprintf(f, ".frame 0x%08x\n", static_cast<uint32_t>(it.first));
|
||||
fprintf(f, ".frame 0x%08x\n",
|
||||
static_cast<uint32_t>(it.first));
|
||||
|
||||
for (int i = 0; i < 101; i++)
|
||||
fprintf(f, "%08x%s", it.second.at(i) & ((i != 50 || FLAGS_C) ? 0xffffffff : 0xffffe000), (i % 6) == 5 ? "\n" : " ");
|
||||
fprintf(f, "%08x%s",
|
||||
it.second.at(i) &
|
||||
((i != 50 || FLAGS_C) ? 0xffffffff
|
||||
: 0xffffe000),
|
||||
(i % 6) == 5 ? "\n" : " ");
|
||||
fprintf(f, "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAGS_p)
|
||||
{
|
||||
if (FLAGS_p) {
|
||||
int width = pgmdata.size() + pgmsep.size();
|
||||
int height = 101*32+100;
|
||||
int height = 101 * 32 + 100;
|
||||
fprintf(f, "P5 %d %d 15\n", width, height);
|
||||
|
||||
for (int y = 0, bit = 101*32-1; y < height; y++, bit--)
|
||||
{
|
||||
for (int x = 0, frame = 0, sep = 0; x < width; x++, frame++)
|
||||
{
|
||||
if (sep < int(pgmsep.size()) && frame == pgmsep.at(sep)) {
|
||||
for (int y = 0, bit = 101 * 32 - 1; y < height; y++, bit--) {
|
||||
for (int x = 0, frame = 0, sep = 0; x < width;
|
||||
x++, frame++) {
|
||||
if (sep < int(pgmsep.size()) &&
|
||||
frame == pgmsep.at(sep)) {
|
||||
fputc(8, f);
|
||||
x++, sep++;
|
||||
}
|
||||
|
|
@ -221,4 +258,3 @@ int main(int argc, char **argv) {
|
|||
printf("DONE\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,15 +11,14 @@ namespace xc7series = prjxray::xilinx::xc7series;
|
|||
|
||||
struct Action {
|
||||
std::string name;
|
||||
std::function<int(int, char*[])> handler;
|
||||
std::function<int(int, char* [])> handler;
|
||||
};
|
||||
|
||||
int ListConfigPackets(int argc, char *argv[]) {
|
||||
int ListConfigPackets(int argc, char* argv[]) {
|
||||
if (argc < 1) {
|
||||
std::cerr << "ERROR: no input specified" << std::endl;
|
||||
std::cerr << "Usage: " << argv[0]
|
||||
<< "list_config_packets <bit_file>"
|
||||
<< std::endl;
|
||||
<< "list_config_packets <bit_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -27,15 +26,14 @@ int ListConfigPackets(int argc, char *argv[]) {
|
|||
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
if (!in_file) {
|
||||
std::cerr << "Unable to open bit file: " << in_file_name
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
auto reader =
|
||||
xc7series::BitstreamReader::InitWithBytes(in_file->as_bytes());
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
std::cerr << "Input doesn't look like a bitstream" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -46,12 +44,12 @@ int ListConfigPackets(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
|
||||
int DumpDebugbitstreamFrameAddresses(int argc, char* argv[]) {
|
||||
if (argc < 1) {
|
||||
std::cerr << "ERROR: no input specified" << std::endl;
|
||||
std::cerr << "Usage: " << argv[0]
|
||||
<< "dump_debugbitstream_frame_addresses <bit_file>"
|
||||
<< std::endl;
|
||||
<< "dump_debugbitstream_frame_addresses <bit_file>"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -59,17 +57,15 @@ int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
|
|||
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
if (!in_file) {
|
||||
std::cerr << "Unable to open bit file: " << in_file_name
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto in_bytes = absl::Span<uint8_t>(
|
||||
static_cast<uint8_t*>(in_file->data()),
|
||||
in_file->size());
|
||||
static_cast<uint8_t*>(in_file->data()), in_file->size());
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
std::cerr << "Input doesn't look like a bitstream" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +80,7 @@ int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
|
|||
|
||||
if (packet.data().size() != 1) {
|
||||
std::cerr << "Write to FAR with word_count != 1"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -94,20 +90,19 @@ int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
|
|||
|
||||
if (!found_one_lout) {
|
||||
std::cerr << "No LOUT writes found. Was "
|
||||
<< "BITSTREAM.GENERAL.DEBUGBITSTREAM set to YES?"
|
||||
<< std::endl;
|
||||
<< "BITSTREAM.GENERAL.DEBUGBITSTREAM set to YES?"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetDeviceId(int argc, char *argv[]) {
|
||||
int GetDeviceId(int argc, char* argv[]) {
|
||||
if (argc < 1) {
|
||||
std::cerr << "ERROR: no input specified" << std::endl;
|
||||
std::cerr << "Usage: " << argv[0]
|
||||
<< "get_device_id <bit_file>"
|
||||
<< std::endl;
|
||||
std::cerr << "Usage: " << argv[0] << "get_device_id <bit_file>"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -115,68 +110,65 @@ int GetDeviceId(int argc, char *argv[]) {
|
|||
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
if (!in_file) {
|
||||
std::cerr << "Unable to open bit file: " << in_file_name
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto in_bytes = absl::Span<uint8_t>(
|
||||
static_cast<uint8_t*>(in_file->data()),
|
||||
in_file->size());
|
||||
static_cast<uint8_t*>(in_file->data()), in_file->size());
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
std::cerr << "Input doesn't look like a bitstream" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto idcode_packet = std::find_if(
|
||||
reader->begin(), reader->end(),
|
||||
[](const xc7series::ConfigurationPacket &packet) {
|
||||
return (packet.opcode() ==
|
||||
xc7series::ConfigurationPacket::Opcode::Write) &&
|
||||
(packet.address() ==
|
||||
xc7series::ConfigurationRegister::IDCODE);
|
||||
});
|
||||
reader->begin(), reader->end(),
|
||||
[](const xc7series::ConfigurationPacket& packet) {
|
||||
return (packet.opcode() ==
|
||||
xc7series::ConfigurationPacket::Opcode::Write) &&
|
||||
(packet.address() ==
|
||||
xc7series::ConfigurationRegister::IDCODE);
|
||||
});
|
||||
if (idcode_packet != reader->end()) {
|
||||
if (idcode_packet->data().size() != 1) {
|
||||
std::cerr << "Write to IDCODE with word_count != 1"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "0x" << std::hex << idcode_packet->data()[0]
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
Action actions[] = {
|
||||
{ "list_config_packets", ListConfigPackets },
|
||||
{ "dump_debugbitstream_frame_addresses",
|
||||
DumpDebugbitstreamFrameAddresses },
|
||||
{ "get_device_id", GetDeviceId },
|
||||
{"list_config_packets", ListConfigPackets},
|
||||
{"dump_debugbitstream_frame_addresses",
|
||||
DumpDebugbitstreamFrameAddresses},
|
||||
{"get_device_id", GetDeviceId},
|
||||
};
|
||||
|
||||
gflags::SetUsageMessage(
|
||||
absl::StrCat("Usage: ", argv[0], " [options] [bitfile]"));
|
||||
absl::StrCat("Usage: ", argv[0], " [options] [bitfile]"));
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
if (argc < 2) {
|
||||
std::cerr << "ERROR: no command specified" << std::endl;
|
||||
std::cerr << "Usage: " << argv[0]
|
||||
<< "<command> <command_options>" << std::endl;
|
||||
<< "<command> <command_options>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto requested_action_str = argv[1];
|
||||
auto requested_action = std::find_if(
|
||||
std::begin(actions), std::end(actions),
|
||||
[&](const Action& t) {
|
||||
return t.name == requested_action_str; });
|
||||
std::begin(actions), std::end(actions),
|
||||
[&](const Action& t) { return t.name == requested_action_str; });
|
||||
if (requested_action == std::end(actions)) {
|
||||
std::cerr << "Unknown action: "
|
||||
<< requested_action_str << std::endl;
|
||||
std::cerr << "Unknown action: " << requested_action_str
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::istream * input_stream = &std::cin;
|
||||
int main(int argc, char* argv[]) {
|
||||
std::istream* input_stream = &std::cin;
|
||||
if (argc > 1) {
|
||||
auto file_stream = std::ifstream(argv[1]);
|
||||
if (file_stream) {
|
||||
|
|
@ -16,27 +16,19 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
for (uint32_t frame_address_raw;
|
||||
(*input_stream) >> std::setbase(0) >> frame_address_raw;
|
||||
) {
|
||||
(*input_stream) >> std::setbase(0) >> frame_address_raw;) {
|
||||
xc7series::FrameAddress frame_address(frame_address_raw);
|
||||
std::cout << "["
|
||||
<< std::hex << std::showbase << std::setw(10)
|
||||
<< frame_address_raw
|
||||
<< "] "
|
||||
<< (frame_address.is_bottom_half_rows() ?
|
||||
"BOTTOM" : "TOP")
|
||||
<< " Row="
|
||||
<< std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(frame_address.row_address())
|
||||
<< " Column="
|
||||
<< std::setw(2) << std::dec
|
||||
<< frame_address.column_address()
|
||||
<< " Minor="
|
||||
<< std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(frame_address.minor_address())
|
||||
<< " Type="
|
||||
<< frame_address.block_type()
|
||||
<< std::endl;
|
||||
std::cout
|
||||
<< "[" << std::hex << std::showbase << std::setw(10)
|
||||
<< frame_address_raw << "] "
|
||||
<< (frame_address.is_bottom_half_rows() ? "BOTTOM" : "TOP")
|
||||
<< " Row=" << std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(frame_address.row_address())
|
||||
<< " Column=" << std::setw(2) << std::dec
|
||||
<< frame_address.column_address()
|
||||
<< " Minor=" << std::setw(2) << std::dec
|
||||
<< static_cast<unsigned int>(frame_address.minor_address())
|
||||
<< " Type=" << frame_address.block_type() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -13,12 +13,11 @@
|
|||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
std::cerr << "ERROR: no input specified" << std::endl;
|
||||
std::cerr << "Usage: " << basename(argv[0])
|
||||
<< " <bit_file>"
|
||||
<< std::endl;
|
||||
std::cerr << "Usage: " << basename(argv[0]) << " <bit_file>"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -26,15 +25,14 @@ int main(int argc, char *argv[]) {
|
|||
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
|
||||
if (!in_file) {
|
||||
std::cerr << "Unable to open bit file: " << in_file_name
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto reader = xc7series::BitstreamReader::InitWithBytes(
|
||||
in_file->as_bytes());
|
||||
auto reader =
|
||||
xc7series::BitstreamReader::InitWithBytes(in_file->as_bytes());
|
||||
if (!reader) {
|
||||
std::cerr << "Input doesn't look like a bitstream"
|
||||
<< std::endl;
|
||||
std::cerr << "Input doesn't look like a bitstream" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +41,7 @@ int main(int argc, char *argv[]) {
|
|||
absl::optional<uint32_t> idcode;
|
||||
for (auto packet : *reader) {
|
||||
if (packet.opcode() !=
|
||||
xc7series::ConfigurationPacket::Opcode::Write) {
|
||||
xc7series::ConfigurationPacket::Opcode::Write) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -51,13 +49,13 @@ int main(int argc, char *argv[]) {
|
|||
xc7series::ConfigurationRegister::FDRI) {
|
||||
found_fdri_write = true;
|
||||
} else if ((packet.address() ==
|
||||
xc7series::ConfigurationRegister::IDCODE) &&
|
||||
packet.data().size() == 1) {
|
||||
xc7series::ConfigurationRegister::IDCODE) &&
|
||||
packet.data().size() == 1) {
|
||||
idcode = packet.data()[0];
|
||||
} else if (found_fdri_write &&
|
||||
(packet.address() ==
|
||||
xc7series::ConfigurationRegister::LOUT) &&
|
||||
packet.data().size() == 1) {
|
||||
(packet.address() ==
|
||||
xc7series::ConfigurationRegister::LOUT) &&
|
||||
packet.data().size() == 1) {
|
||||
frame_addresses.push_back(packet.data()[0]);
|
||||
}
|
||||
}
|
||||
|
|
@ -69,8 +67,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if (frame_addresses.empty()) {
|
||||
std::cerr << "No LOUT writes found. Was "
|
||||
<< "BITSTREAM.GENERAL.DEBUGBITSTREAM set to YES?"
|
||||
<< std::endl;
|
||||
<< "BITSTREAM.GENERAL.DEBUGBITSTREAM set to YES?"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -80,17 +78,15 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
std::vector<xc7series::ConfigurationFrameRange> ranges;
|
||||
for (auto start_of_range = frame_addresses.begin();
|
||||
start_of_range != frame_addresses.end();
|
||||
) {
|
||||
start_of_range != frame_addresses.end();) {
|
||||
auto end_of_range = start_of_range;
|
||||
while (end_of_range + 1 != frame_addresses.end() &&
|
||||
*(end_of_range + 1) == *end_of_range + 1) {
|
||||
++end_of_range;
|
||||
}
|
||||
|
||||
ranges.push_back(
|
||||
xc7series::ConfigurationFrameRange(*start_of_range,
|
||||
*end_of_range+1));
|
||||
ranges.push_back(xc7series::ConfigurationFrameRange(
|
||||
*start_of_range, *end_of_range + 1));
|
||||
|
||||
start_of_range = ++end_of_range;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <absl/strings/str_cat.h>
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
DEFINE_int32(c, 4, "threshold under which candidates are output. set to -1 to output all.");
|
||||
DEFINE_int32(
|
||||
c,
|
||||
4,
|
||||
"threshold under which candidates are output. set to -1 to output all.");
|
||||
DEFINE_bool(i, false, "add inverted tags");
|
||||
DEFINE_int32(m, 0, "min number of set/cleared samples each");
|
||||
DEFINE_int32(M, 0, "min number of set/cleared samples total");
|
||||
|
|
@ -22,9 +25,9 @@ DEFINE_string(o, "", "set output file");
|
|||
DEFINE_string(k, "", "set output mask file");
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::tuple;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
int num_bits = 0, num_tags = 0;
|
||||
map<string, int> bit_ids, tag_ids;
|
||||
|
|
@ -76,51 +79,40 @@ struct bool_vec
|
|||
}
|
||||
};
|
||||
#else
|
||||
struct bool_vec
|
||||
{
|
||||
struct bool_vec {
|
||||
vector<uint64_t> data;
|
||||
|
||||
bool_vec(int n = 0, bool initval = false) :
|
||||
data((n+63)/64, initval ? ~uint64_t(0) : uint64_t(0))
|
||||
{
|
||||
for (int i = data.size()*64-1; i >= n; i--)
|
||||
bool_vec(int n = 0, bool initval = false)
|
||||
: data((n + 63) / 64, initval ? ~uint64_t(0) : uint64_t(0)) {
|
||||
for (int i = data.size() * 64 - 1; i >= n; i--)
|
||||
data[n / 64] &= ~(uint64_t(1) << (n % 64));
|
||||
}
|
||||
|
||||
void set(int n)
|
||||
{
|
||||
if (int(data.size()*64) <= n)
|
||||
data.resize((n+64) / 64);
|
||||
void set(int n) {
|
||||
if (int(data.size() * 64) <= n)
|
||||
data.resize((n + 64) / 64);
|
||||
data[n / 64] |= uint64_t(1) << (n % 64);
|
||||
}
|
||||
|
||||
bool get(int n)
|
||||
{
|
||||
return (data[n / 64] >> (n % 64)) & 1;
|
||||
}
|
||||
bool get(int n) { return (data[n / 64] >> (n % 64)) & 1; }
|
||||
|
||||
void resize(int n)
|
||||
{
|
||||
data.resize((n+63) / 64);
|
||||
}
|
||||
void resize(int n) { data.resize((n + 63) / 64); }
|
||||
|
||||
int count()
|
||||
{
|
||||
int count() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 64*int(data.size()); i++)
|
||||
if (get(i)) sum++;
|
||||
for (int i = 0; i < 64 * int(data.size()); i++)
|
||||
if (get(i))
|
||||
sum++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
void apply_and(const bool_vec &other)
|
||||
{
|
||||
void apply_and(const bool_vec& other) {
|
||||
assert(data.size() == other.data.size());
|
||||
for (int i = 0; i < int(data.size()); i++)
|
||||
data[i] &= other.data[i];
|
||||
}
|
||||
|
||||
void apply_andc(const bool_vec &other)
|
||||
{
|
||||
void apply_andc(const bool_vec& other) {
|
||||
assert(data.size() == other.data.size());
|
||||
for (int i = 0; i < int(data.size()); i++)
|
||||
data[i] &= ~other.data[i];
|
||||
|
|
@ -134,19 +126,22 @@ map<string, segdata_t> segdata;
|
|||
|
||||
map<string, int> segnamecnt;
|
||||
|
||||
static inline bool_vec &segdata_bits(segdata_t &sd) { return std::get<0>(sd); }
|
||||
static inline bool_vec &segdata_tags1(segdata_t &sd) { return std::get<1>(sd); }
|
||||
static inline bool_vec &segdata_tags0(segdata_t &sd) { return std::get<2>(sd); }
|
||||
static inline bool_vec& segdata_bits(segdata_t& sd) {
|
||||
return std::get<0>(sd);
|
||||
}
|
||||
static inline bool_vec& segdata_tags1(segdata_t& sd) {
|
||||
return std::get<1>(sd);
|
||||
}
|
||||
static inline bool_vec& segdata_tags0(segdata_t& sd) {
|
||||
return std::get<2>(sd);
|
||||
}
|
||||
|
||||
void read_input(std::istream &f, std::string filename)
|
||||
{
|
||||
void read_input(std::istream& f, std::string filename) {
|
||||
string token;
|
||||
segdata_t *segptr = nullptr;
|
||||
segdata_t* segptr = nullptr;
|
||||
|
||||
while (f >> token)
|
||||
{
|
||||
if (token == "seg")
|
||||
{
|
||||
while (f >> token) {
|
||||
if (token == "seg") {
|
||||
f >> token;
|
||||
token = filename + ":" + token;
|
||||
while (segdata.count(token)) {
|
||||
|
|
@ -162,8 +157,7 @@ void read_input(std::istream &f, std::string filename)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (token == "bit")
|
||||
{
|
||||
if (token == "bit") {
|
||||
assert(segptr != nullptr);
|
||||
|
||||
f >> token;
|
||||
|
|
@ -173,14 +167,13 @@ void read_input(std::istream &f, std::string filename)
|
|||
}
|
||||
|
||||
int bit_idx = bit_ids.at(token);
|
||||
auto &bits = segdata_bits(*segptr);
|
||||
auto& bits = segdata_bits(*segptr);
|
||||
|
||||
bits.set(bit_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token == "tag")
|
||||
{
|
||||
if (token == "tag") {
|
||||
assert(segptr != nullptr);
|
||||
|
||||
f >> token;
|
||||
|
|
@ -194,13 +187,15 @@ void read_input(std::istream &f, std::string filename)
|
|||
f >> token;
|
||||
assert(token == "0" || token == "1");
|
||||
|
||||
auto &tags = token == "1" ? segdata_tags1(*segptr) : segdata_tags0(*segptr);
|
||||
auto& tags = token == "1" ? segdata_tags1(*segptr)
|
||||
: segdata_tags0(*segptr);
|
||||
|
||||
tags.set(tag_idx);
|
||||
|
||||
if (FLAGS_i)
|
||||
{
|
||||
auto &inv_tags = token == "1" ? segdata_tags0(*segptr) : segdata_tags1(*segptr);
|
||||
if (FLAGS_i) {
|
||||
auto& inv_tags = token == "1"
|
||||
? segdata_tags0(*segptr)
|
||||
: segdata_tags1(*segptr);
|
||||
|
||||
token = tag_ids_r.at(tag_idx) + "__INV";
|
||||
|
||||
|
|
@ -223,17 +218,16 @@ void read_input(std::istream &f, std::string filename)
|
|||
// printf("Number of bits: %d\n", num_bits);
|
||||
// printf("Number of tags: %d\n", num_tags);
|
||||
|
||||
for (auto &segdat : segdata) {
|
||||
for (auto& segdat : segdata) {
|
||||
segdata_bits(segdat.second).resize(num_bits);
|
||||
segdata_tags1(segdat.second).resize(num_tags);
|
||||
segdata_tags0(segdat.second).resize(num_tags);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char** argv) {
|
||||
gflags::SetUsageMessage(
|
||||
absl::StrCat("Usage: ", argv[0], " [options] file.."));
|
||||
absl::StrCat("Usage: ", argv[0], " [options] file.."));
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
if (argc > 1) {
|
||||
|
|
@ -253,7 +247,7 @@ int main(int argc, char **argv)
|
|||
printf("#of bits: %d\n", num_bits);
|
||||
printf("#of tags: %d\n", num_tags);
|
||||
|
||||
FILE *f = stdout;
|
||||
FILE* f = stdout;
|
||||
|
||||
if (!FLAGS_o.empty()) {
|
||||
f = fopen(FLAGS_o.c_str(), "w");
|
||||
|
|
@ -269,14 +263,12 @@ int main(int argc, char **argv)
|
|||
|
||||
std::vector<std::string> out_lines;
|
||||
|
||||
for (int tag_idx = 0; tag_idx < num_tags; tag_idx++)
|
||||
{
|
||||
for (int tag_idx = 0; tag_idx < num_tags; tag_idx++) {
|
||||
bool_vec mask(num_bits, true);
|
||||
int count1 = 0, count0 = 0;
|
||||
|
||||
for (auto &segdat : segdata)
|
||||
{
|
||||
auto &sd = segdat.second;
|
||||
for (auto& segdat : segdata) {
|
||||
auto& sd = segdat.second;
|
||||
bool tag1 = segdata_tags1(sd).get(tag_idx);
|
||||
bool tag0 = segdata_tags0(sd).get(tag_idx);
|
||||
|
||||
|
|
@ -331,25 +323,28 @@ int main(int argc, char **argv)
|
|||
int num_candidates = mask.count();
|
||||
|
||||
if (count0) {
|
||||
min_candidates = std::min(min_candidates, num_candidates);
|
||||
max_candidates = std::max(max_candidates, num_candidates);
|
||||
min_candidates =
|
||||
std::min(min_candidates, num_candidates);
|
||||
max_candidates =
|
||||
std::max(max_candidates, num_candidates);
|
||||
avg_candidates += num_candidates;
|
||||
cnt_candidates += 1;
|
||||
}
|
||||
|
||||
if (FLAGS_c < 0 ||
|
||||
(0 < num_candidates &&
|
||||
num_candidates <= FLAGS_c)) {
|
||||
(0 < num_candidates && num_candidates <= FLAGS_c)) {
|
||||
std::vector<std::string> out_tags;
|
||||
for (int bit_idx = 0; bit_idx < num_bits; bit_idx++)
|
||||
if (mask.get(bit_idx))
|
||||
out_tags.push_back(bit_ids_r.at(bit_idx));
|
||||
out_tags.push_back(
|
||||
bit_ids_r.at(bit_idx));
|
||||
std::sort(out_tags.begin(), out_tags.end());
|
||||
for (auto &tag : out_tags)
|
||||
for (auto& tag : out_tags)
|
||||
out_line += " " + tag;
|
||||
} else {
|
||||
char buffer[64];
|
||||
snprintf(buffer, 64, " <%d candidates>", num_candidates);
|
||||
snprintf(buffer, 64, " <%d candidates>",
|
||||
num_candidates);
|
||||
out_line += buffer;
|
||||
}
|
||||
|
||||
|
|
@ -358,7 +353,7 @@ int main(int argc, char **argv)
|
|||
|
||||
std::sort(out_lines.begin(), out_lines.end());
|
||||
|
||||
for (auto &line : out_lines)
|
||||
for (auto& line : out_lines)
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
|
||||
if (cnt_candidates)
|
||||
|
|
@ -383,4 +378,3 @@ int main(int argc, char **argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys, re
|
||||
import sys
|
||||
import re
|
||||
|
||||
database = dict()
|
||||
database_r = dict()
|
||||
|
|
@ -24,20 +25,23 @@ for arg in sys.argv[1:]:
|
|||
database[key] = bits
|
||||
database_r[bits] = key
|
||||
|
||||
|
||||
def get_subsets(bits):
|
||||
retval = list()
|
||||
retval.append(bits)
|
||||
for i in range(len(bits)):
|
||||
for s in get_subsets(bits[i+1:]):
|
||||
retval.append(bits[0:i] + s);
|
||||
for s in get_subsets(bits[i + 1:]):
|
||||
retval.append(bits[0:i] + s)
|
||||
return retval
|
||||
|
||||
|
||||
def check_subsets(bits):
|
||||
for sub_bits in sorted(get_subsets(bits)):
|
||||
if sub_bits != bits and sub_bits != ():
|
||||
if sub_bits in database_r:
|
||||
print("Warning: Entry %s %s is a subset of entry %s %s." % (database_r[sub_bits], sub_bits, database_r[bits], bits))
|
||||
print("Warning: Entry %s %s is a subset of entry %s %s." %
|
||||
(database_r[sub_bits], sub_bits, database_r[bits], bits))
|
||||
|
||||
|
||||
for key, bits in database.items():
|
||||
check_subsets(bits)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#/usr/bin/env python3
|
||||
|
||||
import sys, os, re
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
zero_db = [
|
||||
"00_21 00_22 00_26 01_28|00_25 01_20 01_21 01_24",
|
||||
|
|
@ -31,9 +33,11 @@ zero_db = [
|
|||
"30_53 31_53 31_56 31_57",
|
||||
]
|
||||
|
||||
|
||||
def add_zero_bits(tile_type):
|
||||
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
|
||||
dbfile = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), tile_type)
|
||||
dbfile = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||
os.getenv("XRAY_DATABASE"), tile_type)
|
||||
new_lines = set()
|
||||
llast = None
|
||||
|
||||
|
|
@ -84,9 +88,11 @@ def add_zero_bits(tile_type):
|
|||
for line in sorted(new_lines):
|
||||
print(line, file=f)
|
||||
|
||||
|
||||
def update_mask(mask_db, *src_dbs):
|
||||
bits = set()
|
||||
mask_db_file = "%s/%s/mask_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), mask_db)
|
||||
mask_db_file = "%s/%s/mask_%s.db" % (
|
||||
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), mask_db)
|
||||
|
||||
if os.path.exists(mask_db_file):
|
||||
with open(mask_db_file, "r") as f:
|
||||
|
|
@ -97,7 +103,8 @@ def update_mask(mask_db, *src_dbs):
|
|||
bits.add(line[1])
|
||||
|
||||
for src_db in src_dbs:
|
||||
seg_db_file = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), src_db)
|
||||
seg_db_file = "%s/%s/segbits_%s.db" % (
|
||||
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), src_db)
|
||||
|
||||
if not os.path.exists(seg_db_file):
|
||||
continue
|
||||
|
|
@ -114,6 +121,7 @@ def update_mask(mask_db, *src_dbs):
|
|||
for bit in sorted(bits):
|
||||
print("bit %s" % bit, file=f)
|
||||
|
||||
|
||||
add_zero_bits("int_l")
|
||||
add_zero_bits("int_r")
|
||||
add_zero_bits("clbll_l")
|
||||
|
|
@ -133,4 +141,3 @@ for k in range(5):
|
|||
update_mask("bram%d_r" % k, "bram%d_r" % k, "int_r")
|
||||
update_mask("dsp%d_l" % k, "dsp%d_l" % k, "int_l")
|
||||
update_mask("dsp%d_r" % k, "dsp%d_r" % k, "int_r")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import os, json, re
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
|
||||
|
||||
class segmaker:
|
||||
def __init__(self, bitsfile):
|
||||
|
|
@ -24,7 +27,8 @@ class segmaker:
|
|||
if bit_wordidx not in self.bits[base_frame]:
|
||||
self.bits[base_frame][bit_wordidx] = set()
|
||||
|
||||
self.bits[base_frame][bit_wordidx].add((bit_frame, bit_wordidx, bit_bitidx))
|
||||
self.bits[base_frame][bit_wordidx].add(
|
||||
(bit_frame, bit_wordidx, bit_bitidx))
|
||||
|
||||
def addtag(self, site, name, value):
|
||||
if site not in self.tags:
|
||||
|
|
@ -50,30 +54,35 @@ class segmaker:
|
|||
segments = self.segments_by_type[segdata["type"]]
|
||||
|
||||
tile_type = tiledata["type"]
|
||||
segname = "%s_%03d" % (segdata["baseaddr"][0][2:], segdata["baseaddr"][1])
|
||||
segname = "%s_%03d" % (
|
||||
segdata["baseaddr"][0][2:], segdata["baseaddr"][1])
|
||||
|
||||
def add_segbits():
|
||||
if not segname in segments:
|
||||
segments[segname] = { "bits": set(), "tags": dict() }
|
||||
segments[segname] = {"bits": set(), "tags": dict()}
|
||||
|
||||
base_frame = int(segdata["baseaddr"][0][2:], 16)
|
||||
for wordidx in range(segdata["baseaddr"][1], segdata["baseaddr"][1]+segdata["words"]):
|
||||
for wordidx in range(segdata["baseaddr"][1], segdata["baseaddr"][1] + segdata["words"]):
|
||||
if base_frame not in self.bits:
|
||||
continue
|
||||
if wordidx not in self.bits[base_frame]:
|
||||
continue
|
||||
for bit_frame, bit_wordidx, bit_bitidx in self.bits[base_frame][wordidx]:
|
||||
bitname_frame = bit_frame - base_frame
|
||||
bitname_bit = 32*(bit_wordidx - segdata["baseaddr"][1]) + bit_bitidx
|
||||
bitname_bit = 32 * \
|
||||
(bit_wordidx -
|
||||
segdata["baseaddr"][1]) + bit_bitidx
|
||||
if bitfilter is None or bitfilter(bitname_frame, bitname_bit):
|
||||
bitname = "%02d_%02d" % (bitname_frame, bitname_bit)
|
||||
bitname = "%02d_%02d" % (
|
||||
bitname_frame, bitname_bit)
|
||||
segments[segname]["bits"].add(bitname)
|
||||
|
||||
if tilename in self.tags:
|
||||
add_segbits()
|
||||
|
||||
for name, value in self.tags[tilename].items():
|
||||
tag = "%s.%s" % (re.sub("(LL|LM)?_[LR]$", "", tile_type), name)
|
||||
tag = "%s.%s" % (
|
||||
re.sub("(LL|LM)?_[LR]$", "", tile_type), name)
|
||||
segments[segname]["tags"][tag] = value
|
||||
|
||||
for site in tiledata["sites"]:
|
||||
|
|
@ -90,7 +99,8 @@ class segmaker:
|
|||
assert 0
|
||||
|
||||
for name, value in self.tags[site].items():
|
||||
tag = "%s.%s.%s" % (re.sub("(LL|LM)?_[LR]$", "", tile_type), sitekey, name)
|
||||
tag = "%s.%s.%s" % (
|
||||
re.sub("(LL|LM)?_[LR]$", "", tile_type), sitekey, name)
|
||||
tag = tag.replace(".SLICEM.", ".")
|
||||
tag = tag.replace(".SLICEL.", ".")
|
||||
segments[segname]["tags"][tag] = value
|
||||
|
|
@ -119,5 +129,5 @@ class segmaker:
|
|||
for bitname in sorted(segdata["bits"]):
|
||||
print("bit %s_%s" % (segname, bitname), file=f)
|
||||
for tagname, tagval in sorted(segdata["tags"].items()):
|
||||
print("tag %s_%s %d" % (segname, tagname, tagval), file=f)
|
||||
|
||||
print("tag %s_%s %d" %
|
||||
(segname, tagname, tagval), file=f)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import getopt, sys, os, json, re
|
||||
import getopt
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
|
||||
flag_z = False
|
||||
flag_b = False
|
||||
flag_d = False
|
||||
flag_D = False
|
||||
|
||||
|
||||
def usage():
|
||||
print("Usage: %s [options] <bits_file> [segments/tiles]" % sys.argv[0])
|
||||
print("")
|
||||
|
|
@ -24,6 +29,7 @@ def usage():
|
|||
print("")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "zbdD")
|
||||
except:
|
||||
|
|
@ -67,6 +73,7 @@ with open(args[0], "r") as f:
|
|||
|
||||
segbitsdb = dict()
|
||||
|
||||
|
||||
def get_database(segtype):
|
||||
if segtype in segbitsdb:
|
||||
return segbitsdb[segtype]
|
||||
|
|
@ -85,16 +92,17 @@ def get_database(segtype):
|
|||
|
||||
return segbitsdb[segtype]
|
||||
|
||||
|
||||
def handle_segment(segname):
|
||||
if segname is None:
|
||||
segframes = dict()
|
||||
for segname, segdata in grid["segments"].items():
|
||||
framebase = int(segdata["baseaddr"][0], 16)
|
||||
for i in range(segdata["frames"]):
|
||||
if (framebase+i) not in segframes:
|
||||
segframes[framebase+i] = set()
|
||||
if (framebase + i) not in segframes:
|
||||
segframes[framebase + i] = set()
|
||||
for j in range(segdata["baseaddr"][1], segdata["baseaddr"][1] + segdata["words"]):
|
||||
segframes[framebase+i].add(j)
|
||||
segframes[framebase + i].add(j)
|
||||
for frame in sorted(bitdata.keys()):
|
||||
for wordidx in sorted(bitdata[frame].keys()):
|
||||
if frame in segframes and wordidx in segframes[frame]:
|
||||
|
|
@ -151,14 +159,15 @@ def handle_segment(segname):
|
|||
segbits = set()
|
||||
segtags = set()
|
||||
|
||||
for frame in range(baseframe, baseframe+numframes):
|
||||
for frame in range(baseframe, baseframe + numframes):
|
||||
if frame not in bitdata:
|
||||
continue
|
||||
for wordidx in range(basewordidx, basewordidx+numwords):
|
||||
for wordidx in range(basewordidx, basewordidx + numwords):
|
||||
if wordidx not in bitdata[frame]:
|
||||
continue
|
||||
for bitidx in bitdata[frame][wordidx]:
|
||||
segbits.add("%02d_%02d" % (frame - baseframe, 32*(wordidx - basewordidx) + bitidx))
|
||||
segbits.add("%02d_%02d" % (frame - baseframe,
|
||||
32 * (wordidx - basewordidx) + bitidx))
|
||||
|
||||
if flag_d or flag_D:
|
||||
for entry in get_database(seginfo["type"]):
|
||||
|
|
@ -185,6 +194,7 @@ def handle_segment(segname):
|
|||
for tag in sorted(segtags):
|
||||
print("tag %s" % tag)
|
||||
|
||||
|
||||
if flag_b:
|
||||
handle_segment(None)
|
||||
|
||||
|
|
@ -197,4 +207,3 @@ if len(args) == 1:
|
|||
else:
|
||||
for arg in args[1:]:
|
||||
handle_segment(arg)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
# Produces a complete database of wires in the ROI and their connections and tests if each
|
||||
# routing node is a tree (i.e. fails with an error when a loop is found).
|
||||
|
||||
import os, sys, json
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
|
||||
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f:
|
||||
tilegrid = json.load(f)["tiles"]
|
||||
|
|
@ -19,13 +21,16 @@ for tilename, tiledata in tilegrid.items():
|
|||
key = (tiledata["grid_x"], tiledata["grid_y"])
|
||||
grid[key] = tilename
|
||||
|
||||
|
||||
def check_tileconn_entry(tilename, tiledata, entry, idx):
|
||||
if idx == 0:
|
||||
otheridx = 1
|
||||
otherxy = (tiledata["grid_x"] + entry["grid_deltas"][0], tiledata["grid_y"] + entry["grid_deltas"][1])
|
||||
otherxy = (tiledata["grid_x"] + entry["grid_deltas"]
|
||||
[0], tiledata["grid_y"] + entry["grid_deltas"][1])
|
||||
else:
|
||||
otheridx = 0
|
||||
otherxy = (tiledata["grid_x"] - entry["grid_deltas"][0], tiledata["grid_y"] - entry["grid_deltas"][1])
|
||||
otherxy = (tiledata["grid_x"] - entry["grid_deltas"]
|
||||
[0], tiledata["grid_y"] - entry["grid_deltas"][1])
|
||||
|
||||
if otherxy not in grid:
|
||||
return
|
||||
|
|
@ -37,7 +42,7 @@ def check_tileconn_entry(tilename, tiledata, entry, idx):
|
|||
return
|
||||
|
||||
print(" Found relevant entry (%s %s %d %d): %s" % (entry["tile_types"][0], entry["tile_types"][1],
|
||||
entry["grid_deltas"][0], entry["grid_deltas"][1], othertilename))
|
||||
entry["grid_deltas"][0], entry["grid_deltas"][1], othertilename))
|
||||
|
||||
for pair in entry["wire_pairs"]:
|
||||
wirename = "%s/%s" % (tilename, pair[idx])
|
||||
|
|
@ -54,6 +59,7 @@ def check_tileconn_entry(tilename, tiledata, entry, idx):
|
|||
wirepairs[otherwirename] = set()
|
||||
wirepairs[otherwirename].add(wirename)
|
||||
|
||||
|
||||
for tilename, tiledata in tilegrid.items():
|
||||
print("Connecting wires in tile %s." % tilename)
|
||||
for entry in tileconn:
|
||||
|
|
@ -62,6 +68,7 @@ for tilename, tiledata in tilegrid.items():
|
|||
if entry["tile_types"][1] == tiledata["type"]:
|
||||
check_tileconn_entry(tilename, tiledata, entry, 1)
|
||||
|
||||
|
||||
def check_wire(wire, source):
|
||||
for next_wire in wirepairs[wire]:
|
||||
if next_wire == source:
|
||||
|
|
@ -73,10 +80,10 @@ def check_wire(wire, source):
|
|||
remwires.remove(next_wire)
|
||||
check_wire(next_wire, wire)
|
||||
|
||||
|
||||
while len(remwires):
|
||||
wire = remwires.pop()
|
||||
print("Checking %s:" % wire)
|
||||
check_wire(wire, None)
|
||||
|
||||
print("NO LOOP FOUND: OK")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage example: python3 %s HCLK_R HCLK_SW6E3" % sys.argv[0])
|
||||
|
|
@ -26,9 +28,11 @@ for entry in tileconn:
|
|||
if wire_pair[this_idx] != sys.argv[2]:
|
||||
continue
|
||||
|
||||
outdata.append((delta_x, delta_y, entry["tile_types"][other_idx], wire_pair[other_idx]))
|
||||
max_tiletype_len = max(max_tiletype_len, len(entry["tile_types"][other_idx]))
|
||||
outdata.append(
|
||||
(delta_x, delta_y, entry["tile_types"][other_idx], wire_pair[other_idx]))
|
||||
max_tiletype_len = max(max_tiletype_len, len(
|
||||
entry["tile_types"][other_idx]))
|
||||
|
||||
for entry in outdata:
|
||||
print("%3d %3d %-*s %s" % (entry[0], entry[1], max_tiletype_len, entry[2], entry[3]))
|
||||
|
||||
print("%3d %3d %-*s %s" %
|
||||
(entry[0], entry[1], max_tiletype_len, entry[2], entry[3]))
|
||||
|
|
|
|||
Loading…
Reference in New Issue