Merge pull request #41 from kc8apf/code_format

Specify and enforce code style for C++ and Python
This commit is contained in:
Rick Altherr 2018-01-09 11:40:57 -08:00 committed by GitHub
commit 17985d1934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 1513 additions and 1213 deletions

5
.clang-format Normal file
View File

@ -0,0 +1,5 @@
---
Language: Cpp
BasedOnStyle: Chromium
IndentWidth: 8
UseTab: ForIndentation

View File

@ -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; }

View File

@ -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 {} \;

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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")))

View File

@ -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)

View File

@ -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")))

View File

@ -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"))

View File

@ -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])

View File

@ -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()

View File

@ -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

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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
''') ''')

View File

@ -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()

View File

@ -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()

View File

@ -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")))

View File

@ -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()

View File

@ -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")))

View File

@ -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()

View File

@ -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")))

View File

@ -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()

View File

@ -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")))

View File

@ -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()

View File

@ -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()

View File

@ -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")))

View File

@ -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()

View File

@ -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")))

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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));
} }

View File

@ -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) {

View File

@ -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));
} }

View File

@ -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) &

View File

@ -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;

View File

@ -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_;
}; };

View File

@ -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_;
}; };

View 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);

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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->();
} }

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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);

View File

@ -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

View File

@ -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";
} }
} }

View File

@ -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

View File

@ -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);

View File

@ -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

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
autopep8

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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)

View File

@ -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")

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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]))