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