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:
include:
# Job 1) Test C++ w/ GCC
- os: linux
dist: trusty
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
before_install:
- eval "${MATRIX_EVAL}"
script:
script:
- export CC=gcc-6
- export CXX=g++-6
- mkdir -p build
- cd build
- pushd build
- cmake -DPRJXRAY_BUILD_TESTING=ON ..
- make -j 4
- ctest
# Job 2) Lint checks on Python and C++
- os: linux
dist: trusty
addons:
apt:
packages:
- clang-format-3.9
install:
- pip install --user -r requirements.txt
script:
- make format
- test $(git status --porcelain | wc -l) -eq 0 || { git diff; false; }

View File

@ -1,7 +1,13 @@
JOBS ?= $(shell nproc)
JOBS ?= 2
CLANG_FORMAT ?= clang-format
go:
git submodule update --init --recursive
mkdir -p build
cd build; cmake ..; make -j$(JOBS)
format:
find . -name \*.cc -and -not -path './third_party/*' -exec $(CLANG_FORMAT) -style=file -i {} \;
find . -name \*.h -and -not -path './third_party/*' -exec $(CLANG_FORMAT) -style=file -i {} \;
find . -name \*.py -and -not -path './third_party/*' -exec autopep8 -i {} \;

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -19,4 +20,3 @@ with open("design.txt", "r") as f:
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, json, re
import os
import json
import re
#################################################
# Loading Raw Source Data
@ -55,7 +57,8 @@ with open("carrydata.txt", "r") as f:
for i, n in enumerate("CYINIT:ZRO:ONE:AX:CIN DI0:AX:O5 DI1:AX:O5 DI2:AX:O5 DI3:AX:O5".split()):
n = n.split(":")
for k in n[1:]:
carry[line[0]]["CARRY_%s_MUX_%s" % (n[0], k)] = line[1+i].upper() == k
carry[line[0]]["CARRY_%s_MUX_%s" %
(n[0], k)] = line[1 + i].upper() == k
#################################################
@ -74,10 +77,11 @@ for tilename, tiledata in grid["tiles"].items():
if not found_data:
continue
segname = "%s_%02x" % (tiledata["cfgcol"]["BASE_FRAMEID"][2:], min(tiledata["cfgcol"]["WORDS"]))
segname = "%s_%02x" % (
tiledata["cfgcol"]["BASE_FRAMEID"][2:], min(tiledata["cfgcol"]["WORDS"]))
if not segname in segments:
segments[segname] = { "bits": list(), "tags": dict() }
segments[segname] = {"bits": list(), "tags": dict()}
for site in tiledata["sites"]:
if site not in luts and site not in carry:
@ -98,12 +102,14 @@ for tilename, tiledata in grid["tiles"].items():
if re.match("^CLBL[LM]_[LR]", tile_type) and "LUT.INIT" in name:
tile_type = "CLBLX_X"
segments[segname]["tags"]["%s.%s.%s" % (tile_type, sitekey, name)] = value
segments[segname]["tags"]["%s.%s.%s" %
(tile_type, sitekey, name)] = value
if site in carry:
for name, value in carry[site].items():
tile_type = tiledata["props"]["TYPE"]
segments[segname]["tags"]["%s.%s.%s" % (tile_type, sitekey, name)] = value
segments[segname]["tags"]["%s.%s.%s" %
(tile_type, sitekey, name)] = value
base_frame = int(tiledata["cfgcol"]["BASE_FRAMEID"][2:], 16)
for wordidx in tiledata["cfgcol"]["WORDS"]:
@ -112,7 +118,8 @@ for tilename, tiledata in grid["tiles"].items():
if wordidx not in bits[base_frame]:
continue
for bit_frame, bit_wordidx, bit_bitidx in bits[base_frame][wordidx]:
segments[segname]["bits"].append("%02x_%02x_%02x" % (bit_frame - base_frame, bit_wordidx - min(tiledata["cfgcol"]["WORDS"]), bit_bitidx))
segments[segname]["bits"].append("%02x_%02x_%02x" % (
bit_frame - base_frame, bit_wordidx - min(tiledata["cfgcol"]["WORDS"]), bit_bitidx))
segments[segname]["bits"].sort()
@ -129,4 +136,3 @@ with open("segdata.txt", "w") as f:
print("bit %s" % bitname, file=f)
for tagname, tagval in sorted(segdata["tags"].items()):
print("tag %s %d" % (tagname, tagval), file=f)

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if line.endswith(".GND_WIRE") or line.endswith(".VCC_WIRE"):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -8,6 +9,7 @@ from segmaker import segmaker
pipdata = dict()
ignpip = set()
def handle_design(prefix, second_pass):
segmk = segmaker(prefix + ".bits")
@ -73,6 +75,7 @@ def handle_design(prefix, second_pass):
segmk.compile()
segmk.write(prefix[7:])
for arg in sys.argv[1:]:
prefix = arg[0:-4]
handle_design(prefix, False)
@ -80,4 +83,3 @@ for arg in sys.argv[1:]:
for arg in sys.argv[1:]:
prefix = arg[0:-4]
handle_design(prefix, True)

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -21,6 +23,8 @@ def maketodo(pipfile, dbfile):
continue
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python3
import os, sys, json, re
import os
import sys
import json
import re
#######################################
@ -18,7 +21,7 @@ for arg in sys.argv[1:]:
with open(arg) as f:
line = f.read().strip()
site = arg[7:-6]
frame = int(line[5:5+8], 16)
frame = int(line[5:5 + 8], 16)
site_baseaddr[site] = "0x%08x" % (frame & ~0x7f)
@ -45,7 +48,7 @@ for record in tiles:
if len(record) > 4:
for i in range(4, len(record), 2):
site_type, site_name = record[i:i+2]
site_type, site_name = record[i:i + 2]
if site_name in site_baseaddr:
framebaseaddr = site_baseaddr[site_name]
database["tiles"][tile_name]["sites"][site_name] = site_type
@ -64,15 +67,16 @@ for tile_name, tile_data in database["tiles"].items():
if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R"]:
if tile_type in ["CLBLL_L", "CLBLM_L"]:
int_tile_name = tiles_by_grid[(grid_x+1, grid_y)]
int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
else:
int_tile_name = tiles_by_grid[(grid_x-1, grid_y)]
int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
segment_name = "SEG_" + tile_name
segtype = tile_type.lower()
database["segments"][segment_name] = dict()
database["segments"][segment_name]["tiles"] = [tile_name, int_tile_name]
database["segments"][segment_name]["tiles"] = [
tile_name, int_tile_name]
database["segments"][segment_name]["type"] = segtype
database["segments"][segment_name]["frames"] = 36
database["segments"][segment_name]["words"] = 2
@ -97,11 +101,11 @@ for tile_name, tile_data in database["tiles"].items():
if tile_type in ["BRAM_L", "DSP_L", "BRAM_R", "DSP_R"]:
for k in range(5):
if tile_type in ["BRAM_L", "DSP_L"]:
interface_tile_name = tiles_by_grid[(grid_x+1, grid_y-k)]
int_tile_name = tiles_by_grid[(grid_x+2, grid_y-k)]
interface_tile_name = tiles_by_grid[(grid_x + 1, grid_y - k)]
int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)]
else:
interface_tile_name = tiles_by_grid[(grid_x-1, grid_y-k)]
int_tile_name = tiles_by_grid[(grid_x-2, grid_y-k)]
interface_tile_name = tiles_by_grid[(grid_x - 1, grid_y - k)]
int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)]
segment_name = "SEG_" + tile_name.replace("_", "%d_" % k, 1)
segtype = tile_type.lower().replace("_", "%d_" % k, 1)
@ -112,12 +116,14 @@ for tile_name, tile_data in database["tiles"].items():
database["segments"][segment_name]["words"] = 2
if k == 0:
database["segments"][segment_name]["tiles"] = [tile_name, interface_tile_name, int_tile_name]
database["segments"][segment_name]["tiles"] = [
tile_name, interface_tile_name, int_tile_name]
database["tiles"][tile_name]["segment"] = segment_name
database["tiles"][interface_tile_name]["segment"] = segment_name
database["tiles"][int_tile_name]["segment"] = segment_name
else:
database["segments"][segment_name]["tiles"] = [interface_tile_name, int_tile_name]
database["segments"][segment_name]["tiles"] = [
interface_tile_name, int_tile_name]
database["tiles"][interface_tile_name]["segment"] = segment_name
database["tiles"][int_tile_name]["segment"] = segment_name
@ -128,7 +134,8 @@ for tile_name, tile_data in database["tiles"].items():
for segment_name in database["segments"].keys():
if "baseaddr" in database["segments"][segment_name]:
framebase, wordbase = database["segments"][segment_name]["baseaddr"]
inttile = [tile for tile in database["segments"][segment_name]["tiles"] if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
inttile = [tile for tile in database["segments"][segment_name]["tiles"]
if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
grid_x = database["tiles"][inttile]["grid_x"]
grid_y = database["tiles"][inttile]["grid_y"]
@ -156,7 +163,8 @@ for segment_name in database["segments"].keys():
seg = database["tiles"][tile]["segment"]
if "baseaddr" in database["segments"][seg]:
assert database["segments"][seg]["baseaddr"] == [framebase, wordbase]
assert database["segments"][seg]["baseaddr"] == [
framebase, wordbase]
else:
database["segments"][seg]["baseaddr"] = [framebase, wordbase]
@ -172,7 +180,8 @@ for segment_name in database["segments"].keys():
for segment_name in start_segments:
framebase, wordbase = database["segments"][segment_name]["baseaddr"]
inttile = [tile for tile in database["segments"][segment_name]["tiles"] if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
inttile = [tile for tile in database["segments"][segment_name]["tiles"]
if database["tiles"][tile]["type"] in ["INT_L", "INT_R"]][0]
grid_x = database["tiles"][inttile]["grid_x"]
grid_y = database["tiles"][inttile]["grid_y"]
@ -192,4 +201,3 @@ for segment_name in start_segments:
# Write
print(json.dumps(database, sort_keys=True, indent="\t"))

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -22,4 +23,3 @@ with open("design_%s.txt" % sys.argv[1], "r") as f:
segmk.compile()
segmk.write(sys.argv[1])

View File

@ -11,22 +11,25 @@ LDPE Primitive: Transparent Data Latch with Asynchronous Preset and Gate Enable
from prims import *
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
segmk = segmaker("design.bits")
def ones(l):
#return l + [x + '_1' for x in l]
#return sorted(l + [x + '_1' for x in l])
# return l + [x + '_1' for x in l]
# return sorted(l + [x + '_1' for x in l])
ret = []
for x in l:
ret.append(x)
ret.append(x + '_1')
return ret
def loadtop():
'''
i,prim,loc,bel
@ -39,17 +42,20 @@ def loadtop():
f.readline()
ret = {}
for l in f:
i,prim,loc,bel,init = l.split(",")
i, prim, loc, bel, init = l.split(",")
i = int(i)
init = int(init)
ret[loc] = (i,prim,loc,bel,init)
ret[loc] = (i, prim, loc, bel, init)
return ret
top = loadtop()
def vs2i(s):
return {"1'b0": 0, "1'b1": 1}[s]
print("Loading tags from design.txt")
with open("design.txt", "r") as f:
for line in f:
@ -117,4 +123,3 @@ with open("design.txt", "r") as f:
segmk.compile()
segmk.write()

View File

@ -1,12 +1,13 @@
def ones(l):
#return l + [x + '_1' for x in l]
#return sorted(l + [x + '_1' for x in l])
# return l + [x + '_1' for x in l]
# return sorted(l + [x + '_1' for x in l])
ret = []
for x in l:
ret.append(x)
ret.append(x + '_1')
return ret
# The complete primitive sets
ffprims_fall = ones([
'FD',
@ -19,14 +20,14 @@ ffprims_fall = ones([
'FDRE',
'FDS',
'FDSE',
])
])
ffprims_lall = ones([
'LDC',
'LDCE',
'LDE',
'LDPE',
'LDP',
])
])
# Base primitives
ffprims_f = [
@ -34,31 +35,33 @@ ffprims_f = [
'FDSE',
'FDCE',
'FDPE',
]
]
ffprims_l = [
'LDCE',
'LDPE',
]
]
ffprims = ffprims_f + ffprims_l
def isff(prim):
return prim.startswith("FD")
def isl(prim):
return prim.startswith("LD")
ff_bels_5 = [
'A5FF',
'B5FF',
'C5FF',
'D5FF',
]
]
ff_bels_ffl = [
'AFF',
'BFF',
'CFF',
'DFF',
]
]
ff_bels = ff_bels_ffl + ff_bels_5
#ff_bels = ff_bels_ffl

View File

@ -5,14 +5,17 @@ import re
from prims import *
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 600
SLICEX, SLICEY = slice_xy()
# 800
@ -25,11 +28,13 @@ print('//Requested CLBs: %s' % str(CLBN))
f = open("top.txt", "w")
f.write("i,prim,loc,bel,init\n")
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 4
DOUT_N = CLBN * 1
@ -64,7 +69,8 @@ endmodule
''' % (DIN_N, DOUT_N))
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
ffprim = random.choice(ones(ffprims))
# clb_FD clb_FD (.clk(clk), .din(din[ 0 +: 4]), .dout(dout[ 0]));
@ -79,7 +85,8 @@ for i in range(CLBN):
#bel = "AFF"
print(' clb_%s' % ffprim)
print(' #(.LOC("%s"), .BEL("%s"), .INIT(%d))' % (loc, bel, init))
print(' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
f.write("%d,%s,%s,%s,%d\n" % (i, ffprim, loc, bel, init))
print('''endmodule
@ -488,4 +495,3 @@ module clb_LDPE_1 (input clk, input [3:0] din, output dout);
endmodule
''')

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -17,7 +18,7 @@ clb_N5FFMUX,SLICE_X14Y100,3,1
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,n,def_a = l.split(',')
module, loc, n, def_a = l.split(',')
def_a = int(def_a)
n = int(n)
#which = chr(ord('A') + n)
@ -30,4 +31,3 @@ for l in f:
segmk.addtag(loc, "%c5FF.MUX.B" % which, 1 ^ def_a ^ inv)
segmk.compile()
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 40
SLICEX, SLICEY = slice_xy()
# 800
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
@ -61,7 +66,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,n,def_a\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
bel = ''
@ -72,7 +78,8 @@ for i in range(CLBN):
print(' %s' % module)
print(' #(.LOC("%s"), .N(%d), .DEF_A(%d))' % (loc, n, def_a))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s,%s,%s\n' % (module, loc, n, def_a))
f.close()
@ -203,4 +210,3 @@ module clb_N5FFMUX (input clk, input [7:0] din, output [7:0] dout);
.D(ffds[0]));
endmodule
''')

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -17,7 +18,7 @@ clb_NCY0_O5,SLICE_X17Y100,A6LUT,2
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,bel,n = l.split(',')
module, loc, bel, n = l.split(',')
n = int(n)
# A, B, etc
which = bel[0]
@ -26,4 +27,3 @@ for l in f:
segmk.addtag(loc, "CARRY4.%cCY0" % which, module == 'clb_NCY0_O5')
segmk.compile()
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 400
SLICEX, SLICEY = slice_xy()
# 800
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
@ -63,7 +68,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,bel,n\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
bel = ''
@ -77,7 +83,8 @@ for i in range(CLBN):
print(' %s' % module)
print(' #(.LOC("%s"), .BEL("%s"), .N(%d))' % (loc, bel, n))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s,%s,%s\n' % (module, loc, bel, n))
f.close()
@ -156,4 +163,3 @@ module clb_NCY0_O5 (input clk, input [7:0] din, output [7:0] dout);
CARRY4 carry4(.O(o), .CO(), .DI(di), .S(s), .CYINIT(1'b0), .CI());
endmodule
''')

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -17,7 +18,7 @@ clb_FDRE,SLICE_X14Y100,1,1
f = open('params.csv', 'r')
f.readline()
for l in f:
name,site,ce,r = l.split(',')
name, site, ce, r = l.split(',')
ce = int(ce)
r = int(r)
@ -30,4 +31,3 @@ for l in f:
segmk.addtag(site, "SRUSEDMUX", r)
segmk.compile()
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 600
SLICEX, SLICEY = slice_xy()
# 800
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 4
DOUT_N = CLBN * 1
ffprims = (
@ -39,7 +44,7 @@ ff_bels = (
'C5FF',
'DFF',
'D5FF',
)
)
print('''
module top(input clk, stb, di, output do);
@ -74,7 +79,8 @@ endmodule
f = open('params.csv', 'w')
f.write('name,loc,ce,r\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
ffprim = random.choice(ffprims)
force_ce = random.randint(0, 1)
@ -86,8 +92,10 @@ for i in range(CLBN):
bel = "AFF"
name = 'clb_%s' % ffprim
print(' %s' % name)
print(' #(.LOC("%s"), .BEL("%s"), .FORCE_CE1(%d), .nFORCE_R0(%d))' % (loc, bel, force_ce, force_r))
print(' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
print(' #(.LOC("%s"), .BEL("%s"), .FORCE_CE1(%d), .nFORCE_R0(%d))' % (
loc, bel, force_ce, force_r))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i))
f.write('%s,%s,%s,%s\n' % (name, loc, force_ce, force_r))
f.close()
print('''endmodule
@ -112,4 +120,3 @@ module clb_FDRE (input clk, input [3:0] din, output dout);
);
endmodule
''')

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -18,7 +20,7 @@ clb_NFFMUX_O6,SLICE_X14Y100,3
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,n = l.split(',')
module, loc, n = l.split(',')
n = int(n)
which = chr(ord('A') + n)
# clb_NFFMUX_AX => AX
@ -63,17 +65,22 @@ for l in f:
for loc, muxes in cache.items():
for which in muxes:
for src in "F7 F8 CY O5 AX XOR O6".split():
if src == "F7" and which not in "AC": continue
if src == "F8" and which not in "B": continue
if src == "AX": src = which + "X"
if src == "F7" and which not in "AC":
continue
if src == "F8" and which not in "B":
continue
if src == "AX":
src = which + "X"
tag = "%sFF.DMUX.%s" % (which, src)
segmk.addtag(loc, tag, 0)
# we know that all bits for those MUXes are in frames 30 and 31, so filter all other bits
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") == "artix7"
return frame_idx in [30, 31]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 400
SLICEX, SLICEY = slice_xy()
# 800
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
@ -61,9 +66,11 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,n\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
modules = ['clb_NFFMUX_' + x for x in ['AX', 'CY', 'F78', 'O5', 'O6', 'XOR']]
modules = ['clb_NFFMUX_' +
x for x in ['AX', 'CY', 'F78', 'O5', 'O6', 'XOR']]
module = random.choice(modules)
if module == 'clb_NFFMUX_F78':
@ -75,7 +82,8 @@ for i in range(CLBN):
print(' %s' % module)
print(' #(.LOC("%s"), .N(%d))' % (loc, n))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s,%s\n' % (module, loc, n))
f.close()
@ -330,4 +338,3 @@ module clb_NFFMUX_XOR (input clk, input [7:0] din, output [7:0] dout);
.ff_d(caro));
endmodule
''')

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -18,7 +20,7 @@ clb_NFFMUX_O6,SLICE_X14Y100,3
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,n = l.split(',')
module, loc, n = l.split(',')
n = int(n)
which = chr(ord('A') + n)
# clb_NFFMUX_AX => AX
@ -63,12 +65,16 @@ for l in f:
for loc, muxes in cache.items():
for which in muxes:
for src in "F7 F8 CY O5 XOR O6 5Q".split():
if src == "F7" and which not in "AC": continue
if src == "F8" and which not in "B": continue
if src == "5Q": src = which + "5Q"
if src == "F7" and which not in "AC":
continue
if src == "F8" and which not in "B":
continue
if src == "5Q":
src = which + "5Q"
tag = "%sMUX.%s" % (which, src)
segmk.addtag(loc, tag, 0)
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") == "artix7"
@ -80,11 +86,12 @@ def bitfilter(frame_idx, bit_idx):
(31, 44), (31, 45), # C5MA
(30, 19), (31, 19), # B5MA
(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
return frame_idx in [30, 31]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 400
SLICEX, SLICEY = slice_xy()
# 800
@ -20,11 +23,13 @@ print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
@ -61,7 +66,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,n\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
# Don't have an O6 example
modules = ['clb_NOUTMUX_' + x for x in ['CY', 'F78', 'O5', 'XOR', 'B5Q']]
@ -76,7 +82,8 @@ for i in range(CLBN):
print(' %s' % module)
print(' #(.LOC("%s"), .N(%d))' % (loc, n))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s,%s\n' % (module, loc, n))
f.close()
@ -305,4 +312,3 @@ module clb_NOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout);
.ff_q(dout[0]));
endmodule
''')

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -11,7 +13,7 @@ print("Loading tags")
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,loc2 = l.split(',')
module, loc, loc2 = l.split(',')
# clb_PRECYINIT_AX => AX
src = module.replace('clb_PRECYINIT_', '')
@ -29,4 +31,3 @@ for l in f:
segmk.compile()
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 400
SLICEX, SLICEY = slice_xy()
# 800
@ -22,12 +25,15 @@ print('//Requested CLBs: %s' % str(CLBN))
# Rearranged to sweep Y so that carry logic is easy to allocate
# XXX: careful...if odd number of Y in ROI will break carry
def gen_slices():
for slicex in range(*SLICEX):
for slicey in range(*SLICEY):
# caller may reject position if needs more room
yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
@ -64,7 +70,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,loc2\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
# Don't have an O6 example
modules = ['clb_PRECYINIT_' + x for x in ['0', '1', 'AX', 'CIN']]
@ -88,7 +95,8 @@ for i in range(CLBN):
print(' %s' % module)
print(' #(%s)' % (params))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
print(
' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s\n' % (module, paramsc))
f.close()
@ -134,4 +142,3 @@ module clb_PRECYINIT_CIN (input clk, input [7:0] din, output [7:0] dout);
CARRY4 carry4_ci(.O(), .CO(co), .DI(din[3:0]), .S(din[7:4]), .CYINIT(1'b0), .CI());
endmodule
''')

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, re, os
import sys
import re
import os
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -12,12 +14,12 @@ segmk = segmaker("design.bits")
multi_bels_by = [
'SRL16E',
'SRLC32E',
]
]
# Not BELable
multi_bels_bn = [
'RAM32X1S',
'RAM64X1S',
]
]
# Those requiring special resources
# Just make one per module
@ -25,7 +27,7 @@ greedy_modules = [
'my_RAM128X1D',
'my_RAM128X1S',
'my_RAM256X1S',
]
]
print("Loading tags")
'''
@ -38,9 +40,10 @@ f = open('params.csv', 'r')
f.readline()
for l in f:
l = l.strip()
module,loc,p0,p1,p2,p3 = l.split(',')
module, loc, p0, p1, p2, p3 = l.split(',')
segmk.addtag(loc, "WA7USED", module in ('my_RAM128X1D', 'my_RAM128X1S', 'my_RAM256X1S'))
segmk.addtag(loc, "WA7USED", module in (
'my_RAM128X1D', 'my_RAM128X1S', 'my_RAM256X1S'))
segmk.addtag(loc, "WA8USED", module == 'my_RAM256X1S')
# (a, b, c, d)
@ -53,7 +56,7 @@ for l in f:
if module == 'my_ram_N':
# Each one of: SRL16E, SRLC32E, LUT6
bels = [p0,p1,p2,p3]
bels = [p0, p1, p2, p3]
# Clock Enable (CE) clock gate only enabled if we have clocked elements
# A pure LUT6 does not, but everything else should
@ -125,12 +128,13 @@ for l in f:
# FIXME
module == segmk.addtag(loc, "%sLUT.SMALL" % bel, size[beli])
def bitfilter(frame_idx, bit_idx):
# Hack to remove aliased PIP bits on CE
# We should either mix up routing more or exclude previous DB entries
assert os.getenv("XRAY_DATABASE") == "artix7"
return (frame_idx, bit_idx) not in [(0, 27), (1, 25), (1, 26), (1, 29)]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -20,14 +20,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 50
SLICEX, SLICEY = slice_xy()
# 800
@ -39,6 +42,8 @@ print('//Requested CLBs: %s' % str(CLBN))
# Rearranged to sweep Y so that carry logic is easy to allocate
# XXX: careful...if odd number of Y in ROI will break carry
def gen_slicems():
'''
SLICEM at the following:
@ -54,7 +59,7 @@ def gen_slicems():
for slicex in (12, 14):
for slicey in range(*SLICEY):
# caller may reject position if needs more room
#yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
# yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
yield "SLICE_X%dY%d" % (slicex, slicey)
@ -94,7 +99,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,bela,belb,belc,beld\n')
slices = gen_slicems()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
randluts = 0
for clbi in range(CLBN):
loc = next(slices)
@ -165,7 +171,8 @@ for clbi in range(CLBN):
print(' %s' % module)
print(' #(.LOC("%s")%s)' % (loc, params))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (clbi, 8 * clbi, 8 * clbi))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (
clbi, 8 * clbi, 8 * clbi))
f.write('%s,%s%s\n' % (module, loc, cparams))
f.close()
@ -510,4 +517,3 @@ module my_ram_N (input clk, input [7:0] din, output [7:0] dout);
endmodule
''')

View File

@ -5,7 +5,9 @@
# Can we find instance where they are not aliased?
WA7USED = 0
import sys, re, os
import sys
import re
import os
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -23,7 +25,7 @@ f = open('params.csv', 'r')
f.readline()
for l in f:
l = l.strip()
module,loc,c31,b31,a31 = l.split(',')
module, loc, c31, b31, a31 = l.split(',')
c31 = int(c31)
b31 = int(b31)
a31 = int(a31)
@ -33,4 +35,3 @@ for l in f:
segmk.compile()
segmk.write()

View File

@ -3,14 +3,17 @@ random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
m = re.match(
r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 50
SLICEX, SLICEY = slice_xy()
# 800
@ -22,6 +25,8 @@ print('//Requested CLBs: %s' % str(CLBN))
# Rearranged to sweep Y so that carry logic is easy to allocate
# XXX: careful...if odd number of Y in ROI will break carry
def gen_slicems():
'''
SLICEM at the following:
@ -37,7 +42,7 @@ def gen_slicems():
for slicex in (12, 14):
for slicey in range(*SLICEY):
# caller may reject position if needs more room
#yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
# yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
yield "SLICE_X%dY%d" % (slicex, slicey)
@ -77,7 +82,8 @@ endmodule
f = open('params.csv', 'w')
f.write('module,loc,c31,b31,a31\n')
slices = gen_slicems()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (
DIN_N - 1, DOUT_N - 1))
multis = 0
for clbi in range(CLBN):
loc = next(slices)
@ -87,8 +93,10 @@ for clbi in range(CLBN):
a31 = random.randint(0, 1)
print(' %s' % module)
print(' #(.LOC("%s"), .C31(%d), .B31(%d), .A31(%d))' % (loc, c31, b31, a31))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (clbi, 8 * clbi, 8 * clbi))
print(' #(.LOC("%s"), .C31(%d), .B31(%d), .A31(%d))' %
(loc, c31, b31, a31))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (
clbi, 8 * clbi, 8 * clbi))
f.write('%s,%s,%d,%d,%d\n' % (module, loc, c31, b31, a31))
f.close()
@ -159,4 +167,3 @@ module my_NDI1MUX_NI_NMC31 (input clk, input [7:0] din, output [7:0] dout);
.D(lutd[0]));
endmodule
''')

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -63,4 +64,3 @@ for tile, pips_srcs_dsts in tiledata.items():
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, re, os
import sys
import re
import os
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -61,12 +63,13 @@ for tile, pips_srcs_dsts in tiledata.items():
elif src_dst[1] not in dsts:
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
if frame_idx in [30, 31]:
return False
return True
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if re.match(r"^INT_[LR].IMUX(_L)?[0-9]+\.LOGIC_OUTS(_L)?[0-9]+$", line):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -58,6 +60,7 @@ for tile, pips_srcs_dsts in tiledata.items():
elif src_dst[1] not in dsts:
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
if frame_idx == 0 and bit_idx == 48:
@ -66,6 +69,6 @@ def bitfilter(frame_idx, bit_idx):
return False
return frame_idx in [0, 1]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if re.match(r"^INT_[LR].CLK", line):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -58,12 +60,13 @@ for tile, pips_srcs_dsts in tiledata.items():
elif src_dst[1] not in dsts:
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
if (frame_idx, bit_idx) in [(0, 48), (1, 31), (0, 32), (1, 35)]:
return False
return frame_idx in [0, 1]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if re.match(r"^INT_[LR].CTRL", line):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if re.match(r"^INT_[LR].GFAN", line) and not line.endswith(".GND_WIRE"):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -60,4 +62,3 @@ for tile, pips_srcs_dsts in tiledata.items():
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -70,4 +72,3 @@ for tile, pips_srcs_dsts in tiledata.items():
segmk.compile()
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
if not line.endswith(".VCC_WIRE"):
print(line)
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("pips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -40,10 +42,11 @@ for tile, pips_nodes in tiledata.items():
elif dst not in nodes and src not in nodes:
segmk.addtag(tile, "%s.%s" % (dst, src), 0)
def bitfilter(frame_idx, bit_idx):
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
return frame_idx in [0, 1]
segmk.compile(bitfilter=bitfilter)
segmk.write()

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, re
import os
import re
def maketodo(pipfile, dbfile):
todos = set()
@ -16,6 +18,8 @@ def maketodo(pipfile, dbfile):
for line in todos:
print(line)
maketodo("bipips_int_l.txt", "%s/%s/segbits_int_l.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("bipips_int_r.txt", "%s/%s/segbits_int_r.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("bipips_int_l.txt", "%s/%s/segbits_int_l.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))
maketodo("bipips_int_r.txt", "%s/%s/segbits_int_r.db" %
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")))

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import sys, os, re
import sys
import os
import re
sys.path.append("../../../utils/")
from segmaker import segmaker
@ -50,4 +52,3 @@ for arg in sys.argv[1:]:
segmk.compile()
segmk.write(arg)

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python3
import os, sys, json, re
import os
import sys
import json
import re
tilenodes = dict()
grid2tile = dict()
@ -24,38 +27,56 @@ with open("nodewires.txt") as f:
tilenodes[wire_tile] = dict()
tilenodes[wire_tile][node] = wire_name
def filter_pair(type1, type2, wire1, wire2, delta_x, delta_y):
if type1 in ["HCLK_L", "HCLK_R"]:
is_vertical_wire = False
if wire1.startswith("HCLK_S"): is_vertical_wire = True
if wire1.startswith("HCLK_N"): is_vertical_wire = True
if wire1.startswith("HCLK_W"): is_vertical_wire = True
if wire1.startswith("HCLK_E"): is_vertical_wire = True
if wire1.startswith("HCLK_LV"): is_vertical_wire = True
if wire1.startswith("HCLK_BYP"): is_vertical_wire = True
if wire1.startswith("HCLK_FAN"): is_vertical_wire = True
if wire1.startswith("HCLK_LEAF_CLK_"): is_vertical_wire = True
if wire1.startswith("HCLK_S"):
is_vertical_wire = True
if wire1.startswith("HCLK_N"):
is_vertical_wire = True
if wire1.startswith("HCLK_W"):
is_vertical_wire = True
if wire1.startswith("HCLK_E"):
is_vertical_wire = True
if wire1.startswith("HCLK_LV"):
is_vertical_wire = True
if wire1.startswith("HCLK_BYP"):
is_vertical_wire = True
if wire1.startswith("HCLK_FAN"):
is_vertical_wire = True
if wire1.startswith("HCLK_LEAF_CLK_"):
is_vertical_wire = True
is_horizontal_wire = False
if wire1.startswith("HCLK_CK_"): is_horizontal_wire = True
if wire1.startswith("HCLK_INT_"): is_horizontal_wire = True
if wire1.startswith("HCLK_CK_"):
is_horizontal_wire = True
if wire1.startswith("HCLK_INT_"):
is_horizontal_wire = True
assert is_vertical_wire != is_horizontal_wire
if is_vertical_wire and delta_y == 0: return True
if is_horizontal_wire and delta_x == 0: return True
if is_vertical_wire and delta_y == 0:
return True
if is_horizontal_wire and delta_x == 0:
return True
if type1 in ["INT_L", "INT_R"]:
# the wires with underscore after BEG/END all connect vertically
if (("BEG_" in wire1) or ("END_" in wire1)) and delta_y == 0: return True
if (("BEG_" in wire1) or ("END_" in wire1)) and delta_y == 0:
return True
if type1 in ["BRKH_INT", "BRKH_B_TERM_INT", "T_TERM_INT"]:
if delta_y == 0: return True
if delta_y == 0:
return True
return False
def handle_pair(tile1, tile2):
if tile1 not in tilenodes: return
if tile2 not in tilenodes: return
if tile1 not in tilenodes:
return
if tile2 not in tilenodes:
return
tile1data = grid["tiles"][tile1]
tile2data = grid["tiles"][tile2]
@ -66,7 +87,8 @@ def handle_pair(tile1, tile2):
if grid1_xy > grid2_xy:
return handle_pair(tile2, tile1)
key = (tile1data["type"], tile2data["type"], grid2_xy[0] - grid1_xy[0], grid2_xy[1] - grid1_xy[1])
key = (tile1data["type"], tile2data["type"],
grid2_xy[0] - grid1_xy[0], grid2_xy[1] - grid1_xy[1])
wire_pairs = set()
@ -84,9 +106,10 @@ def handle_pair(tile1, tile2):
else:
database[key] &= wire_pairs
for tile, tiledata in grid["tiles"].items():
grid_right_xy = (tiledata["grid_x"]+1, tiledata["grid_y"])
grid_below_xy = (tiledata["grid_x"], tiledata["grid_y"]+1)
grid_right_xy = (tiledata["grid_x"] + 1, tiledata["grid_y"])
grid_below_xy = (tiledata["grid_x"], tiledata["grid_y"] + 1)
if grid_right_xy in grid2tile:
handle_pair(tile, grid2tile[grid_right_xy])
@ -108,4 +131,3 @@ for key in sorted(database.keys()):
print("Writing tileconn.json.")
with open("tileconn.json", "w") as f:
print(json.dumps(json_db, sort_keys=True, indent="\t"), file=f)

View File

@ -13,17 +13,20 @@ db_site_prop = dict()
db_site_tile = dict()
db_site_bit = dict()
def add_tile(tile):
if tile not in db_tiles:
db_tiles.add(tile)
db_tile_prop[tile] = dict()
db_tile_sites[tile] = list()
def add_site(site):
if site not in db_sites:
db_sites.add(site)
db_site_prop[site] = dict()
with open("%s.txt" % sys.argv[1]) as f:
for line in f:
line = line.split()
@ -89,34 +92,36 @@ for site, bit in db_site_bit.items():
for i in range(50):
m = re.match("(.*)Y([0-9]+)", site)
this_site = "%sY%d" % (m.group(1), int(m.group(2))+i)
this_site = "%sY%d" % (m.group(1), int(m.group(2)) + i)
tile = db_site_tile[this_site]
word = bit_word + 2*i
if word >= 50: word += 1
word = bit_word + 2 * i
if word >= 50:
word += 1
entry = dict()
entry["BASE_FRAMEID"] = "0x%08x" % ((bit_type << 23) | (bit_half << 22) | (bit_row << 17) | (bit_col << 7))
entry["BASE_FRAMEID"] = "0x%08x" % ((bit_type << 23) | (
bit_half << 22) | (bit_row << 17) | (bit_col << 7))
entry["FRAME_TYPE"] = bit_type
entry["FRAME_HALF"] = bit_half
entry["FRAME_ROW"] = bit_row
entry["FRAME_COLUMN"] = bit_col
entry["WORDS"] = [word, word+1]
entry["WORDS"] = [word, word + 1]
database["tiles"][tile]["cfgcol"] = entry
if database["tiles"][tile]["props"]["TILE_TYPE"] in ("CLBLL_L", "CLBLM_L"):
col = int(db_tile_prop[tile]["COLUMN"])
row = int(db_tile_prop[tile]["ROW"])
right_tile = loc_to_tile[(col+1, row)]
right_tile = loc_to_tile[(col + 1, row)]
database["tiles"][right_tile]["cfgcol"] = entry
if database["tiles"][tile]["props"]["TILE_TYPE"] in ("CLBLL_R", "CLBLM_R"):
col = int(db_tile_prop[tile]["COLUMN"])
row = int(db_tile_prop[tile]["ROW"])
left_tile = loc_to_tile[(col-1, row)]
left_tile = loc_to_tile[(col - 1, row)]
database["tiles"][left_tile]["cfgcol"] = entry
@ -133,4 +138,3 @@ print("Number of tiles with assigned column: %d" % tile_cfgcol_count)
with open("%s.json" % sys.argv[1], "w") as f:
print(json.dumps(database, sort_keys=True, indent="\t"), file=f)

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python3
import os, sys, json, re
import os
import sys
import json
import re
from io import StringIO
import argparse
@ -37,13 +40,17 @@ else:
def get_setting(name):
return os.getenv(name)
db_dir = os.path.join(get_setting("XRAY_DATABASE_DIR"), get_setting("XRAY_DATABASE"))
db_dir = os.path.join(get_setting("XRAY_DATABASE_DIR"),
get_setting("XRAY_DATABASE"))
def db_open(fn):
filename = os.path.join(db_dir, fn)
if not os.path.exists(filename):
return StringIO("")
return open(os.path.join(db_dir, fn))
def out_open(fn):
out_dir = os.path.join(args.output, get_setting("XRAY_DATABASE"))
os.makedirs(out_dir, exist_ok=True)
@ -51,6 +58,7 @@ def out_open(fn):
print("Writing %s" % fp)
return open(fp, "w")
clb_bitgroups_db = [
# copy&paste from zero_db in dbfixup.py
"00_21 00_22 00_26 01_28|00_25 01_20 01_21 01_24",
@ -84,9 +92,9 @@ hclk_bitgroups_db = [
# groupings for SNWE bits in frames 2..7
for i in range(0, 64, 4):
clb_bitgroups_db.append("02_%02d 03_%02d 05_%02d 06_%02d 07_%02d|05_%02d 03_%02d 04_%02d 04_%02d" %
(i+1, i, i, i, i+1, i+3, i+1, i+1, i+2))
(i + 1, i, i, i, i + 1, i + 3, i + 1, i + 1, i + 2))
clb_bitgroups_db.append("02_%02d 04_%02d 05_%02d 05_%02d 06_%02d|02_%02d 03_%02d 04_%02d 07_%02d" %
(i+2, i, i+1, i+2, i+2, i+3, i+2, i+3, i+3))
(i + 2, i, i + 1, i + 2, i + 2, i + 3, i + 2, i + 3, i + 3))
clb_left_bits = set()
clb_right_bits = set()
@ -108,6 +116,7 @@ for entry in hclk_bitgroups_db:
for bit in b.split():
hclk_right_bits.add(bit)
class UnionFind:
def __init__(self):
self.parents = dict()
@ -152,8 +161,8 @@ with db_open("tilegrid.json") as f:
"tiles": {
"NULL": {
"grid_x": 0,
"grid_y":0,
"type":"NULL",
"grid_y": 0,
"type": "NULL",
}
}
}
@ -228,10 +237,13 @@ grid_range = None
grid_map = dict()
with out_open("index.html") as f:
print("<html><title>X-Ray %s Database</title><body>" % get_setting("XRAY_DATABASE").upper(), file=f)
print("<h3>X-Ray %s Database</h3>" % get_setting("XRAY_DATABASE").upper(), file=f)
print("<html><title>X-Ray %s Database</title><body>" %
get_setting("XRAY_DATABASE").upper(), file=f)
print("<h3>X-Ray %s Database</h3>" %
get_setting("XRAY_DATABASE").upper(), file=f)
print("<p><b>Part: %s<br/>ROI: %s<br/>ROI Frames: %s</b></p>" % (get_setting("XRAY_PART"), get_setting("XRAY_ROI"), get_setting("XRAY_ROI_FRAMES")), file=f)
print("<p><b>Part: %s<br/>ROI: %s<br/>ROI Frames: %s</b></p>" %
(get_setting("XRAY_PART"), get_setting("XRAY_ROI"), get_setting("XRAY_ROI_FRAMES")), file=f)
for tilename, tiledata in grid["tiles"].items():
grid_x = tiledata["grid_x"]
@ -248,25 +260,33 @@ with out_open("index.html") as f:
print("<table border>", file=f)
for grid_y in range(grid_range[1], grid_range[3]+1):
for grid_y in range(grid_range[1], grid_range[3] + 1):
print("<tr>", file=f)
for grid_x in range(grid_range[0], grid_range[2]+1):
for grid_x in range(grid_range[0], grid_range[2] + 1):
tilename = grid_map[(grid_x, grid_y)]
tiledata = grid["tiles"][tilename]
segdata = None
bgcolor = "#aaaaaa"
if tiledata["type"] in ["INT_L", "INT_R"]: bgcolor="#aaaaff"
if tiledata["type"] in ["CLBLL_L", "CLBLL_R"]: bgcolor="#ffffaa"
if tiledata["type"] in ["CLBLM_L", "CLBLM_R"]: bgcolor="#ffaaaa"
if tiledata["type"] in ["HCLK_L", "HCLK_R"]: bgcolor="#aaffaa"
if tiledata["type"] in ["INT_L", "INT_R"]:
bgcolor = "#aaaaff"
if tiledata["type"] in ["CLBLL_L", "CLBLL_R"]:
bgcolor = "#ffffaa"
if tiledata["type"] in ["CLBLM_L", "CLBLM_R"]:
bgcolor = "#ffaaaa"
if tiledata["type"] in ["HCLK_L", "HCLK_R"]:
bgcolor = "#aaffaa"
if tiledata["type"] in ["BRAM_INT_INTERFACE_L", "BRAM_L"]: bgcolor="#aaffff"
if tiledata["type"] in ["BRAM_INT_INTERFACE_R", "BRAM_R"]: bgcolor="#aaffff"
if tiledata["type"] in ["BRAM_INT_INTERFACE_L", "BRAM_L"]:
bgcolor = "#aaffff"
if tiledata["type"] in ["BRAM_INT_INTERFACE_R", "BRAM_R"]:
bgcolor = "#aaffff"
if tiledata["type"] in ["INT_INTERFACE_L", "DSP_L"]: bgcolor="#ffaaff"
if tiledata["type"] in ["INT_INTERFACE_R", "DSP_R"]: bgcolor="#ffaaff"
if tiledata["type"] in ["INT_INTERFACE_L", "DSP_L"]:
bgcolor = "#ffaaff"
if tiledata["type"] in ["INT_INTERFACE_R", "DSP_R"]:
bgcolor = "#ffaaff"
title = [tilename]
@ -282,21 +302,25 @@ with out_open("index.html") as f:
if "segment" in tiledata:
if "baseaddr" in segdata:
title.append("Baseaddr: %s %d" % tuple(segdata["baseaddr"]))
title.append("Baseaddr: %s %d" %
tuple(segdata["baseaddr"]))
else:
print("Warning: no baseaddr in segment %s (via tile %s)." % (tiledata["segment"], tilename))
print("Warning: no baseaddr in segment %s (via tile %s)." %
(tiledata["segment"], tilename))
tilename = tilename.replace("INT_INTERFACE_", "INTF_")
tilename = tilename.replace("_X", "<br/>X")
tilename = tilename.replace("B_TERM", "B<br/>TERM")
print("<td bgcolor=\"%s\" align=\"center\" title=\"%s\"><span style=\"font-size:10px\">" % (bgcolor, "\n".join(title)), file=f)
print("<td bgcolor=\"%s\" align=\"center\" title=\"%s\"><span style=\"font-size:10px\">" %
(bgcolor, "\n".join(title)), file=f)
if "segment" in tiledata:
segtype = segdata["type"].lower()
print("<a style=\"text-decoration: none; color: black\" href=\"seg_%s.html\">%s</a></span></td>" %
(segtype, tilename.replace("_X", "<br/>X")), file=f)
else:
print("%s</span></td>" % tilename.replace("_X", "<br/>X").replace("B_TERM", "B<br/>TERM"), file=f)
print("%s</span></td>" % tilename.replace("_X",
"<br/>X").replace("B_TERM", "B<br/>TERM"), file=f)
print("</tr>", file=f)
@ -309,9 +333,11 @@ with out_open("index.html") as f:
for segtype in sorted(segbits.keys()):
with out_open("seg_%s.html" % segtype) as f:
print("<html><title>X-Ray %s Database: %s</title><body>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
print("<html><title>X-Ray %s Database: %s</title><body>" %
(get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
if segtype in ["hclk_l", "hclk_r"]:
print("<h3>X-Ray %s Database: %s Segment</h3>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
print("<h3>X-Ray %s Database: %s Segment</h3>" %
(get_setting("XRAY_DATABASE").upper(), segtype.upper()), file=f)
else:
print("<h3>X-Ray %s Database: %s Segment (%s Tile + %s Tile)</h3>" % (get_setting("XRAY_DATABASE").upper(), segtype.upper(),
segtype.upper(), re.sub("clbl[lm]|bram[0-4]|dsp[0-4]", "int", segtype).upper()), file=f)
@ -364,12 +390,14 @@ function oml() {
print("<tr>", file=f)
print("<th width=\"30\"></th>", file=f)
for frameidx in range(segframes[segtype]):
print("<th width=\"30\"><span style=\"font-size:10px\">%d</span></th>" % frameidx, file=f)
print("<th width=\"30\"><span style=\"font-size:10px\">%d</span></th>" %
frameidx, file=f)
print("</tr>", file=f)
for bitidx in range(31 if (segtype in ["hclk_l", "hclk_r"]) else 63, -1, -1):
print("<tr>", file=f)
print("<th align=\"right\"><span style=\"font-size:10px\">%d</span></th>" % bitidx, file=f)
print(
"<th align=\"right\"><span style=\"font-size:10px\">%d</span></th>" % bitidx, file=f)
for frameidx in range(segframes[segtype]):
bit_pos = "%02d_%02d" % (frameidx, bitidx)
bit_name = segbits_r[segtype][bit_pos] if bit_pos in segbits_r[segtype] else None
@ -420,7 +448,8 @@ function oml() {
else:
bgcolor = "#ff0000"
m = re.search(r"\.([ABCD]5?)FF\.([A-Z]+(\.A|\.B)?)$", bit_name)
m = re.search(
r"\.([ABCD]5?)FF\.([A-Z]+(\.A|\.B)?)$", bit_name)
if m:
bgcolor = "#aaffaa"
if m.group(2) == "ZINI":
@ -583,12 +612,14 @@ function oml() {
print("<p/>", file=f)
print("<h4>%s</h4>" % prefix, file=f)
print("<table cellspacing=0>", file=f)
print("<tr><th width=\"400\" align=\"left\">Bit Name</th><th>Position</th></tr>", file=f)
print(
"<tr><th width=\"400\" align=\"left\">Bit Name</th><th>Position</th></tr>", file=f)
trstyle = ""
for bit_name, bit_pos in sorted(bits):
trstyle = " bgcolor=\"#dddddd\"" if trstyle == "" else ""
print("<tr%s><td>%s</td><td>%s</td></tr>" % (trstyle, bit_name, bit_pos), file=f)
print("<tr%s><td>%s</td><td>%s</td></tr>" %
(trstyle, bit_name, bit_pos), file=f)
print("</table>", file=f)
@ -663,7 +694,8 @@ function oml() {
print("<a id=\"b%s\"/>" % bit, file=f)
print("<script><!--", file=f)
print("grp2bits['%s'] = ['%s'];" % (grp_bits[0], "', '".join(grp_bits)), file=f)
print("grp2bits['%s'] = ['%s'];" %
(grp_bits[0], "', '".join(grp_bits)), file=f)
for bit in grp_bits:
print("bit2grp['%s'] = '%s';" % (bit, grp_bits[0]), file=f)
print("//--></script>", file=f)
@ -682,8 +714,10 @@ function oml() {
line = " --><td>%s</td>" % (pip)
for bit in grp_bits:
c = "-"
if bit in routebits[segtype] and pip in routebits[segtype][bit]: c = "1"
if bit in routezbits[segtype] and pip in routezbits[segtype][bit]: c = "0"
if bit in routebits[segtype] and pip in routebits[segtype][bit]:
c = "1"
if bit in routezbits[segtype] and pip in routezbits[segtype][bit]:
c = "0"
line = "%s%s<td align=\"center\">%s</td>" % (c, line, c)
lines.append(line)
@ -699,8 +733,10 @@ function oml() {
if len(shared_bits[bit]) > 1:
if first_note:
print("<p><b>Note(s):</b><br/>", file=f)
print("Warning: Groups sharing bit %s: %s." % (bit, ", ".join(sorted(shared_bits[bit]))))
print("Groups sharing bit <b>%s</b>: %s.<br/>" % (bit, ", ".join(sorted(shared_bits[bit]))), file=f)
print("Warning: Groups sharing bit %s: %s." %
(bit, ", ".join(sorted(shared_bits[bit]))))
print("Groups sharing bit <b>%s</b>: %s.<br/>" %
(bit, ", ".join(sorted(shared_bits[bit]))), file=f)
first_note = False
if not first_note:
print("</p>", file=f)
@ -708,13 +744,15 @@ function oml() {
for tile_type in segtiles[segtype]:
print("<h3>Tile %s Pseudo PIPs</h3>" % tile_type, file=f)
print("<table cellspacing=0>", file=f)
print("<tr><th width=\"500\" align=\"left\">PIP</th><th>Type</th></tr>", file=f)
print(
"<tr><th width=\"500\" align=\"left\">PIP</th><th>Type</th></tr>", file=f)
trstyle = ""
with db_open("ppips_%s.db" % tile_type.lower()) as fi:
for line in fi:
pip_name, pip_type = line.split()
trstyle = " bgcolor=\"#dddddd\"" if trstyle == "" else ""
print("<tr%s><td>%s</td><td>%s</td></tr>" % (trstyle, pip_name, pip_type), file=f)
print("<tr%s><td>%s</td><td>%s</td></tr>" %
(trstyle, pip_name, pip_type), file=f)
print("</table>", file=f)
print("</div>", file=f)

View File

@ -44,28 +44,24 @@ TEST(BitFieldGetTest, SelectMidway) {
TEST(BitFieldSetTest, WriteOneBit) {
uint32_t actual = prjxray::bit_field_set(
static_cast<uint32_t>(0x0), 23, 23,
static_cast<uint32_t>(0x1));
static_cast<uint32_t>(0x0), 23, 23, static_cast<uint32_t>(0x1));
EXPECT_EQ(actual, static_cast<uint32_t>(0x800000));
}
TEST(BitFieldSetTest, WriteOneBitWithOutOfRangeValue) {
uint32_t actual = prjxray::bit_field_set(
static_cast<uint32_t>(0x0), 23, 23,
static_cast<uint32_t>(0x3));
static_cast<uint32_t>(0x0), 23, 23, static_cast<uint32_t>(0x3));
EXPECT_EQ(actual, static_cast<uint32_t>(0x800000));
}
TEST(BitFieldSetTest, WriteMultipleBits) {
uint32_t actual = prjxray::bit_field_set(
static_cast<uint32_t>(0x0), 18, 8,
static_cast<uint32_t>(0x123));
static_cast<uint32_t>(0x0), 18, 8, static_cast<uint32_t>(0x123));
EXPECT_EQ(actual, static_cast<uint32_t>(0x12300));
}
TEST(BitFieldSetTest, WriteMultipleBitsWithOutOfRangeValue) {
uint32_t actual = prjxray::bit_field_set(
static_cast<uint32_t>(0x0), 18, 8,
static_cast<uint32_t>(0x1234));
static_cast<uint32_t>(0x0), 18, 8, static_cast<uint32_t>(0x1234));
EXPECT_EQ(actual, static_cast<uint32_t>(0x23400));
}

View File

@ -10,18 +10,18 @@ namespace prjxray {
static constexpr const char kSegbitsGlobPattern[] = "segbits_*.db";
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> Database::segbits() const {
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> Database::segbits()
const {
std::vector<std::unique_ptr<prjxray::SegbitsFileReader>> segbits;
glob_t segbits_glob_results;
int ret = glob(absl::StrCat(db_path_, "/", kSegbitsGlobPattern).c_str(),
GLOB_NOSORT | GLOB_TILDE,
NULL, &segbits_glob_results);
GLOB_NOSORT | GLOB_TILDE, NULL, &segbits_glob_results);
if (ret < 0) {
return {};
}
for(size_t idx = 0; idx < segbits_glob_results.gl_pathc; idx++) {
for (size_t idx = 0; idx < segbits_glob_results.gl_pathc; idx++) {
auto this_segbit = SegbitsFileReader::InitWithFile(
segbits_glob_results.gl_pathv[idx]);
if (this_segbit) {

View File

@ -8,7 +8,7 @@
namespace prjxray {
template<typename WordType, typename ByteType>
template <typename WordType, typename ByteType>
class BigEndianSpan {
public:
constexpr static size_t kBytesPerElement = sizeof(WordType);
@ -21,15 +21,19 @@ class BigEndianSpan {
public:
operator WordType() const {
WordType word = 0;
for(size_t ii = 0; ii < kBytesPerElement; ++ii) {
word |= (static_cast<WordType>(bytes_[ii]) << ((kBytesPerElement - 1 - ii) * 8));
for (size_t ii = 0; ii < kBytesPerElement; ++ii) {
word |= (static_cast<WordType>(bytes_[ii])
<< ((kBytesPerElement - 1 - ii) * 8));
}
return word;
}
value_type& operator=(WordType word) {
for (size_t ii = 0; ii < kBytesPerElement; ++ii) {
bytes_[ii] = ((word >> ((kBytesPerElement - 1 - ii) * 8)) & 0xFF);
bytes_[ii] =
((word >>
((kBytesPerElement - 1 - ii) * 8)) &
0xFF);
}
return *this;
}
@ -37,7 +41,7 @@ class BigEndianSpan {
protected:
friend class BigEndianSpan<WordType, ByteType>;
value_type(absl::Span<ByteType> bytes) : bytes_(bytes) {};
value_type(absl::Span<ByteType> bytes) : bytes_(bytes){};
private:
absl::Span<ByteType> bytes_;
@ -46,15 +50,13 @@ class BigEndianSpan {
class iterator
: public std::iterator<std::input_iterator_tag, value_type> {
public:
value_type operator*() const {
return value_type(bytes_);
}
value_type operator*() const { return value_type(bytes_); }
bool operator==(const iterator &other) const {
bool operator==(const iterator& other) const {
return bytes_ == other.bytes_;
}
bool operator!=(const iterator &other) const {
bool operator!=(const iterator& other) const {
return bytes_ != other.bytes_;
}
@ -66,17 +68,16 @@ class BigEndianSpan {
protected:
friend class BigEndianSpan<WordType, ByteType>;
iterator(absl::Span<ByteType> bytes) : bytes_(bytes) {};
iterator(absl::Span<ByteType> bytes) : bytes_(bytes){};
private:
absl::Span<ByteType> bytes_;
};
using pointer = value_type*;
using reference = value_type&;
BigEndianSpan(absl::Span<ByteType> bytes) : bytes_(bytes) {};
BigEndianSpan(absl::Span<ByteType> bytes) : bytes_(bytes){};
constexpr size_type size() const noexcept {
return bytes_.size() / kBytesPerElement;
@ -88,7 +89,7 @@ class BigEndianSpan {
value_type operator[](size_type pos) const {
assert(pos >= 0 && pos < size());
return value_type(bytes_.subspan((pos*kBytesPerElement)));
return value_type(bytes_.subspan((pos * kBytesPerElement)));
}
constexpr reference at(size_type pos) const {
@ -99,13 +100,12 @@ class BigEndianSpan {
iterator end() const { return iterator({}); }
private:
absl::Span<ByteType> bytes_;
};
template<typename WordType, typename Container>
template <typename WordType, typename Container>
BigEndianSpan<WordType, typename Container::value_type> make_big_endian_span(
Container &bytes) {
Container& bytes) {
return BigEndianSpan<WordType, typename Container::value_type>(
absl::Span<typename Container::value_type>(bytes));
}

View File

@ -3,37 +3,40 @@
namespace prjxray {
template<typename UInt>
template <typename UInt>
constexpr UInt bit_mask(const int bit) {
return (static_cast<UInt>(1) << bit);
}
template<typename UInt>
template <typename UInt>
constexpr UInt bit_sizeof() {
return sizeof(UInt) * 8;
}
template<typename UInt>
template <typename UInt>
constexpr UInt bit_all_ones() {
return ~static_cast<UInt>(0);
}
template<typename UInt>
template <typename UInt>
constexpr UInt bit_mask_range(const int top_bit, const int bottom_bit) {
return ((bit_all_ones<UInt>() >> (bit_sizeof<UInt>() - 1 - top_bit)) &
(bit_all_ones<UInt>() - bit_mask<UInt>(bottom_bit) +
static_cast<UInt>(1)));
}
template<typename UInt>
constexpr UInt bit_field_get(UInt value, const int top_bit, const int bottom_bit) {
return (value & bit_mask_range<UInt>(top_bit, bottom_bit)) >> bottom_bit;
template <typename UInt>
constexpr UInt bit_field_get(UInt value,
const int top_bit,
const int bottom_bit) {
return (value & bit_mask_range<UInt>(top_bit, bottom_bit)) >>
bottom_bit;
}
template<typename UInt, typename ValueType>
template <typename UInt, typename ValueType>
constexpr UInt bit_field_set(const UInt reg_value,
const int top_bit, const int bottom_bit,
const int top_bit,
const int bottom_bit,
const ValueType field_value) {
return ((reg_value & ~bit_mask_range<UInt>(top_bit, bottom_bit)) |
((static_cast<UInt>(field_value) << bottom_bit) &

View File

@ -11,8 +11,7 @@ namespace prjxray {
class Database {
public:
Database(const std::string &path)
: db_path_(path) {}
Database(const std::string& path) : db_path_(path) {}
std::vector<std::unique_ptr<SegbitsFileReader>> segbits() const;

View File

@ -13,7 +13,7 @@ class MemoryMappedFile {
~MemoryMappedFile();
static std::unique_ptr<MemoryMappedFile> InitWithFile(
const std::string &path);
const std::string& path);
void* const data() const { return data_; }
const size_t size() const { return size_; }
@ -23,10 +23,9 @@ class MemoryMappedFile {
}
private:
MemoryMappedFile(void *data, size_t size)
: data_(data), size_(size) {};
MemoryMappedFile(void* data, size_t size) : data_(data), size_(size){};
void *data_;
void* data_;
size_t size_;
};

View File

@ -19,7 +19,7 @@ class SegbitsFileReader {
private:
friend SegbitsFileReader;
value_type(const absl::string_view &view);
value_type(const absl::string_view& view);
absl::string_view tag_;
absl::string_view bit_;
@ -31,9 +31,11 @@ class SegbitsFileReader {
iterator& operator++();
bool operator==(iterator other) const {
return view_ == other.view_; }
return view_ == other.view_;
}
bool operator!=(iterator other) const {
return !(*this == other);}
return !(*this == other);
}
const value_type& operator*() const { return value_; }
const value_type* operator->() const { return &value_; }
@ -50,14 +52,14 @@ class SegbitsFileReader {
};
static std::unique_ptr<SegbitsFileReader> InitWithFile(
const std::string &path);
const std::string& path);
iterator begin();
iterator end();
private:
SegbitsFileReader(std::unique_ptr<MemoryMappedFile> &&mapped_file)
: mapped_file_(std::move(mapped_file)) {};
SegbitsFileReader(std::unique_ptr<MemoryMappedFile>&& mapped_file)
: mapped_file_(std::move(mapped_file)){};
std::unique_ptr<MemoryMappedFile> mapped_file_;
};

View File

@ -24,8 +24,8 @@ class BitstreamReader {
public:
iterator& operator++();
bool operator==(const iterator &other) const;
bool operator!=(const iterator &other) const;
bool operator==(const iterator& other) const;
bool operator!=(const iterator& other) const;
const value_type& operator*() const;
const value_type* operator->() const;
@ -42,26 +42,27 @@ class BitstreamReader {
// Construct a reader from a collection of 32-bit, big-endian words.
// Assumes that any sync word has already been removed.
BitstreamReader(std::vector<uint32_t> &&words);
BitstreamReader(std::vector<uint32_t>&& words);
// Construct a `BitstreamReader` from a Container of bytes.
// Any bytes preceding an initial sync word are ignored.
template<typename T>
template <typename T>
static absl::optional<BitstreamReader> InitWithBytes(T bitstream);
const std::vector<uint32_t> &words() { return words_; };
const std::vector<uint32_t>& words() { return words_; };
// Returns an iterator that yields `ConfigurationPackets`
// as read from the bitstream.
iterator begin();
iterator end();
private:
static std::array<uint8_t, 4> kSyncWord;
std::vector<uint32_t> words_;
};
template<typename T>
template <typename T>
absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T bitstream) {
// If this is really a Xilinx 7-Series bitstream, there will be a sync
// word somewhere toward the beginning.
@ -74,8 +75,8 @@ absl::optional<BitstreamReader> BitstreamReader::InitWithBytes(T bitstream) {
// Wrap the provided container in a span that strips off the preamble.
absl::Span<typename T::value_type> bitstream_span(bitstream);
auto config_packets = bitstream_span.subspan(
sync_pos - bitstream.begin());
auto config_packets =
bitstream_span.subspan(sync_pos - bitstream.begin());
// Convert the bytes into 32-bit, big-endian words.
auto big_endian_reader = make_big_endian_span<uint32_t>(config_packets);

View File

@ -16,18 +16,18 @@ enum class BlockType : unsigned int {
/* reserved = 0x3, */
};
std::ostream &operator<<(std::ostream &o, BlockType value);
std::ostream& operator<<(std::ostream& o, BlockType value);
} // namespace xc7series
} // namespace xilinx
} // namespace prjxray
namespace YAML {
template<>
template <>
struct convert<prjxray::xilinx::xc7series::BlockType> {
static Node encode(const prjxray::xilinx::xc7series::BlockType &rhs);
static Node encode(const prjxray::xilinx::xc7series::BlockType& rhs);
static bool decode(const Node& node,
prjxray::xilinx::xc7series::BlockType &lhs);
prjxray::xilinx::xc7series::BlockType& lhs);
};
} // namespace YAML

View File

@ -15,14 +15,14 @@ namespace xc7series {
class Configuration {
public:
using FrameMap = std::map<FrameAddress,
absl::Span<uint32_t>>;
using FrameMap = std::map<FrameAddress, absl::Span<uint32_t>>;
template<typename Collection>
template <typename Collection>
static absl::optional<Configuration> InitWithPackets(
const Part& part, Collection &packets);
const Part& part,
Collection& packets);
Configuration(const Part& part, const FrameMap &frames)
Configuration(const Part& part, const FrameMap& frames)
: part_(part), frames_(std::move(frames)) {}
const Part& part() const { return part_; }
@ -35,9 +35,10 @@ class Configuration {
FrameMap frames_;
};
template<typename Collection>
template <typename Collection>
absl::optional<Configuration> Configuration::InitWithPackets(
const Part& part, Collection &packets) {
const Part& part,
Collection& packets) {
// Registers that can be directly written to.
uint32_t command_register = 0;
uint32_t frame_address_register = 0;
@ -56,46 +57,55 @@ absl::optional<Configuration> Configuration::InitWithPackets(
switch (packet.address()) {
case ConfigurationRegister::MASK:
if (packet.data().size() < 1) continue;
if (packet.data().size() < 1)
continue;
mask_register = packet.data()[0];
break;
case ConfigurationRegister::CTL1:
if (packet.data().size() < 1) continue;
ctl1_register = packet.data()[0] & mask_register;
if (packet.data().size() < 1)
continue;
ctl1_register =
packet.data()[0] & mask_register;
break;
case ConfigurationRegister::CMD:
if (packet.data().size() < 1) continue;
if (packet.data().size() < 1)
continue;
command_register = packet.data()[0];
// Writes to CMD trigger an immediate action. In the case of
// WCFG, that is just setting a flag for the next FDIR.
// Writes to CMD trigger an immediate action. In
// the case of WCFG, that is just setting a flag
// for the next FDIR.
if (command_register == 0x1) {
start_new_write = true;
}
break;
case ConfigurationRegister::IDCODE:
// This really should be a one-word write.
if (packet.data().size() < 1) continue;
if (packet.data().size() < 1)
continue;
// If the IDCODE doesn't match our expected part,
// consider the bitstream invalid.
// If the IDCODE doesn't match our expected
// part, consider the bitstream invalid.
if (packet.data()[0] != part.idcode()) {
return {};
}
break;
case ConfigurationRegister::FAR:
// This really should be a one-word write.
if (packet.data().size() < 1) continue;
if (packet.data().size() < 1)
continue;
frame_address_register = packet.data()[0];
// Per UG470, the command present in the CMD register
// is executed each time the FAR register is laoded
// with a new value. As we only care about WCFG
// commands, just check that here. CTRL1 is completely
// undocumented but looking at generated bitstreams, bit 21
// is used when per-frame CRC is enabled. Setting this
// bit seems to inhibit the re-execution of CMD during a
// FAR write. In practice, this is used so FAR writes
// can be added in the bitstream to show progress
// Per UG470, the command present in the CMD
// register is executed each time the FAR
// register is laoded with a new value. As we
// only care about WCFG commands, just check
// that here. CTRL1 is completely undocumented
// but looking at generated bitstreams, bit 21
// is used when per-frame CRC is enabled.
// Setting this bit seems to inhibit the
// re-execution of CMD during a FAR write. In
// practice, this is used so FAR writes can be
// added in the bitstream to show progress
// markers without impacting the actual write
// operation.
if (bit_field_get(ctl1_register, 21, 21) == 0 &&
@ -105,28 +115,31 @@ absl::optional<Configuration> Configuration::InitWithPackets(
break;
case ConfigurationRegister::FDRI: {
if (start_new_write) {
current_frame_address = frame_address_register;
current_frame_address =
frame_address_register;
start_new_write = false;
}
// 7-series frames are 101-words long. Writes to this
// register can be multiples of that to do
// auto-incrementing block writes.
for (size_t ii = 0;
ii < packet.data().size();
// 7-series frames are 101-words long. Writes
// to this register can be multiples of that to
// do auto-incrementing block writes.
for (size_t ii = 0; ii < packet.data().size();
ii += kWordsPerFrame) {
frames[current_frame_address] =
packet.data().subspan(
ii, kWordsPerFrame);
auto next_address = part.GetNextFrameAddress(
auto next_address =
part.GetNextFrameAddress(
current_frame_address);
if (!next_address) break;
if (!next_address)
break;
// Bitstreams appear to have 2 frames of
// padding between rows.
if (next_address->row_address() !=
current_frame_address.row_address()) {
current_frame_address
.row_address()) {
ii += 2 * kWordsPerFrame;
}
current_frame_address = *next_address;
@ -141,7 +154,6 @@ absl::optional<Configuration> Configuration::InitWithPackets(
return Configuration(part, frames);
}
} // namespace xc7series
} // namespace xilinx
} // namespace prjxray

View File

@ -15,7 +15,7 @@ class ConfigurationFrameRange {
ConfigurationFrameRange() : begin_(0), end_(0) {}
ConfigurationFrameRange(FrameAddress begin, FrameAddress end)
: begin_(begin), end_(end) {};
: begin_(begin), end_(end){};
FrameAddress begin() const { return begin_; }
FrameAddress end() const { return end_; }
@ -35,13 +35,13 @@ class ConfigurationFrameRange {
} // namespace prjxray
namespace YAML {
template<>
template <>
struct convert<prjxray::xilinx::xc7series::ConfigurationFrameRange> {
static Node encode(
const prjxray::xilinx::xc7series::ConfigurationFrameRange &rhs);
const prjxray::xilinx::xc7series::ConfigurationFrameRange& rhs);
static bool decode(
const Node& node,
prjxray::xilinx::xc7series::ConfigurationFrameRange &lhs);
prjxray::xilinx::xc7series::ConfigurationFrameRange& lhs);
};
} // namespace YAML
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CONFIGURATION_FRAME_RANGE_H_

View File

@ -24,11 +24,14 @@ class ConfigurationPacket {
/* reserved = 3 */
};
ConfigurationPacket(unsigned int header_type, Opcode opcode,
ConfigurationPacket(unsigned int header_type,
Opcode opcode,
ConfigurationRegister address,
const absl::Span<uint32_t> &data)
: header_type_(header_type), opcode_(opcode),
address_(address), data_(std::move(data)) {}
const absl::Span<uint32_t>& data)
: header_type_(header_type),
opcode_(opcode),
address_(address),
data_(std::move(data)) {}
// Attempt to read a configuration packet from a sequence of
// 32-bit, big-endian words. If successful, returns the packet read and
@ -39,12 +42,12 @@ class ConfigurationPacket {
// returned.
static ParseResult InitWithWords(
absl::Span<uint32_t> words,
const ConfigurationPacket *previous_packet = nullptr);
const ConfigurationPacket* previous_packet = nullptr);
unsigned int header_type() const { return header_type_; }
const Opcode opcode() const { return opcode_; }
const ConfigurationRegister address() const { return address_; }
const absl::Span<uint32_t> &data() const { return data_; }
const absl::Span<uint32_t>& data() const { return data_; }
private:
unsigned int header_type_;
@ -53,7 +56,7 @@ class ConfigurationPacket {
absl::Span<uint32_t> data_;
};
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet);
std::ostream& operator<<(std::ostream& o, const ConfigurationPacket& packet);
} // namespace xc7series
} // namespace xilinx

View File

@ -30,7 +30,7 @@ enum class ConfigurationRegister : unsigned int {
BSPI = 0x1F,
};
std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value);
std::ostream& operator<<(std::ostream& o, const ConfigurationRegister& value);
} // namespace xc7series
} // namespace xilinx

View File

@ -15,11 +15,13 @@ class FrameAddress {
public:
FrameAddress() : address_(0) {}
FrameAddress(uint32_t address)
: address_(address) {};
FrameAddress(uint32_t address) : address_(address){};
FrameAddress(BlockType block_type, bool is_bottom_half_rows,
uint8_t row, uint16_t column, uint8_t minor);
FrameAddress(BlockType block_type,
bool is_bottom_half_rows,
uint8_t row,
uint16_t column,
uint8_t minor);
operator uint32_t() const { return address_; }
@ -33,18 +35,18 @@ class FrameAddress {
uint32_t address_;
};
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr);
std::ostream& operator<<(std::ostream& o, const FrameAddress& addr);
} // namespace xc7series
} // namespace xilinx
} // namespace prjxray
namespace YAML {
template<>
template <>
struct convert<prjxray::xilinx::xc7series::FrameAddress> {
static Node encode(const prjxray::xilinx::xc7series::FrameAddress &rhs);
static Node encode(const prjxray::xilinx::xc7series::FrameAddress& rhs);
static bool decode(const Node& node,
prjxray::xilinx::xc7series::FrameAddress &lhs);
prjxray::xilinx::xc7series::FrameAddress& lhs);
};
} // namespace YAML
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_FRAME_ADDRESS_H_

View File

@ -4,8 +4,8 @@
#include <vector>
#include <absl/types/optional.h>
#include <prjxray/xilinx/xc7series/frame_address.h>
#include <prjxray/xilinx/xc7series/configuration_frame_range.h>
#include <prjxray/xilinx/xc7series/frame_address.h>
namespace prjxray {
namespace xilinx {
@ -13,23 +13,25 @@ namespace xc7series {
class Part {
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
// conversion but shouldn't be used otherwise.
Part() : idcode_(0), frame_ranges_() {}
Part(uint32_t idcode,
const std::vector<ConfigurationFrameRange> &ranges)
const std::vector<ConfigurationFrameRange>& ranges)
: idcode_(idcode), frame_ranges_(std::move(ranges)) {}
uint32_t idcode() const { return idcode_; }
const std::vector<ConfigurationFrameRange>&
configuration_frame_ranges() const { return frame_ranges_; }
const std::vector<ConfigurationFrameRange>& configuration_frame_ranges()
const {
return frame_ranges_;
}
absl::optional<FrameAddress>
GetNextFrameAddress(FrameAddress address) const;
absl::optional<FrameAddress> GetNextFrameAddress(
FrameAddress address) const;
private:
uint32_t idcode_;
@ -43,11 +45,11 @@ class Part {
} // namespace prjxray
namespace YAML {
template<>
template <>
struct convert<prjxray::xilinx::xc7series::Part> {
static Node encode(const prjxray::xilinx::xc7series::Part &rhs);
static Node encode(const prjxray::xilinx::xc7series::Part& rhs);
static bool decode(const Node& node,
prjxray::xilinx::xc7series::Part &lhs);
prjxray::xilinx::xc7series::Part& lhs);
};
} // namespace YAML

View File

@ -2,17 +2,17 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace prjxray {
std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
const std::string &path) {
const std::string& path) {
int fd = open(path.c_str(), O_RDONLY, 0);
if (fd == -1) return nullptr;
if (fd == -1)
return nullptr;
struct stat statbuf;
if (fstat(fd, &statbuf) < 0) {
@ -29,7 +29,7 @@ std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
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);
// If mmap() succeeded, the fd is no longer needed as the mapping will
@ -37,7 +37,8 @@ std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
// anyway.
close(fd);
if (file_map == MAP_FAILED) return nullptr;
if (file_map == MAP_FAILED)
return nullptr;
return std::unique_ptr<MemoryMappedFile>(
new MemoryMappedFile(file_map, statbuf.st_size));
@ -47,4 +48,4 @@ MemoryMappedFile::~MemoryMappedFile() {
munmap(data_, size_);
}
} // namepsace prjxray
} // namespace prjxray

View File

@ -3,18 +3,18 @@
namespace prjxray {
std::unique_ptr<SegbitsFileReader> SegbitsFileReader::InitWithFile(
const std::string &path) {
const std::string& path) {
auto mapped_file = MemoryMappedFile::InitWithFile(path);
if (!mapped_file) return nullptr;
if (!mapped_file)
return nullptr;
return std::unique_ptr<SegbitsFileReader>(
new SegbitsFileReader(std::move(mapped_file)));
}
SegbitsFileReader::iterator SegbitsFileReader::begin() {
return iterator(absl::string_view(
static_cast<const char*>(mapped_file_->data()),
return iterator(
absl::string_view(static_cast<const char*>(mapped_file_->data()),
mapped_file_->size()));
}
@ -22,7 +22,7 @@ SegbitsFileReader::iterator SegbitsFileReader::end() {
return iterator(absl::string_view());
}
SegbitsFileReader::value_type::value_type(const absl::string_view &view) {
SegbitsFileReader::value_type::value_type(const absl::string_view& view) {
size_t separator_start = view.find_first_of(" \t");
if (separator_start == absl::string_view::npos) {
tag_ = view;
@ -55,5 +55,4 @@ SegbitsFileReader::iterator& SegbitsFileReader::iterator::operator++() {
return *this;
}
} // namespace prjxray

View File

@ -6,7 +6,8 @@
#include <gtest/gtest.h>
TEST(SegbitsFileReaderTest, NonExistantFileReturnsNull) {
EXPECT_FALSE(prjxray::SegbitsFileReader::InitWithFile("does_not_exist"));
EXPECT_FALSE(
prjxray::SegbitsFileReader::InitWithFile("does_not_exist"));
}
TEST(SegbitsFileReaderTest, ZeroLengthFileYieldsNoItems) {
@ -66,8 +67,8 @@ TEST(SegbitsFileReaderTest, FileWithOneEntryWithExtraWhitespace) {
}
TEST(SegbitsFileReaderTest, FileWithTwoEntries) {
auto segbits_reader = prjxray::SegbitsFileReader::InitWithFile(
"two_entries.segbits");
auto segbits_reader =
prjxray::SegbitsFileReader::InitWithFile("two_entries.segbits");
ASSERT_TRUE(segbits_reader);
auto iter = segbits_reader->begin();

View File

@ -6,7 +6,7 @@ namespace xc7series {
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)) {}
BitstreamReader::iterator BitstreamReader::begin() {
@ -23,14 +23,12 @@ BitstreamReader::iterator::iterator(absl::Span<uint32_t> words) {
++(*this);
}
BitstreamReader::iterator&
BitstreamReader::iterator::operator++() {
BitstreamReader::iterator& BitstreamReader::iterator::operator++() {
do {
auto new_result = ConfigurationPacket::InitWithWords(
parse_result_.first,
parse_result_.second.has_value() ?
parse_result_.second.operator->() :
nullptr);
parse_result_.first, parse_result_.second.has_value()
? parse_result_.second.operator->()
: nullptr);
// If the a valid header is being found but there are
// insufficient words to yield a packet, consider it the end.
@ -41,8 +39,7 @@ BitstreamReader::iterator::operator++() {
words_ = parse_result_.first;
parse_result_ = new_result;
} while (!parse_result_.first.empty() &&
!parse_result_.second);
} while (!parse_result_.first.empty() && !parse_result_.second);
if (!parse_result_.second) {
words_ = absl::Span<uint32_t>();
@ -51,21 +48,21 @@ BitstreamReader::iterator::operator++() {
return *this;
}
bool BitstreamReader::iterator::operator==(const iterator &other) const {
bool BitstreamReader::iterator::operator==(const iterator& other) const {
return words_ == other.words_;
}
bool BitstreamReader::iterator::operator!=(const iterator &other) const {
bool BitstreamReader::iterator::operator!=(const iterator& other) const {
return !(*this == other);
}
const BitstreamReader::value_type&
BitstreamReader::iterator::operator*() const {
const BitstreamReader::value_type& BitstreamReader::iterator::operator*()
const {
return *(parse_result_.second);
}
const BitstreamReader::value_type*
BitstreamReader::iterator::operator->() const {
const BitstreamReader::value_type* BitstreamReader::iterator::operator->()
const {
return parse_result_.second.operator->();
}

View File

@ -19,22 +19,15 @@ TEST(BitstreamReaderTest, InitWithOnlySyncReturnsObject) {
EXPECT_TRUE(reader);
}
TEST(BitstreamReaderTest,
InitWithSyncAfterNonWordSizedPaddingReturnsObject) {
std::vector<uint8_t> bitstream{
0xFF, 0xFE,
0xAA, 0x99, 0x55, 0x66
};
TEST(BitstreamReaderTest, InitWithSyncAfterNonWordSizedPaddingReturnsObject) {
std::vector<uint8_t> bitstream{0xFF, 0xFE, 0xAA, 0x99, 0x55, 0x66};
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
EXPECT_TRUE(reader);
}
TEST(BitstreamReaderTest,
InitWithSyncAfterWordSizedPaddingReturnsObject) {
std::vector<uint8_t> bitstream{
0xFF, 0xFE, 0xFD, 0xFC,
0xAA, 0x99, 0x55, 0x66
};
TEST(BitstreamReaderTest, InitWithSyncAfterWordSizedPaddingReturnsObject) {
std::vector<uint8_t> bitstream{0xFF, 0xFE, 0xFD, 0xFC,
0xAA, 0x99, 0x55, 0x66};
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
EXPECT_TRUE(reader);
}
@ -65,19 +58,16 @@ TEST(BitstreamReaderTest, ParseType2PacketWithoutType1Fails) {
EXPECT_EQ(reader->begin(), reader->end());
}
TEST(BitstreamReaderTest, ParsesType2AfterType1Packet) {
std::vector<uint8_t> bitstream{
0xAA, 0x99, 0x55, 0x66, // sync
0x28, 0x00, 0x60, 0x00, // Type 1 Read zero bytes from 6
0x48, 0x00, 0x00, 0x04, // Type 2 write of 4 words
0x1, 0x2, 0x3, 0x4,
0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC,
0xD, 0xE, 0xF, 0x10,
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10,
};
std::vector<uint32_t> data_words{
0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10};
std::vector<uint32_t> data_words{0x01020304, 0x05060708, 0x090A0B0C,
0x0D0E0F10};
auto reader = xc7series::BitstreamReader::InitWithBytes(bitstream);
ASSERT_TRUE(reader);

View File

@ -4,7 +4,7 @@ namespace prjxray {
namespace xilinx {
namespace xc7series {
std::ostream &operator<<(std::ostream &o, BlockType value) {
std::ostream& operator<<(std::ostream& o, BlockType value) {
switch (value) {
case BlockType::CLB_IO_CLK:
o << "CLB/IO/CLK";
@ -27,7 +27,7 @@ std::ostream &operator<<(std::ostream &o, BlockType value) {
namespace YAML {
Node convert<prjxray::xilinx::xc7series::BlockType>::encode(
const prjxray::xilinx::xc7series::BlockType &rhs) {
const prjxray::xilinx::xc7series::BlockType& rhs) {
switch (rhs) {
case prjxray::xilinx::xc7series::BlockType::CLB_IO_CLK:
return Node("CLB_IO_CLK");
@ -41,7 +41,8 @@ Node convert<prjxray::xilinx::xc7series::BlockType>::encode(
}
bool YAML::convert<prjxray::xilinx::xc7series::BlockType>::decode(
const Node &node, prjxray::xilinx::xc7series::BlockType &lhs) {
const Node& node,
prjxray::xilinx::xc7series::BlockType& lhs) {
auto type_str = node.as<std::string>();
if (type_str == "CLB_IO_CLK") {
@ -58,4 +59,4 @@ bool YAML::convert<prjxray::xilinx::xc7series::BlockType>::decode(
}
}
} // namespace YAML;
} // namespace YAML

View File

@ -17,7 +17,7 @@ namespace xc7series = prjxray::xilinx::xc7series;
namespace YAML {
Node convert<xc7series::ConfigurationFrameRange>::encode(
const xc7series::ConfigurationFrameRange &rhs) {
const xc7series::ConfigurationFrameRange& rhs) {
Node node;
node.SetTag("xilinx/xc7series/configuration_frame_range");
node["begin"] = rhs.begin();
@ -26,11 +26,11 @@ Node convert<xc7series::ConfigurationFrameRange>::encode(
}
bool convert<xc7series::ConfigurationFrameRange>::decode(
const Node &node,
xc7series::ConfigurationFrameRange &lhs) {
const Node& node,
xc7series::ConfigurationFrameRange& lhs) {
if (node.Tag() != "xilinx/xc7series/configuration_frame_range" ||
!node["begin"] ||
!node["end"]) return false;
!node["begin"] || !node["end"])
return false;
lhs = xc7series::ConfigurationFrameRange(
node["begin"].as<xc7series::FrameAddress>(),
@ -38,4 +38,4 @@ bool convert<xc7series::ConfigurationFrameRange>::decode(
return true;
}
} // namespace YAML;
} // namespace YAML

View File

@ -11,19 +11,20 @@ namespace xc7series {
std::pair<absl::Span<uint32_t>, absl::optional<ConfigurationPacket>>
ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
const ConfigurationPacket *previous_packet) {
const ConfigurationPacket* previous_packet) {
// Need at least one 32-bit word to have a valid packet header.
if (words.size() < 1) return {words, {}};
if (words.size() < 1)
return {words, {}};
uint32_t header_type = bit_field_get(words[0], 31, 29);
switch (header_type) {
case 0x0:
// Type 0 is emitted at the end of a configuration row when
// BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES. These seem
// to be padding that are interepreted as NOPs. Since Type 0
// packets don't exist according to UG470 and they seem to be
// zero-filled, just consume the bytes without generating a
// packet.
// Type 0 is emitted at the end of a configuration row
// when BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES.
// These seem to be padding that are interepreted as
// NOPs. Since Type 0 packets don't exist according to
// UG470 and they seem to be zero-filled, just consume
// the bytes without generating a packet.
return {words.subspan(1), {}};
case 0x1: {
Opcode opcode = static_cast<Opcode>(
@ -31,15 +32,16 @@ ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
ConfigurationRegister address =
static_cast<ConfigurationRegister>(
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
// no valid packet was found.
// If the full packet has not been received, return as
// though no valid packet was found.
if (data_word_count > words.size() - 1) {
return {words, {}};
}
return {words.subspan(data_word_count+1),
return {words.subspan(data_word_count + 1),
{{header_type, opcode, address,
words.subspan(1, data_word_count)}}};
}
@ -47,10 +49,11 @@ ConfigurationPacket::InitWithWords(absl::Span<uint32_t> words,
absl::optional<ConfigurationPacket> packet;
Opcode opcode = static_cast<Opcode>(
bit_field_get(words[0], 28, 27));
uint32_t data_word_count = bit_field_get(words[0], 26, 0);
uint32_t data_word_count =
bit_field_get(words[0], 26, 0);
// If the full packet has not been received, return as though
// no valid packet was found.
// If the full packet has not been received, return as
// though no valid packet was found.
if (data_word_count > words.size() - 1) {
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()) {
case ConfigurationPacket::Opcode::NOP:
o << "[NOP]" << std::endl;
@ -101,7 +104,7 @@ std::ostream& operator<<(std::ostream& o, const ConfigurationPacket &packet) {
o << std::setw(8) << std::hex;
o << packet.data()[ii] << " ";
if ((ii+1) % 4 == 0) {
if ((ii + 1) % 4 == 0) {
o << std::endl;
}
}

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 MakeType1(const int opcode, const int address,
constexpr uint32_t MakeType1(const int opcode,
const int address,
const int word_count) {
return prjxray::bit_field_set<uint32_t>(
prjxray::bit_field_set<uint32_t>(
prjxray::bit_field_set<uint32_t>(
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x1),
28, 27, opcode),
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x1), 28, 27,
opcode),
26, 13, address),
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) {
return prjxray::bit_field_set<uint32_t>(
prjxray::bit_field_set<uint32_t>(
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x2),
28, 27, opcode),
prjxray::bit_field_set<uint32_t>(0x0, 31, 29, 0x2), 28, 27,
opcode),
26, 0, word_count);
}
TEST(ConfigPacket, InitWithZeroBytes) {
auto packet = xc7series::ConfigurationPacket::InitWithWords({});
@ -88,8 +88,7 @@ TEST(ConfigPacket, InitWithType2WithPreviousPacket) {
xc7series::ConfigurationPacket previous_packet(
static_cast<unsigned int>(0x1),
xc7series::ConfigurationPacket::Opcode::Read,
xc7series::ConfigurationRegister::MFWR,
absl::Span<uint32_t>());
xc7series::ConfigurationRegister::MFWR, absl::Span<uint32_t>());
std::vector<uint32_t> words{
MakeType2(0x01, 12), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
absl::Span<uint32_t> word_span(words);

View File

@ -4,7 +4,7 @@ namespace prjxray {
namespace xilinx {
namespace xc7series {
std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value) {
std::ostream& operator<<(std::ostream& o, const ConfigurationRegister& value) {
switch (value) {
case ConfigurationRegister::CRC:
return o << "CRC";
@ -51,7 +51,6 @@ std::ostream& operator<<(std::ostream &o, const ConfigurationRegister &value) {
}
};
} // namespace xc7series
} // namespace xilinx
} // namespace prjxray

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);
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);
absl::Span<uint32_t> frame_span(frame);
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(2));
EXPECT_EQ(test_config->frames().at(0x456F), std::vector<uint32_t>(101, 0xAA));
EXPECT_EQ(test_config->frames().at(0x4580), std::vector<uint32_t>(101, 0xBB));
EXPECT_EQ(test_config->frames().at(0x456F),
std::vector<uint32_t>(101, 0xAA));
EXPECT_EQ(test_config->frames().at(0x4580),
std::vector<uint32_t>(101, 0xBB));
}
TEST(ConfigurationTest, DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations) {
TEST(ConfigurationTest,
DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations) {
auto part = xc7series::Part::FromFile("configuration_test.yaml");
ASSERT_TRUE(part);
@ -123,8 +128,8 @@ TEST(ConfigurationTest, DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations)
debug_bitstream->as_bytes());
ASSERT_TRUE(debug_reader);
auto debug_configuration = xc7series::Configuration::InitWithPackets(
*part, *debug_reader);
auto debug_configuration =
xc7series::Configuration::InitWithPackets(*part, *debug_reader);
ASSERT_TRUE(debug_configuration);
auto perframecrc_bitstream = prjxray::MemoryMappedFile::InitWithFile(
@ -135,28 +140,35 @@ TEST(ConfigurationTest, DebugAndPerFrameCrcBitstreamsProduceEqualConfigurations)
perframecrc_bitstream->as_bytes());
ASSERT_TRUE(perframecrc_reader);
auto perframecrc_configuration = xc7series::Configuration::InitWithPackets(
*part, *perframecrc_reader);
auto perframecrc_configuration =
xc7series::Configuration::InitWithPackets(*part,
*perframecrc_reader);
ASSERT_TRUE(perframecrc_configuration);
for (auto debug_frame : debug_configuration->frames()) {
auto perframecrc_frame = perframecrc_configuration->frames().find(debug_frame.first);
if (perframecrc_frame == perframecrc_configuration->frames().end()) {
ADD_FAILURE() << debug_frame.first << ": missing in perframecrc bitstream";
auto perframecrc_frame =
perframecrc_configuration->frames().find(debug_frame.first);
if (perframecrc_frame ==
perframecrc_configuration->frames().end()) {
ADD_FAILURE() << debug_frame.first
<< ": missing in perframecrc bitstream";
continue;
}
for (int ii = 0; ii < 101; ++ii) {
EXPECT_EQ(perframecrc_frame->second[ii], debug_frame.second[ii])
EXPECT_EQ(perframecrc_frame->second[ii],
debug_frame.second[ii])
<< debug_frame.first << ": word " << ii;
}
}
for (auto perframecrc_frame : perframecrc_configuration->frames()) {
auto debug_frame = debug_configuration->frames().find(perframecrc_frame.first);
auto debug_frame =
debug_configuration->frames().find(perframecrc_frame.first);
if (debug_frame == debug_configuration->frames().end()) {
ADD_FAILURE() << perframecrc_frame.first
<< ": unexpectedly present in perframecrc bitstream";
<< ": unexpectedly present in "
"perframecrc bitstream";
}
}
}
@ -173,39 +185,44 @@ TEST(ConfigurationTest, DebugAndNormalBitstreamsProduceEqualConfigurations) {
debug_bitstream->as_bytes());
ASSERT_TRUE(debug_reader);
auto debug_configuration = xc7series::Configuration::InitWithPackets(
*part, *debug_reader);
auto debug_configuration =
xc7series::Configuration::InitWithPackets(*part, *debug_reader);
ASSERT_TRUE(debug_configuration);
auto normal_bitstream = prjxray::MemoryMappedFile::InitWithFile(
"configuration_test.bit");
auto normal_bitstream =
prjxray::MemoryMappedFile::InitWithFile("configuration_test.bit");
ASSERT_TRUE(normal_bitstream);
auto normal_reader = xc7series::BitstreamReader::InitWithBytes(
normal_bitstream->as_bytes());
ASSERT_TRUE(normal_reader);
auto normal_configuration = xc7series::Configuration::InitWithPackets(
*part, *normal_reader);
auto normal_configuration =
xc7series::Configuration::InitWithPackets(*part, *normal_reader);
ASSERT_TRUE(normal_configuration);
for (auto debug_frame : debug_configuration->frames()) {
auto normal_frame = normal_configuration->frames().find(debug_frame.first);
auto normal_frame =
normal_configuration->frames().find(debug_frame.first);
if (normal_frame == normal_configuration->frames().end()) {
ADD_FAILURE() << debug_frame.first << ": missing in normal bitstream";
ADD_FAILURE() << debug_frame.first
<< ": missing in normal bitstream";
continue;
}
for (int ii = 0; ii < 101; ++ii) {
EXPECT_EQ(normal_frame->second[ii], debug_frame.second[ii])
EXPECT_EQ(normal_frame->second[ii],
debug_frame.second[ii])
<< debug_frame.first << ": word " << ii;
}
}
for (auto normal_frame : normal_configuration->frames()) {
auto debug_frame = debug_configuration->frames().find(normal_frame.first);
auto debug_frame =
debug_configuration->frames().find(normal_frame.first);
if (debug_frame == debug_configuration->frames().end()) {
ADD_FAILURE() << normal_frame.first
ADD_FAILURE()
<< normal_frame.first
<< ": unexpectedly present in normal bitstream";
}
}

View File

@ -8,8 +8,11 @@ namespace prjxray {
namespace xilinx {
namespace xc7series {
FrameAddress::FrameAddress(BlockType block_type, bool is_bottom_half_rows,
uint8_t row, uint16_t column, uint8_t minor) {
FrameAddress::FrameAddress(BlockType block_type,
bool is_bottom_half_rows,
uint8_t row,
uint16_t column,
uint8_t minor) {
address_ = bit_field_set(0, 25, 23, block_type);
address_ = bit_field_set(address_, 22, 22, is_bottom_half_rows);
address_ = bit_field_set(address_, 21, 17, row);
@ -37,23 +40,16 @@ uint8_t FrameAddress::minor_address() const {
return bit_field_get(address_, 6, 0);
}
std::ostream &operator<<(std::ostream &o, const FrameAddress& addr) {
o << "["
<< std::hex << std::showbase << std::setw(10)
<< static_cast<uint32_t>(addr)
<< "] "
std::ostream& operator<<(std::ostream& o, const FrameAddress& addr) {
o << "[" << std::hex << std::showbase << std::setw(10)
<< static_cast<uint32_t>(addr) << "] "
<< (addr.is_bottom_half_rows() ? "BOTTOM" : "TOP")
<< " Row="
<< std::setw(2) << std::dec
<< " Row=" << std::setw(2) << std::dec
<< static_cast<unsigned int>(addr.row_address())
<< " Column="
<< std::setw(2) << std::dec
<< addr.column_address()
<< " Minor="
<< std::setw(2) << std::dec
<< " Column=" << std::setw(2) << std::dec << addr.column_address()
<< " Minor=" << std::setw(2) << std::dec
<< static_cast<unsigned int>(addr.minor_address())
<< " Type="
<< addr.block_type();
<< " Type=" << addr.block_type();
return o;
}
@ -66,7 +62,7 @@ namespace YAML {
namespace xc7series = prjxray::xilinx::xc7series;
Node convert<xc7series::FrameAddress>::encode(
const xc7series::FrameAddress &rhs) {
const xc7series::FrameAddress& rhs) {
Node node;
node.SetTag("xilinx/xc7series/frame_address");
node["block_type"] = rhs.block_type();
@ -77,15 +73,13 @@ Node convert<xc7series::FrameAddress>::encode(
return node;
}
bool convert<xc7series::FrameAddress>::decode(
const Node &node, xc7series::FrameAddress &lhs) {
bool convert<xc7series::FrameAddress>::decode(const Node& node,
xc7series::FrameAddress& lhs) {
if (!(node.Tag() == "xilinx/xc7series/frame_address" ||
node.Tag() == "xilinx/xc7series/configuration_frame_address") ||
!node["block_type"] ||
!node["row_half"] ||
!node["row"] ||
!node["column"] ||
!node["minor"]) return false;
!node["block_type"] || !node["row_half"] || !node["row"] ||
!node["column"] || !node["minor"])
return false;
bool row_half;
if (node["row_half"].as<std::string>() == "top") {
@ -97,12 +91,10 @@ bool convert<xc7series::FrameAddress>::decode(
}
lhs = prjxray::xilinx::xc7series::FrameAddress(
node["block_type"].as<xc7series::BlockType>(),
row_half,
node["row"].as<unsigned int>(),
node["column"].as<unsigned int>(),
node["block_type"].as<xc7series::BlockType>(), row_half,
node["row"].as<unsigned int>(), node["column"].as<unsigned int>(),
node["minor"].as<unsigned int>());
return true;
}
} // namespace YAML;
} // namespace YAML

View File

@ -5,8 +5,8 @@
namespace xc7series = prjxray::xilinx::xc7series;
TEST(FrameAddressTest, YamlEncode) {
xc7series::FrameAddress address(xc7series::BlockType::BLOCK_RAM,
false, 10, 0, 5);
xc7series::FrameAddress address(xc7series::BlockType::BLOCK_RAM, false,
10, 0, 5);
YAML::Node node(address);
@ -27,8 +27,7 @@ TEST(FrameAddressTest, YamlDecode) {
node["column"] = "5";
node["minor"] = "11";
xc7series::FrameAddress address =
node.as<xc7series::FrameAddress>();
xc7series::FrameAddress address = node.as<xc7series::FrameAddress>();
EXPECT_EQ(address.block_type(), xc7series::BlockType::BLOCK_RAM);
EXPECT_TRUE(address.is_bottom_half_rows());
EXPECT_EQ(address.row_address(), 0);

View File

@ -7,7 +7,7 @@ namespace prjxray {
namespace xilinx {
namespace xc7series {
absl::optional<Part> Part::FromFile(const std::string &path) {
absl::optional<Part> Part::FromFile(const std::string& path) {
try {
YAML::Node yaml = YAML::LoadFile(path);
return yaml.as<Part>();
@ -16,8 +16,8 @@ absl::optional<Part> Part::FromFile(const std::string &path) {
}
}
absl::optional<FrameAddress>
Part::GetNextFrameAddress(FrameAddress address) const {
absl::optional<FrameAddress> Part::GetNextFrameAddress(
FrameAddress address) const {
// Start with the next linear address.
FrameAddress target_address(address + 1);
@ -27,8 +27,7 @@ Part::GetNextFrameAddress(FrameAddress address) const {
// address.
absl::optional<FrameAddress> closest_address;
int32_t closest_distance;
for (auto iter = frame_ranges_.begin();
iter != frame_ranges_.end();
for (auto iter = frame_ranges_.begin(); iter != frame_ranges_.end();
++iter) {
if (iter->Contains(target_address)) {
return target_address;
@ -36,8 +35,7 @@ Part::GetNextFrameAddress(FrameAddress address) const {
int32_t distance = iter->begin() - target_address;
if (distance > 0 &&
(!closest_address ||
distance < closest_distance)) {
(!closest_address || distance < closest_distance)) {
closest_address = iter->begin();
closest_distance = distance;
}
@ -54,7 +52,7 @@ namespace xc7series = prjxray::xilinx::xc7series;
namespace YAML {
Node convert<xc7series::Part>::encode(const xc7series::Part &rhs) {
Node convert<xc7series::Part>::encode(const xc7series::Part& rhs) {
Node node;
node.SetTag("xilinx/xc7series/part");
@ -66,17 +64,16 @@ Node convert<xc7series::Part>::encode(const xc7series::Part &rhs) {
return node;
}
bool convert<xc7series::Part>::decode(const Node &node, xc7series::Part &lhs) {
if (node.Tag() != "xilinx/xc7series/part" ||
!node["idcode"] ||
!node["configuration_ranges"]) return false;
bool convert<xc7series::Part>::decode(const Node& node, xc7series::Part& lhs) {
if (node.Tag() != "xilinx/xc7series/part" || !node["idcode"] ||
!node["configuration_ranges"])
return false;
lhs = xc7series::Part(
node["idcode"].as<uint32_t>(),
node["configuration_ranges"].as<
std::vector<xc7series::ConfigurationFrameRange>>());
node["configuration_ranges"]
.as<std::vector<xc7series::ConfigurationFrameRange>>());
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 <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <set>
#include <string>
#include <vector>
#include <absl/strings/numbers.h>
@ -19,11 +19,18 @@
DEFINE_bool(c, false, "output '*' for repeating patterns");
DEFINE_bool(C, false, "do not ignore the checksum in each frame");
DEFINE_int32(f, -1, "only dump the specified frame (might be used more than once)");
DEFINE_string(F, "", "<first_frame_address>:<last_frame_address> only dump frame in the specified range");
DEFINE_int32(f,
-1,
"only dump the specified frame (might be used more than once)");
DEFINE_string(F,
"",
"<first_frame_address>:<last_frame_address> only dump frame in "
"the specified range");
DEFINE_string(o, "", "write machine-readable output file with config frames");
DEFINE_bool(p, false, "output a binary netpgm image");
DEFINE_bool(x, false, "use format 'bit_%%08x_%%03d_%%02d_t%%d_h%%d_r%%d_c%%d_m%%d'\n"
DEFINE_bool(x,
false,
"use format 'bit_%%08x_%%03d_%%02d_t%%d_h%%d_r%%d_c%%d_m%%d'\n"
"The fields have the following meaning:\n"
" - complete 32 bit hex frame id\n"
" - word index with that frame (decimal)\n"
@ -44,7 +51,7 @@ uint32_t frame_range_begin = 0, frame_range_end = 0;
std::vector<uint32_t> zero_frame(101);
int main(int argc, char **argv) {
int main(int argc, char** argv) {
gflags::SetUsageMessage(
absl::StrCat("Usage: ", argv[0], " [options] [bitfile]"));
gflags::ParseCommandLineFlags(&argc, &argv, true);
@ -60,7 +67,8 @@ int main(int argc, char **argv) {
}
if (!FLAGS_F.empty()) {
std::pair<std::string, std::string> p = absl::StrSplit(FLAGS_F, ":");
std::pair<std::string, std::string> p =
absl::StrSplit(FLAGS_F, ":");
frame_range_begin = strtol(p.first.c_str(), nullptr, 0);
frame_range_end = strtol(p.second.c_str(), nullptr, 0) + 1;
}
@ -68,7 +76,8 @@ int main(int argc, char **argv) {
absl::optional<xc7series::BitstreamReader> reader;
if (argc == 2) {
auto in_file_name = argv[1];
auto in_file = prjxray::MemoryMappedFile::InitWithFile(in_file_name);
auto in_file =
prjxray::MemoryMappedFile::InitWithFile(in_file_name);
if (!in_file) {
std::cerr << "Can't open input file '" << in_file_name
<< "' for reading!" << std::endl;
@ -84,7 +93,8 @@ int main(int argc, char **argv) {
std::vector<uint8_t> bitdata;
while (1) {
int c = getchar();
if (c == EOF) break;
if (c == EOF)
break;
bitdata.push_back(c);
}
@ -100,8 +110,8 @@ int main(int argc, char **argv) {
return 1;
}
std::cout << "Config size: " << reader->words().size()
<< " words" << std::endl;
std::cout << "Config size: " << reader->words().size() << " words"
<< std::endl;
auto config = xc7series::Configuration::InitWithPackets(*part, *reader);
if (!config) {
@ -113,14 +123,14 @@ int main(int argc, char **argv) {
std::cout << "Number of configuration frames: "
<< config->frames().size() << std::endl;
FILE *f = stdout;
FILE* f = stdout;
if (!FLAGS_o.empty())
{
if (!FLAGS_o.empty()) {
f = fopen(FLAGS_o.c_str(), "w");
if (f == nullptr) {
printf("Can't open output file '%s' for writing!\n", FLAGS_o.c_str());
printf("Can't open output file '%s' for writing!\n",
FLAGS_o.c_str());
return 1;
}
} else {
@ -130,8 +140,7 @@ int main(int argc, char **argv) {
std::vector<std::vector<bool>> pgmdata;
std::vector<int> pgmsep;
for (auto &it : config->frames())
{
for (auto& it : config->frames()) {
if (FLAGS_z && it.second == zero_frame)
continue;
@ -139,17 +148,21 @@ int main(int argc, char **argv) {
continue;
if (frame_range_begin != frame_range_end &&
(it.first < frame_range_begin || frame_range_end <= it.first))
(it.first < frame_range_begin ||
frame_range_end <= it.first))
continue;
if (FLAGS_o.empty())
printf("Frame 0x%08x (Type=%d Top=%d Row=%d Column=%d Minor=%d):\n",
static_cast<uint32_t>(it.first), static_cast<unsigned int>(it.first.block_type()),
printf(
"Frame 0x%08x (Type=%d Top=%d Row=%d Column=%d "
"Minor=%d):\n",
static_cast<uint32_t>(it.first),
static_cast<unsigned int>(it.first.block_type()),
it.first.is_bottom_half_rows() ? 1 : 0,
it.first.row_address(), it.first.column_address(), it.first.minor_address());
it.first.row_address(), it.first.column_address(),
it.first.minor_address());
if (FLAGS_p)
{
if (FLAGS_p) {
if (it.first.minor_address() == 0 && !pgmdata.empty())
pgmsep.push_back(pgmdata.size());
@ -157,49 +170,73 @@ int main(int argc, char **argv) {
for (int i = 0; i < 101; i++)
for (int k = 0; k < 32; k++)
pgmdata.back().push_back((it.second.at(i) & (1 << k)) != 0);
}
else
if (FLAGS_x || FLAGS_y)
{
pgmdata.back().push_back(
(it.second.at(i) & (1 << k)) != 0);
} else if (FLAGS_x || FLAGS_y) {
for (int i = 0; i < 101; i++)
for (int k = 0; k < 32; k++)
if ((i != 50 || k > 12 || FLAGS_C) && ((it.second.at(i) & (1 << k)) != 0)) {
if ((i != 50 || k > 12 || FLAGS_C) &&
((it.second.at(i) & (1 << k)) !=
0)) {
if (FLAGS_x)
fprintf(f, "bit_%08x_%03d_%02d_t%d_h%d_r%d_c%d_m%d\n",
static_cast<uint32_t>(it.first),
fprintf(
f,
"bit_%08x_%03d_%"
"02d_t%d_h%d_r%d_c%"
"d_m%d\n",
static_cast<
uint32_t>(
it.first),
i, k,
static_cast<unsigned int>(it.first.block_type()),
it.first.is_bottom_half_rows() ? 1 : 0,
it.first.row_address(), it.first.column_address(), it.first.minor_address());
static_cast<
unsigned int>(
it.first
.block_type()),
it.first.is_bottom_half_rows()
? 1
: 0,
it.first
.row_address(),
it.first
.column_address(),
it.first
.minor_address());
else
fprintf(f, "bit_%08x_%03d_%02d\n", static_cast<uint32_t>(it.first), i, k);
fprintf(f,
"bit_%08x_%03d_"
"%02d\n",
static_cast<
uint32_t>(
it.first),
i, k);
}
if (FLAGS_o.empty())
fprintf(f, "\n");
}
else
{
} else {
if (!FLAGS_o.empty())
fprintf(f, ".frame 0x%08x\n", static_cast<uint32_t>(it.first));
fprintf(f, ".frame 0x%08x\n",
static_cast<uint32_t>(it.first));
for (int i = 0; i < 101; i++)
fprintf(f, "%08x%s", it.second.at(i) & ((i != 50 || FLAGS_C) ? 0xffffffff : 0xffffe000), (i % 6) == 5 ? "\n" : " ");
fprintf(f, "%08x%s",
it.second.at(i) &
((i != 50 || FLAGS_C) ? 0xffffffff
: 0xffffe000),
(i % 6) == 5 ? "\n" : " ");
fprintf(f, "\n\n");
}
}
if (FLAGS_p)
{
if (FLAGS_p) {
int width = pgmdata.size() + pgmsep.size();
int height = 101*32+100;
int height = 101 * 32 + 100;
fprintf(f, "P5 %d %d 15\n", width, height);
for (int y = 0, bit = 101*32-1; y < height; y++, bit--)
{
for (int x = 0, frame = 0, sep = 0; x < width; x++, frame++)
{
if (sep < int(pgmsep.size()) && frame == pgmsep.at(sep)) {
for (int y = 0, bit = 101 * 32 - 1; y < height; y++, bit--) {
for (int x = 0, frame = 0, sep = 0; x < width;
x++, frame++) {
if (sep < int(pgmsep.size()) &&
frame == pgmsep.at(sep)) {
fputc(8, f);
x++, sep++;
}
@ -221,4 +258,3 @@ int main(int argc, char **argv) {
printf("DONE\n");
return 0;
}

View File

@ -11,15 +11,14 @@ namespace xc7series = prjxray::xilinx::xc7series;
struct Action {
std::string name;
std::function<int(int, char*[])> handler;
std::function<int(int, char* [])> handler;
};
int ListConfigPackets(int argc, char *argv[]) {
int ListConfigPackets(int argc, char* argv[]) {
if (argc < 1) {
std::cerr << "ERROR: no input specified" << std::endl;
std::cerr << "Usage: " << argv[0]
<< "list_config_packets <bit_file>"
<< std::endl;
<< "list_config_packets <bit_file>" << std::endl;
return 1;
}
@ -31,11 +30,10 @@ int ListConfigPackets(int argc, char *argv[]) {
return 1;
}
auto reader = xc7series::BitstreamReader::InitWithBytes(
in_file->as_bytes());
auto reader =
xc7series::BitstreamReader::InitWithBytes(in_file->as_bytes());
if (!reader) {
std::cerr << "Input doesn't look like a bitstream"
<< std::endl;
std::cerr << "Input doesn't look like a bitstream" << std::endl;
return 1;
}
@ -46,7 +44,7 @@ int ListConfigPackets(int argc, char *argv[]) {
return 0;
}
int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
int DumpDebugbitstreamFrameAddresses(int argc, char* argv[]) {
if (argc < 1) {
std::cerr << "ERROR: no input specified" << std::endl;
std::cerr << "Usage: " << argv[0]
@ -64,12 +62,10 @@ int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
}
auto in_bytes = absl::Span<uint8_t>(
static_cast<uint8_t*>(in_file->data()),
in_file->size());
static_cast<uint8_t*>(in_file->data()), in_file->size());
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
if (!reader) {
std::cerr << "Input doesn't look like a bitstream"
<< std::endl;
std::cerr << "Input doesn't look like a bitstream" << std::endl;
return 1;
}
@ -102,11 +98,10 @@ int DumpDebugbitstreamFrameAddresses(int argc, char *argv[]) {
return 0;
}
int GetDeviceId(int argc, char *argv[]) {
int GetDeviceId(int argc, char* argv[]) {
if (argc < 1) {
std::cerr << "ERROR: no input specified" << std::endl;
std::cerr << "Usage: " << argv[0]
<< "get_device_id <bit_file>"
std::cerr << "Usage: " << argv[0] << "get_device_id <bit_file>"
<< std::endl;
return 1;
}
@ -120,18 +115,16 @@ int GetDeviceId(int argc, char *argv[]) {
}
auto in_bytes = absl::Span<uint8_t>(
static_cast<uint8_t*>(in_file->data()),
in_file->size());
static_cast<uint8_t*>(in_file->data()), in_file->size());
auto reader = xc7series::BitstreamReader::InitWithBytes(in_bytes);
if (!reader) {
std::cerr << "Input doesn't look like a bitstream"
<< std::endl;
std::cerr << "Input doesn't look like a bitstream" << std::endl;
return 1;
}
auto idcode_packet = std::find_if(
reader->begin(), reader->end(),
[](const xc7series::ConfigurationPacket &packet) {
[](const xc7series::ConfigurationPacket& packet) {
return (packet.opcode() ==
xc7series::ConfigurationPacket::Opcode::Write) &&
(packet.address() ==
@ -150,12 +143,12 @@ int GetDeviceId(int argc, char *argv[]) {
return 0;
}
int main(int argc, char *argv[]) {
int main(int argc, char* argv[]) {
Action actions[] = {
{ "list_config_packets", ListConfigPackets },
{ "dump_debugbitstream_frame_addresses",
DumpDebugbitstreamFrameAddresses },
{ "get_device_id", GetDeviceId },
{"list_config_packets", ListConfigPackets},
{"dump_debugbitstream_frame_addresses",
DumpDebugbitstreamFrameAddresses},
{"get_device_id", GetDeviceId},
};
gflags::SetUsageMessage(
@ -172,11 +165,10 @@ int main(int argc, char *argv[]) {
auto requested_action_str = argv[1];
auto requested_action = std::find_if(
std::begin(actions), std::end(actions),
[&](const Action& t) {
return t.name == requested_action_str; });
[&](const Action& t) { return t.name == requested_action_str; });
if (requested_action == std::end(actions)) {
std::cerr << "Unknown action: "
<< requested_action_str << std::endl;
std::cerr << "Unknown action: " << requested_action_str
<< std::endl;
return 1;
}

View File

@ -6,8 +6,8 @@
namespace xc7series = prjxray::xilinx::xc7series;
int main(int argc, char *argv[]) {
std::istream * input_stream = &std::cin;
int main(int argc, char* argv[]) {
std::istream* input_stream = &std::cin;
if (argc > 1) {
auto file_stream = std::ifstream(argv[1]);
if (file_stream) {
@ -16,27 +16,19 @@ int main(int argc, char *argv[]) {
}
for (uint32_t frame_address_raw;
(*input_stream) >> std::setbase(0) >> frame_address_raw;
) {
(*input_stream) >> std::setbase(0) >> frame_address_raw;) {
xc7series::FrameAddress frame_address(frame_address_raw);
std::cout << "["
<< std::hex << std::showbase << std::setw(10)
<< frame_address_raw
<< "] "
<< (frame_address.is_bottom_half_rows() ?
"BOTTOM" : "TOP")
<< " Row="
<< std::setw(2) << std::dec
std::cout
<< "[" << std::hex << std::showbase << std::setw(10)
<< frame_address_raw << "] "
<< (frame_address.is_bottom_half_rows() ? "BOTTOM" : "TOP")
<< " Row=" << std::setw(2) << std::dec
<< static_cast<unsigned int>(frame_address.row_address())
<< " Column="
<< std::setw(2) << std::dec
<< " Column=" << std::setw(2) << std::dec
<< frame_address.column_address()
<< " Minor="
<< std::setw(2) << std::dec
<< " Minor=" << std::setw(2) << std::dec
<< static_cast<unsigned int>(frame_address.minor_address())
<< " Type="
<< frame_address.block_type()
<< std::endl;
<< " Type=" << frame_address.block_type() << std::endl;
}
return 0;

View File

@ -13,11 +13,10 @@
namespace xc7series = prjxray::xilinx::xc7series;
int main(int argc, char *argv[]) {
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "ERROR: no input specified" << std::endl;
std::cerr << "Usage: " << basename(argv[0])
<< " <bit_file>"
std::cerr << "Usage: " << basename(argv[0]) << " <bit_file>"
<< std::endl;
return 1;
}
@ -30,11 +29,10 @@ int main(int argc, char *argv[]) {
return 1;
}
auto reader = xc7series::BitstreamReader::InitWithBytes(
in_file->as_bytes());
auto reader =
xc7series::BitstreamReader::InitWithBytes(in_file->as_bytes());
if (!reader) {
std::cerr << "Input doesn't look like a bitstream"
<< std::endl;
std::cerr << "Input doesn't look like a bitstream" << std::endl;
return 1;
}
@ -80,17 +78,15 @@ int main(int argc, char *argv[]) {
std::vector<xc7series::ConfigurationFrameRange> ranges;
for (auto start_of_range = frame_addresses.begin();
start_of_range != frame_addresses.end();
) {
start_of_range != frame_addresses.end();) {
auto end_of_range = start_of_range;
while (end_of_range + 1 != frame_addresses.end() &&
*(end_of_range + 1) == *end_of_range + 1) {
++end_of_range;
}
ranges.push_back(
xc7series::ConfigurationFrameRange(*start_of_range,
*end_of_range+1));
ranges.push_back(xc7series::ConfigurationFrameRange(
*start_of_range, *end_of_range + 1));
start_of_range = ++end_of_range;
}

View File

@ -1,20 +1,23 @@
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <numeric>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <vector>
#include <absl/strings/str_cat.h>
#include <gflags/gflags.h>
DEFINE_int32(c, 4, "threshold under which candidates are output. set to -1 to output all.");
DEFINE_int32(
c,
4,
"threshold under which candidates are output. set to -1 to output all.");
DEFINE_bool(i, false, "add inverted tags");
DEFINE_int32(m, 0, "min number of set/cleared samples each");
DEFINE_int32(M, 0, "min number of set/cleared samples total");
@ -22,9 +25,9 @@ DEFINE_string(o, "", "set output file");
DEFINE_string(k, "", "set output mask file");
using std::map;
using std::string;
using std::tuple;
using std::vector;
using std::string;
int num_bits = 0, num_tags = 0;
map<string, int> bit_ids, tag_ids;
@ -76,51 +79,40 @@ struct bool_vec
}
};
#else
struct bool_vec
{
struct bool_vec {
vector<uint64_t> data;
bool_vec(int n = 0, bool initval = false) :
data((n+63)/64, initval ? ~uint64_t(0) : uint64_t(0))
{
for (int i = data.size()*64-1; i >= n; i--)
bool_vec(int n = 0, bool initval = false)
: data((n + 63) / 64, initval ? ~uint64_t(0) : uint64_t(0)) {
for (int i = data.size() * 64 - 1; i >= n; i--)
data[n / 64] &= ~(uint64_t(1) << (n % 64));
}
void set(int n)
{
if (int(data.size()*64) <= n)
data.resize((n+64) / 64);
void set(int n) {
if (int(data.size() * 64) <= n)
data.resize((n + 64) / 64);
data[n / 64] |= uint64_t(1) << (n % 64);
}
bool get(int n)
{
return (data[n / 64] >> (n % 64)) & 1;
}
bool get(int n) { return (data[n / 64] >> (n % 64)) & 1; }
void resize(int n)
{
data.resize((n+63) / 64);
}
void resize(int n) { data.resize((n + 63) / 64); }
int count()
{
int count() {
int sum = 0;
for (int i = 0; i < 64*int(data.size()); i++)
if (get(i)) sum++;
for (int i = 0; i < 64 * int(data.size()); i++)
if (get(i))
sum++;
return sum;
}
void apply_and(const bool_vec &other)
{
void apply_and(const bool_vec& other) {
assert(data.size() == other.data.size());
for (int i = 0; i < int(data.size()); i++)
data[i] &= other.data[i];
}
void apply_andc(const bool_vec &other)
{
void apply_andc(const bool_vec& other) {
assert(data.size() == other.data.size());
for (int i = 0; i < int(data.size()); i++)
data[i] &= ~other.data[i];
@ -134,19 +126,22 @@ map<string, segdata_t> segdata;
map<string, int> segnamecnt;
static inline bool_vec &segdata_bits(segdata_t &sd) { return std::get<0>(sd); }
static inline bool_vec &segdata_tags1(segdata_t &sd) { return std::get<1>(sd); }
static inline bool_vec &segdata_tags0(segdata_t &sd) { return std::get<2>(sd); }
static inline bool_vec& segdata_bits(segdata_t& sd) {
return std::get<0>(sd);
}
static inline bool_vec& segdata_tags1(segdata_t& sd) {
return std::get<1>(sd);
}
static inline bool_vec& segdata_tags0(segdata_t& sd) {
return std::get<2>(sd);
}
void read_input(std::istream &f, std::string filename)
{
void read_input(std::istream& f, std::string filename) {
string token;
segdata_t *segptr = nullptr;
segdata_t* segptr = nullptr;
while (f >> token)
{
if (token == "seg")
{
while (f >> token) {
if (token == "seg") {
f >> token;
token = filename + ":" + token;
while (segdata.count(token)) {
@ -162,8 +157,7 @@ void read_input(std::istream &f, std::string filename)
continue;
}
if (token == "bit")
{
if (token == "bit") {
assert(segptr != nullptr);
f >> token;
@ -173,14 +167,13 @@ void read_input(std::istream &f, std::string filename)
}
int bit_idx = bit_ids.at(token);
auto &bits = segdata_bits(*segptr);
auto& bits = segdata_bits(*segptr);
bits.set(bit_idx);
continue;
}
if (token == "tag")
{
if (token == "tag") {
assert(segptr != nullptr);
f >> token;
@ -194,13 +187,15 @@ void read_input(std::istream &f, std::string filename)
f >> token;
assert(token == "0" || token == "1");
auto &tags = token == "1" ? segdata_tags1(*segptr) : segdata_tags0(*segptr);
auto& tags = token == "1" ? segdata_tags1(*segptr)
: segdata_tags0(*segptr);
tags.set(tag_idx);
if (FLAGS_i)
{
auto &inv_tags = token == "1" ? segdata_tags0(*segptr) : segdata_tags1(*segptr);
if (FLAGS_i) {
auto& inv_tags = token == "1"
? segdata_tags0(*segptr)
: segdata_tags1(*segptr);
token = tag_ids_r.at(tag_idx) + "__INV";
@ -223,15 +218,14 @@ void read_input(std::istream &f, std::string filename)
// printf("Number of bits: %d\n", num_bits);
// printf("Number of tags: %d\n", num_tags);
for (auto &segdat : segdata) {
for (auto& segdat : segdata) {
segdata_bits(segdat.second).resize(num_bits);
segdata_tags1(segdat.second).resize(num_tags);
segdata_tags0(segdat.second).resize(num_tags);
}
}
int main(int argc, char **argv)
{
int main(int argc, char** argv) {
gflags::SetUsageMessage(
absl::StrCat("Usage: ", argv[0], " [options] file.."));
gflags::ParseCommandLineFlags(&argc, &argv, true);
@ -253,7 +247,7 @@ int main(int argc, char **argv)
printf("#of bits: %d\n", num_bits);
printf("#of tags: %d\n", num_tags);
FILE *f = stdout;
FILE* f = stdout;
if (!FLAGS_o.empty()) {
f = fopen(FLAGS_o.c_str(), "w");
@ -269,14 +263,12 @@ int main(int argc, char **argv)
std::vector<std::string> out_lines;
for (int tag_idx = 0; tag_idx < num_tags; tag_idx++)
{
for (int tag_idx = 0; tag_idx < num_tags; tag_idx++) {
bool_vec mask(num_bits, true);
int count1 = 0, count0 = 0;
for (auto &segdat : segdata)
{
auto &sd = segdat.second;
for (auto& segdat : segdata) {
auto& sd = segdat.second;
bool tag1 = segdata_tags1(sd).get(tag_idx);
bool tag0 = segdata_tags0(sd).get(tag_idx);
@ -331,25 +323,28 @@ int main(int argc, char **argv)
int num_candidates = mask.count();
if (count0) {
min_candidates = std::min(min_candidates, num_candidates);
max_candidates = std::max(max_candidates, num_candidates);
min_candidates =
std::min(min_candidates, num_candidates);
max_candidates =
std::max(max_candidates, num_candidates);
avg_candidates += num_candidates;
cnt_candidates += 1;
}
if (FLAGS_c < 0 ||
(0 < num_candidates &&
num_candidates <= FLAGS_c)) {
(0 < num_candidates && num_candidates <= FLAGS_c)) {
std::vector<std::string> out_tags;
for (int bit_idx = 0; bit_idx < num_bits; bit_idx++)
if (mask.get(bit_idx))
out_tags.push_back(bit_ids_r.at(bit_idx));
out_tags.push_back(
bit_ids_r.at(bit_idx));
std::sort(out_tags.begin(), out_tags.end());
for (auto &tag : out_tags)
for (auto& tag : out_tags)
out_line += " " + tag;
} else {
char buffer[64];
snprintf(buffer, 64, " <%d candidates>", num_candidates);
snprintf(buffer, 64, " <%d candidates>",
num_candidates);
out_line += buffer;
}
@ -358,7 +353,7 @@ int main(int argc, char **argv)
std::sort(out_lines.begin(), out_lines.end());
for (auto &line : out_lines)
for (auto& line : out_lines)
fprintf(f, "%s\n", line.c_str());
if (cnt_candidates)
@ -383,4 +378,3 @@ int main(int argc, char **argv)
return 0;
}

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, re
import sys
import re
database = dict()
database_r = dict()
@ -24,20 +25,23 @@ for arg in sys.argv[1:]:
database[key] = bits
database_r[bits] = key
def get_subsets(bits):
retval = list()
retval.append(bits)
for i in range(len(bits)):
for s in get_subsets(bits[i+1:]):
retval.append(bits[0:i] + s);
for s in get_subsets(bits[i + 1:]):
retval.append(bits[0:i] + s)
return retval
def check_subsets(bits):
for sub_bits in sorted(get_subsets(bits)):
if sub_bits != bits and sub_bits != ():
if sub_bits in database_r:
print("Warning: Entry %s %s is a subset of entry %s %s." % (database_r[sub_bits], sub_bits, database_r[bits], bits))
print("Warning: Entry %s %s is a subset of entry %s %s." %
(database_r[sub_bits], sub_bits, database_r[bits], bits))
for key, bits in database.items():
check_subsets(bits)

View File

@ -1,6 +1,8 @@
#/usr/bin/env python3
import sys, os, re
import sys
import os
import re
zero_db = [
"00_21 00_22 00_26 01_28|00_25 01_20 01_21 01_24",
@ -31,9 +33,11 @@ zero_db = [
"30_53 31_53 31_56 31_57",
]
def add_zero_bits(tile_type):
assert os.getenv("XRAY_DATABASE") in ["artix7", "kintex7"]
dbfile = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), tile_type)
dbfile = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
os.getenv("XRAY_DATABASE"), tile_type)
new_lines = set()
llast = None
@ -84,9 +88,11 @@ def add_zero_bits(tile_type):
for line in sorted(new_lines):
print(line, file=f)
def update_mask(mask_db, *src_dbs):
bits = set()
mask_db_file = "%s/%s/mask_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), mask_db)
mask_db_file = "%s/%s/mask_%s.db" % (
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), mask_db)
if os.path.exists(mask_db_file):
with open(mask_db_file, "r") as f:
@ -97,7 +103,8 @@ def update_mask(mask_db, *src_dbs):
bits.add(line[1])
for src_db in src_dbs:
seg_db_file = "%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), src_db)
seg_db_file = "%s/%s/segbits_%s.db" % (
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), src_db)
if not os.path.exists(seg_db_file):
continue
@ -114,6 +121,7 @@ def update_mask(mask_db, *src_dbs):
for bit in sorted(bits):
print("bit %s" % bit, file=f)
add_zero_bits("int_l")
add_zero_bits("int_r")
add_zero_bits("clbll_l")
@ -133,4 +141,3 @@ for k in range(5):
update_mask("bram%d_r" % k, "bram%d_r" % k, "int_r")
update_mask("dsp%d_l" % k, "dsp%d_l" % k, "int_l")
update_mask("dsp%d_r" % k, "dsp%d_r" % k, "int_r")

View File

@ -1,4 +1,7 @@
import os, json, re
import os
import json
import re
class segmaker:
def __init__(self, bitsfile):
@ -24,7 +27,8 @@ class segmaker:
if bit_wordidx not in self.bits[base_frame]:
self.bits[base_frame][bit_wordidx] = set()
self.bits[base_frame][bit_wordidx].add((bit_frame, bit_wordidx, bit_bitidx))
self.bits[base_frame][bit_wordidx].add(
(bit_frame, bit_wordidx, bit_bitidx))
def addtag(self, site, name, value):
if site not in self.tags:
@ -50,30 +54,35 @@ class segmaker:
segments = self.segments_by_type[segdata["type"]]
tile_type = tiledata["type"]
segname = "%s_%03d" % (segdata["baseaddr"][0][2:], segdata["baseaddr"][1])
segname = "%s_%03d" % (
segdata["baseaddr"][0][2:], segdata["baseaddr"][1])
def add_segbits():
if not segname in segments:
segments[segname] = { "bits": set(), "tags": dict() }
segments[segname] = {"bits": set(), "tags": dict()}
base_frame = int(segdata["baseaddr"][0][2:], 16)
for wordidx in range(segdata["baseaddr"][1], segdata["baseaddr"][1]+segdata["words"]):
for wordidx in range(segdata["baseaddr"][1], segdata["baseaddr"][1] + segdata["words"]):
if base_frame not in self.bits:
continue
if wordidx not in self.bits[base_frame]:
continue
for bit_frame, bit_wordidx, bit_bitidx in self.bits[base_frame][wordidx]:
bitname_frame = bit_frame - base_frame
bitname_bit = 32*(bit_wordidx - segdata["baseaddr"][1]) + bit_bitidx
bitname_bit = 32 * \
(bit_wordidx -
segdata["baseaddr"][1]) + bit_bitidx
if bitfilter is None or bitfilter(bitname_frame, bitname_bit):
bitname = "%02d_%02d" % (bitname_frame, bitname_bit)
bitname = "%02d_%02d" % (
bitname_frame, bitname_bit)
segments[segname]["bits"].add(bitname)
if tilename in self.tags:
add_segbits()
for name, value in self.tags[tilename].items():
tag = "%s.%s" % (re.sub("(LL|LM)?_[LR]$", "", tile_type), name)
tag = "%s.%s" % (
re.sub("(LL|LM)?_[LR]$", "", tile_type), name)
segments[segname]["tags"][tag] = value
for site in tiledata["sites"]:
@ -90,7 +99,8 @@ class segmaker:
assert 0
for name, value in self.tags[site].items():
tag = "%s.%s.%s" % (re.sub("(LL|LM)?_[LR]$", "", tile_type), sitekey, name)
tag = "%s.%s.%s" % (
re.sub("(LL|LM)?_[LR]$", "", tile_type), sitekey, name)
tag = tag.replace(".SLICEM.", ".")
tag = tag.replace(".SLICEL.", ".")
segments[segname]["tags"][tag] = value
@ -119,5 +129,5 @@ class segmaker:
for bitname in sorted(segdata["bits"]):
print("bit %s_%s" % (segname, bitname), file=f)
for tagname, tagval in sorted(segdata["tags"].items()):
print("tag %s_%s %d" % (segname, tagname, tagval), file=f)
print("tag %s_%s %d" %
(segname, tagname, tagval), file=f)

View File

@ -1,12 +1,17 @@
#!/usr/bin/env python3
import getopt, sys, os, json, re
import getopt
import sys
import os
import json
import re
flag_z = False
flag_b = False
flag_d = False
flag_D = False
def usage():
print("Usage: %s [options] <bits_file> [segments/tiles]" % sys.argv[0])
print("")
@ -24,6 +29,7 @@ def usage():
print("")
sys.exit(0)
try:
opts, args = getopt.getopt(sys.argv[1:], "zbdD")
except:
@ -67,6 +73,7 @@ with open(args[0], "r") as f:
segbitsdb = dict()
def get_database(segtype):
if segtype in segbitsdb:
return segbitsdb[segtype]
@ -85,16 +92,17 @@ def get_database(segtype):
return segbitsdb[segtype]
def handle_segment(segname):
if segname is None:
segframes = dict()
for segname, segdata in grid["segments"].items():
framebase = int(segdata["baseaddr"][0], 16)
for i in range(segdata["frames"]):
if (framebase+i) not in segframes:
segframes[framebase+i] = set()
if (framebase + i) not in segframes:
segframes[framebase + i] = set()
for j in range(segdata["baseaddr"][1], segdata["baseaddr"][1] + segdata["words"]):
segframes[framebase+i].add(j)
segframes[framebase + i].add(j)
for frame in sorted(bitdata.keys()):
for wordidx in sorted(bitdata[frame].keys()):
if frame in segframes and wordidx in segframes[frame]:
@ -151,14 +159,15 @@ def handle_segment(segname):
segbits = set()
segtags = set()
for frame in range(baseframe, baseframe+numframes):
for frame in range(baseframe, baseframe + numframes):
if frame not in bitdata:
continue
for wordidx in range(basewordidx, basewordidx+numwords):
for wordidx in range(basewordidx, basewordidx + numwords):
if wordidx not in bitdata[frame]:
continue
for bitidx in bitdata[frame][wordidx]:
segbits.add("%02d_%02d" % (frame - baseframe, 32*(wordidx - basewordidx) + bitidx))
segbits.add("%02d_%02d" % (frame - baseframe,
32 * (wordidx - basewordidx) + bitidx))
if flag_d or flag_D:
for entry in get_database(seginfo["type"]):
@ -185,6 +194,7 @@ def handle_segment(segname):
for tag in sorted(segtags):
print("tag %s" % tag)
if flag_b:
handle_segment(None)
@ -197,4 +207,3 @@ if len(args) == 1:
else:
for arg in args[1:]:
handle_segment(arg)

View File

@ -3,7 +3,9 @@
# Produces a complete database of wires in the ROI and their connections and tests if each
# routing node is a tree (i.e. fails with an error when a loop is found).
import os, sys, json
import os
import sys
import json
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f:
tilegrid = json.load(f)["tiles"]
@ -19,13 +21,16 @@ for tilename, tiledata in tilegrid.items():
key = (tiledata["grid_x"], tiledata["grid_y"])
grid[key] = tilename
def check_tileconn_entry(tilename, tiledata, entry, idx):
if idx == 0:
otheridx = 1
otherxy = (tiledata["grid_x"] + entry["grid_deltas"][0], tiledata["grid_y"] + entry["grid_deltas"][1])
otherxy = (tiledata["grid_x"] + entry["grid_deltas"]
[0], tiledata["grid_y"] + entry["grid_deltas"][1])
else:
otheridx = 0
otherxy = (tiledata["grid_x"] - entry["grid_deltas"][0], tiledata["grid_y"] - entry["grid_deltas"][1])
otherxy = (tiledata["grid_x"] - entry["grid_deltas"]
[0], tiledata["grid_y"] - entry["grid_deltas"][1])
if otherxy not in grid:
return
@ -54,6 +59,7 @@ def check_tileconn_entry(tilename, tiledata, entry, idx):
wirepairs[otherwirename] = set()
wirepairs[otherwirename].add(wirename)
for tilename, tiledata in tilegrid.items():
print("Connecting wires in tile %s." % tilename)
for entry in tileconn:
@ -62,6 +68,7 @@ for tilename, tiledata in tilegrid.items():
if entry["tile_types"][1] == tiledata["type"]:
check_tileconn_entry(tilename, tiledata, entry, 1)
def check_wire(wire, source):
for next_wire in wirepairs[wire]:
if next_wire == source:
@ -73,10 +80,10 @@ def check_wire(wire, source):
remwires.remove(next_wire)
check_wire(next_wire, wire)
while len(remwires):
wire = remwires.pop()
print("Checking %s:" % wire)
check_wire(wire, None)
print("NO LOOP FOUND: OK")

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3
import os, sys, json
import os
import sys
import json
if len(sys.argv) != 3:
print("Usage example: python3 %s HCLK_R HCLK_SW6E3" % sys.argv[0])
@ -26,9 +28,11 @@ for entry in tileconn:
if wire_pair[this_idx] != sys.argv[2]:
continue
outdata.append((delta_x, delta_y, entry["tile_types"][other_idx], wire_pair[other_idx]))
max_tiletype_len = max(max_tiletype_len, len(entry["tile_types"][other_idx]))
outdata.append(
(delta_x, delta_y, entry["tile_types"][other_idx], wire_pair[other_idx]))
max_tiletype_len = max(max_tiletype_len, len(
entry["tile_types"][other_idx]))
for entry in outdata:
print("%3d %3d %-*s %s" % (entry[0], entry[1], max_tiletype_len, entry[2], entry[3]))
print("%3d %3d %-*s %s" %
(entry[0], entry[1], max_tiletype_len, entry[2], entry[3]))