mirror of https://github.com/openXC7/prjxray.git
Run make format.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
b22001a645
commit
e7370d6fdc
|
|
@ -13,9 +13,9 @@ f.write("i,prim,loc,bel,init\n")
|
|||
|
||||
def gen_slices():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites([
|
||||
'SLICEL',
|
||||
'SLICEM',
|
||||
]):
|
||||
'SLICEL',
|
||||
'SLICEM',
|
||||
]):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
|
||||
def gen_slices():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites([
|
||||
'SLICEL',
|
||||
'SLICEM'
|
||||
]):
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(
|
||||
['SLICEL', 'SLICEM']):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
|
||||
def gen_slices():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites([
|
||||
'SLICEL',
|
||||
'SLICEM'
|
||||
]):
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(
|
||||
['SLICEL', 'SLICEM']):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
def gen_slices():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites([
|
||||
'SLICEL',
|
||||
'SLICEM',
|
||||
]):
|
||||
'SLICEL',
|
||||
'SLICEM',
|
||||
]):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
|
||||
def gen_slices():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites([
|
||||
'SLICEL',
|
||||
'SLICEM'
|
||||
]):
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(
|
||||
['SLICEL', 'SLICEM']):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
|
||||
def gen_slicems():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(['SLICEM']):
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(
|
||||
['SLICEM']):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ print('//Requested CLBs: %s' % str(CLBN))
|
|||
|
||||
|
||||
def gen_slicems():
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(['SLICEM']):
|
||||
for _tile_name, site_name, _site_type in util.get_roi().gen_sites(
|
||||
['SLICEM']):
|
||||
yield site_name
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# Break frames into WORD_SIZE bit words.
|
||||
WORD_SIZE_BITS = 32
|
||||
|
||||
|
||||
def load_bitdata(f):
|
||||
""" Read bit file and return bitdata map.
|
||||
|
||||
|
|
@ -22,6 +23,6 @@ def load_bitdata(f):
|
|||
bitdata[frame] = set(), set()
|
||||
|
||||
bitdata[frame][0].add(wordidx)
|
||||
bitdata[frame][1].add(wordidx*WORD_SIZE_BITS + bitidx)
|
||||
bitdata[frame][1].add(wordidx * WORD_SIZE_BITS + bitidx)
|
||||
|
||||
return bitdata
|
||||
|
|
|
|||
|
|
@ -137,6 +137,6 @@ class Database(object):
|
|||
def get_tile_segbits(self, tile_type):
|
||||
if tile_type not in self.tile_segbits:
|
||||
self.tile_segbits[tile_type] = tile_segbits.TileSegbits(
|
||||
self.tile_types[tile_type.upper()])
|
||||
self.tile_types[tile_type.upper()])
|
||||
|
||||
return self.tile_segbits[tile_type]
|
||||
|
|
|
|||
|
|
@ -2,20 +2,25 @@ import fasm
|
|||
from prjxray import bitstream
|
||||
from prjxray import grid
|
||||
|
||||
|
||||
class FasmLookupError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FasmInconsistentBits(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# How many 32-bit words for frame in a 7-series bitstream?
|
||||
FRAME_WORD_COUNT = 101
|
||||
|
||||
|
||||
def init_frame_at_address(frames, addr):
|
||||
'''Set given frame to 0 if not initialized '''
|
||||
if not addr in frames:
|
||||
frames[addr] = [0 for _i in range(FRAME_WORD_COUNT)]
|
||||
|
||||
|
||||
class FasmAssembler(object):
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
|
|
@ -44,7 +49,8 @@ class FasmAssembler(object):
|
|||
|
||||
for bits_info in self.grid.iter_all_frames():
|
||||
for coli in range(bits_info.bits.frames):
|
||||
init_frame_at_address(frames, bits_info.bits.base_address + coli)
|
||||
init_frame_at_address(
|
||||
frames, bits_info.bits.base_address + coli)
|
||||
|
||||
return frames
|
||||
|
||||
|
|
@ -56,8 +62,11 @@ class FasmAssembler(object):
|
|||
if key in self.frames:
|
||||
if self.frames[key] != 1:
|
||||
raise FasmInconsistentBits(
|
||||
'FASM line "{}" wanted to set bit {} but was cleared by FASM line "{}"'.format(
|
||||
line, key, self.frames_line[key],
|
||||
'FASM line "{}" wanted to set bit {} but was cleared by FASM line "{}"'
|
||||
.format(
|
||||
line,
|
||||
key,
|
||||
self.frames_line[key],
|
||||
))
|
||||
return
|
||||
|
||||
|
|
@ -72,8 +81,11 @@ class FasmAssembler(object):
|
|||
if key in self.frames:
|
||||
if self.frames[key] != 0:
|
||||
raise FasmInconsistentBits(
|
||||
'FASM line "{}" wanted to clear bit {} but was set by FASM line "{}"'.format(
|
||||
line, key, self.frames_line[key],
|
||||
'FASM line "{}" wanted to clear bit {} but was set by FASM line "{}"'
|
||||
.format(
|
||||
line,
|
||||
key,
|
||||
self.frames_line[key],
|
||||
))
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import re
|
|||
import fasm
|
||||
from prjxray import bitstream
|
||||
|
||||
|
||||
def mk_fasm(tile_name, feature):
|
||||
""" Convert matches tile and feature to FasmLine tuple. """
|
||||
# Seperate addressing of multi-bit features:
|
||||
|
|
@ -16,18 +17,20 @@ def mk_fasm(tile_name, feature):
|
|||
feature = '{}.{}'.format(tile_name, tag_post)
|
||||
|
||||
return fasm.FasmLine(
|
||||
set_feature=fasm.SetFasmFeature(
|
||||
feature=feature,
|
||||
start=address,
|
||||
end=None,
|
||||
value=1,
|
||||
value_format=None,
|
||||
),
|
||||
annotations=None,
|
||||
comment=None)
|
||||
set_feature=fasm.SetFasmFeature(
|
||||
feature=feature,
|
||||
start=address,
|
||||
end=None,
|
||||
value=1,
|
||||
value_format=None,
|
||||
),
|
||||
annotations=None,
|
||||
comment=None)
|
||||
|
||||
|
||||
class FasmDisassembler(object):
|
||||
""" Given a Project X-ray data, outputs FasmLine tuples for bits set. """
|
||||
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
self.grid = self.db.grid()
|
||||
|
|
@ -47,26 +50,25 @@ class FasmDisassembler(object):
|
|||
return
|
||||
|
||||
comment = " WARNING: failed to load DB for tile type {}".format(
|
||||
gridinfo.tile_type)
|
||||
gridinfo.tile_type)
|
||||
yield fasm.FasmLine(
|
||||
set_feature=None,
|
||||
annotations=None,
|
||||
comment=comment,
|
||||
)
|
||||
set_feature=None,
|
||||
annotations=None,
|
||||
comment=comment,
|
||||
)
|
||||
yield fasm.FasmLine(
|
||||
set_feature=None,
|
||||
annotations=[
|
||||
fasm.Annotation('missing_segbits', gridinfo.tile_type),
|
||||
fasm.Annotation('exception', str(e)),
|
||||
],
|
||||
comment=None,
|
||||
)
|
||||
set_feature=None,
|
||||
annotations=[
|
||||
fasm.Annotation('missing_segbits', gridinfo.tile_type),
|
||||
fasm.Annotation('exception', str(e)),
|
||||
],
|
||||
comment=None,
|
||||
)
|
||||
|
||||
self.decode_warnings.add(gridinfo.tile_type)
|
||||
return
|
||||
|
||||
for ones_matched, feature in tile_segbits.match_bitdata(
|
||||
bits, bitdata):
|
||||
for ones_matched, feature in tile_segbits.match_bitdata(bits, bitdata):
|
||||
for frame, bit in ones_matched:
|
||||
bitdata[frame][1].remove(bit)
|
||||
|
||||
|
|
@ -102,9 +104,7 @@ class FasmDisassembler(object):
|
|||
tiles_checked.add(bits_info.tile)
|
||||
|
||||
for fasm_line in self.find_features_in_tile(
|
||||
bits_info.tile,
|
||||
bits_info.bits,
|
||||
bitdata,
|
||||
bits_info.tile, bits_info.bits, bitdata,
|
||||
verbose=verbose):
|
||||
yield fasm_line
|
||||
|
||||
|
|
@ -112,19 +112,22 @@ class FasmDisassembler(object):
|
|||
# Some bits were not decoded, add warning and annotations to
|
||||
# FASM.
|
||||
yield fasm.FasmLine(
|
||||
set_feature=None,
|
||||
annotations=None,
|
||||
comment=" In frame 0x{:08x} {} bits were not converted.".format(
|
||||
frame, len(bitdata[frame]),
|
||||
))
|
||||
set_feature=None,
|
||||
annotations=None,
|
||||
comment=" In frame 0x{:08x} {} bits were not converted.".
|
||||
format(
|
||||
frame,
|
||||
len(bitdata[frame]),
|
||||
))
|
||||
|
||||
for bit in bitdata[frame][1]:
|
||||
wordidx = bit // bitstream.WORD_SIZE_BITS
|
||||
bitidx = bit % bitstream.WORD_SIZE_BITS
|
||||
annotation = fasm.Annotation('unknown_bit',
|
||||
'{:08x}_{}_{}'.format(frame, wordidx, bitidx))
|
||||
annotation = fasm.Annotation(
|
||||
'unknown_bit', '{:08x}_{}_{}'.format(
|
||||
frame, wordidx, bitidx))
|
||||
yield fasm.FasmLine(
|
||||
set_feature=None,
|
||||
annotations=[annotation],
|
||||
comment=None,
|
||||
)
|
||||
set_feature=None,
|
||||
annotations=[annotation],
|
||||
comment=None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from collections import namedtuple
|
|||
import enum
|
||||
from prjxray import segment_map
|
||||
|
||||
|
||||
class SegmentType(enum.Enum):
|
||||
# Segments describing CLB features, interconnect, clocks and IOs.
|
||||
CLB_IO_CLK = 'CLB_IO_CLK'
|
||||
|
|
@ -9,11 +10,13 @@ class SegmentType(enum.Enum):
|
|||
# Segments describing block RAM initialization.
|
||||
BLOCK_RAM = 'BLOCK_RAM'
|
||||
|
||||
|
||||
GridLoc = namedtuple('GridLoc', 'grid_x grid_y')
|
||||
GridInfo = namedtuple('GridInfo', 'segment bits sites tile_type in_roi')
|
||||
Bits = namedtuple('Bits', 'base_address frames offset words')
|
||||
BitsInfo = namedtuple('BitsInfo', 'segment_type tile bits')
|
||||
|
||||
|
||||
class Grid(object):
|
||||
""" Object that represents grid for a given database.
|
||||
|
||||
|
|
@ -62,7 +65,7 @@ class Grid(object):
|
|||
frames=tileinfo['bits'][k]['frames'],
|
||||
offset=tileinfo['bits'][k]['offset'],
|
||||
words=tileinfo['bits'][k]['words'],
|
||||
)
|
||||
)
|
||||
|
||||
self.tileinfo[tile] = GridInfo(
|
||||
segment=tileinfo['segment'] if 'segment' in tileinfo else None,
|
||||
|
|
@ -107,10 +110,10 @@ class Grid(object):
|
|||
for tile, tileinfo in self.tileinfo.items():
|
||||
for segment_type, bits in tileinfo.bits.items():
|
||||
yield BitsInfo(
|
||||
segment_type=segment_type,
|
||||
tile=tile,
|
||||
bits=bits,
|
||||
)
|
||||
segment_type=segment_type,
|
||||
tile=tile,
|
||||
bits=bits,
|
||||
)
|
||||
|
||||
def get_segment_map(self):
|
||||
return segment_map.SegmentMap(self)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import json
|
||||
|
||||
|
||||
class Roi(object):
|
||||
def __init__(self, tilegrid_file, x1, x2, y1, y2):
|
||||
self.tilegrid_file = tilegrid_file
|
||||
|
|
@ -12,14 +13,13 @@ class Roi(object):
|
|||
def tile_in_roi(self, tilej):
|
||||
x = int(tilej['grid_x'])
|
||||
y = int(tilej['grid_y'])
|
||||
return self.x1 <= x and x <= self.x2 and self.y1 <= y and y <= self.y2
|
||||
return self.x1 <= x and x <= self.x2 and self.y1 <= y and y <= self.y2
|
||||
|
||||
def read_tilegrid(self):
|
||||
if not self.tilegrid:
|
||||
with open(self.tilegrid_file) as f:
|
||||
self.tilegrid = json.load(f)
|
||||
|
||||
|
||||
def gen_tiles(self, tile_types=None):
|
||||
'''
|
||||
tile_types: list of tile types to keep, or None for all
|
||||
|
|
@ -29,10 +29,9 @@ class Roi(object):
|
|||
|
||||
for tile_name, tilej in self.tilegrid.items():
|
||||
if self.tile_in_roi(tilej) and (tile_types is None
|
||||
or tilej['type'] in tile_types):
|
||||
or tilej['type'] in tile_types):
|
||||
yield (tile_name, tilej)
|
||||
|
||||
|
||||
def gen_sites(self, site_types=None):
|
||||
'''
|
||||
site_types: list of site types to keep, or None for all
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
from intervaltree import IntervalTree, Interval
|
||||
from prjxray import bitstream
|
||||
|
||||
|
||||
class SegmentMap(object):
|
||||
def __init__(self, grid):
|
||||
self.segment_tree = IntervalTree()
|
||||
|
||||
for bits_info in grid.iter_all_frames():
|
||||
self.segment_tree.add(Interval(
|
||||
begin=bits_info.bits.base_address,
|
||||
end=bits_info.bits.base_address+bits_info.bits.frames,
|
||||
data=bits_info,
|
||||
self.segment_tree.add(
|
||||
Interval(
|
||||
begin=bits_info.bits.base_address,
|
||||
end=bits_info.bits.base_address + bits_info.bits.frames,
|
||||
data=bits_info,
|
||||
))
|
||||
|
||||
def segment_info_for_frame(self, frame):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from collections import namedtuple
|
||||
import json
|
||||
from prjxray import lib
|
||||
|
||||
""" Database files available for a tile """
|
||||
TileDbs = namedtuple('TileDbs', 'segbits ppips mask tile_type')
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ from collections import namedtuple
|
|||
from prjxray import bitstream
|
||||
import enum
|
||||
|
||||
|
||||
class PsuedoPipType(enum.Enum):
|
||||
ALWAYS = 'always'
|
||||
DEFAULT = 'default'
|
||||
HINT = 'hint'
|
||||
|
||||
|
||||
def read_ppips(f):
|
||||
ppips = {}
|
||||
|
||||
|
|
@ -21,8 +23,10 @@ def read_ppips(f):
|
|||
|
||||
return ppips
|
||||
|
||||
|
||||
Bit = namedtuple('Bit', 'word_column word_bit isset')
|
||||
|
||||
|
||||
def parsebit(val):
|
||||
'''Return "!012_23" => (12, 23, False)'''
|
||||
isset = True
|
||||
|
|
@ -34,10 +38,11 @@ def parsebit(val):
|
|||
seg_word_column, word_bit_n = val.split('_')
|
||||
|
||||
return Bit(
|
||||
word_column=int(seg_word_column),
|
||||
word_bit=int(word_bit_n),
|
||||
isset=isset,
|
||||
)
|
||||
word_column=int(seg_word_column),
|
||||
word_bit=int(word_bit_n),
|
||||
isset=isset,
|
||||
)
|
||||
|
||||
|
||||
def read_segbits(f):
|
||||
segbits = {}
|
||||
|
|
@ -57,6 +62,7 @@ def read_segbits(f):
|
|||
|
||||
return segbits
|
||||
|
||||
|
||||
class TileSegbits(object):
|
||||
def __init__(self, tile_db):
|
||||
self.segbits = {}
|
||||
|
|
@ -65,7 +71,7 @@ class TileSegbits(object):
|
|||
|
||||
if tile_db.ppips is not None:
|
||||
with open(tile_db.ppips) as f:
|
||||
self.ppips = read_ppips(f)
|
||||
self.ppips = read_ppips(f)
|
||||
|
||||
if tile_db.segbits is not None:
|
||||
with open(tile_db.segbits) as f:
|
||||
|
|
@ -83,8 +89,8 @@ class TileSegbits(object):
|
|||
if base_feature not in self.feature_addresses:
|
||||
self.feature_addresses[base_feature] = {}
|
||||
|
||||
self.feature_addresses[base_feature][int(feature[sidx+1:eidx])] = feature
|
||||
|
||||
self.feature_addresses[base_feature][int(
|
||||
feature[sidx + 1:eidx])] = feature
|
||||
|
||||
def match_bitdata(self, bits, bitdata):
|
||||
""" Return matching features for tile bits data (grid.Bits) and bitdata.
|
||||
|
|
@ -96,8 +102,8 @@ class TileSegbits(object):
|
|||
for feature, segbit in self.segbits.items():
|
||||
match = True
|
||||
for query_bit in segbit:
|
||||
frame = bits.base_address + query_bit.word_column
|
||||
bitidx = bits.offset*bitstream.WORD_SIZE_BITS + query_bit.word_bit
|
||||
frame = bits.base_address + query_bit.word_column
|
||||
bitidx = bits.offset * bitstream.WORD_SIZE_BITS + query_bit.word_bit
|
||||
|
||||
if frame not in bitdata:
|
||||
match = not query_bit.isset
|
||||
|
|
@ -118,8 +124,8 @@ class TileSegbits(object):
|
|||
def inner():
|
||||
for query_bit in segbit:
|
||||
if query_bit.isset:
|
||||
frame = bits.base_address + query_bit.word_column
|
||||
bitidx = bits.offset*bitstream.WORD_SIZE_BITS + query_bit.word_bit
|
||||
frame = bits.base_address + query_bit.word_column
|
||||
bitidx = bits.offset * bitstream.WORD_SIZE_BITS + query_bit.word_bit
|
||||
yield (frame, bitidx)
|
||||
|
||||
yield (tuple(inner()), feature)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import os
|
|||
import re
|
||||
from .roi import Roi
|
||||
|
||||
|
||||
def get_db_root():
|
||||
return "%s/%s" % (
|
||||
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"))
|
||||
|
||||
|
||||
def roi_xy():
|
||||
x1 = int(os.getenv('XRAY_ROI_GRID_X1'))
|
||||
x2 = int(os.getenv('XRAY_ROI_GRID_X2'))
|
||||
|
|
@ -14,6 +16,7 @@ def roi_xy():
|
|||
|
||||
return (x1, x2), (y1, y2)
|
||||
|
||||
|
||||
def slice_xy():
|
||||
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
|
||||
# SLICE_X12Y100:SLICE_X27Y149
|
||||
|
|
@ -24,14 +27,16 @@ def slice_xy():
|
|||
ms = [int(m.group(i + 1)) for i in range(4)]
|
||||
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
|
||||
|
||||
|
||||
def get_roi():
|
||||
(x1, x2), (y1, y2) = roi_xy()
|
||||
return Roi(
|
||||
tilegrid_file=os.path.join(get_db_root(), 'tilegrid.json'),
|
||||
x1=x1,
|
||||
x2=x2,
|
||||
y1=y1,
|
||||
y2=y2)
|
||||
tilegrid_file=os.path.join(get_db_root(), 'tilegrid.json'),
|
||||
x1=x1,
|
||||
x2=x2,
|
||||
y1=y1,
|
||||
y2=y2)
|
||||
|
||||
|
||||
# we know that all bits for CLB MUXes are in frames 30 and 31, so filter all other bits
|
||||
def bitfilter_clb_mux(frame_idx, bit_idx):
|
||||
|
|
|
|||
|
|
@ -9,15 +9,18 @@ from prjxray import db
|
|||
from prjxray import fasm_disassembler
|
||||
from prjxray import bitstream
|
||||
|
||||
|
||||
def run(db_root, bits_file, verbose, canonical):
|
||||
disassembler = fasm_disassembler.FasmDisassembler(db.Database(db_root))
|
||||
|
||||
with open(bits_file) as f:
|
||||
bitdata = bitstream.load_bitdata(f)
|
||||
|
||||
print(fasm.fasm_tuple_to_string(
|
||||
disassembler.find_features_in_bitstream(bitdata, verbose=verbose),
|
||||
canonical=canonical))
|
||||
print(
|
||||
fasm.fasm_tuple_to_string(
|
||||
disassembler.find_features_in_bitstream(bitdata, verbose=verbose),
|
||||
canonical=canonical))
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
|
@ -34,16 +37,18 @@ def main():
|
|||
db_root_kwargs['required'] = False
|
||||
db_root_kwargs['default'] = os.path.join(database_dir, database)
|
||||
|
||||
parser.add_argument(
|
||||
'--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('bits_file', help='')
|
||||
parser.add_argument('verbose', help='Print lines for unknown tiles and bits',
|
||||
action='store_true')
|
||||
parser.add_argument('--canonical', help='Output canonical bitstream.',
|
||||
action='store_true')
|
||||
parser.add_argument(
|
||||
'verbose',
|
||||
help='Print lines for unknown tiles and bits',
|
||||
action='store_true')
|
||||
parser.add_argument(
|
||||
'--canonical', help='Output canonical bitstream.', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.db_root, args.bits_file, args.verbose, args.canonical)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import os
|
|||
import fasm
|
||||
from prjxray import db
|
||||
|
||||
|
||||
def process_fasm(db_root, fasm_file, canonical):
|
||||
database = db.Database(db_root)
|
||||
grid = database.grid()
|
||||
|
|
@ -20,7 +21,6 @@ def process_fasm(db_root, fasm_file, canonical):
|
|||
parts = feature.feature.split('.')
|
||||
tile = parts[0]
|
||||
|
||||
|
||||
gridinfo = grid.gridinfo_at_tilename(tile)
|
||||
tile_segbits = database.get_tile_segbits(gridinfo.tile_type)
|
||||
|
||||
|
|
@ -28,21 +28,23 @@ def process_fasm(db_root, fasm_file, canonical):
|
|||
if feature.start is not None:
|
||||
address = feature.start
|
||||
|
||||
feature_name = '{}.{}'.format(gridinfo.tile_type, '.'.join(parts[1:]))
|
||||
feature_name = '{}.{}'.format(
|
||||
gridinfo.tile_type, '.'.join(parts[1:]))
|
||||
|
||||
# Convert feature to bits. If no bits are set, feature is
|
||||
# psuedo pip, and should not be output from canonical FASM.
|
||||
bits = tuple(tile_segbits.feature_to_bits(feature_name, address=address))
|
||||
bits = tuple(
|
||||
tile_segbits.feature_to_bits(feature_name, address=address))
|
||||
if len(bits) == 0 and canonical:
|
||||
continue
|
||||
|
||||
# In canonical output, only output the canonical features.
|
||||
if canonical:
|
||||
yield fasm.FasmLine(
|
||||
set_feature=feature,
|
||||
annotations=None,
|
||||
comment=None,
|
||||
)
|
||||
set_feature=feature,
|
||||
annotations=None,
|
||||
comment=None,
|
||||
)
|
||||
|
||||
# If not in canonical mode, output original FASM line
|
||||
if not canonical:
|
||||
|
|
@ -50,15 +52,18 @@ def process_fasm(db_root, fasm_file, canonical):
|
|||
|
||||
|
||||
def run(db_root, fasm_file, canonical):
|
||||
print(fasm.fasm_tuple_to_string(
|
||||
process_fasm(db_root, fasm_file, canonical),
|
||||
canonical=canonical))
|
||||
print(
|
||||
fasm.fasm_tuple_to_string(
|
||||
process_fasm(db_root, fasm_file, canonical), canonical=canonical))
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Read FASM file, check against database, and output optionally canonical FASM.')
|
||||
description=
|
||||
'Read FASM file, check against database, and output optionally canonical FASM.'
|
||||
)
|
||||
|
||||
database_dir = os.getenv("XRAY_DATABASE_DIR")
|
||||
database = os.getenv("XRAY_DATABASE")
|
||||
|
|
@ -69,15 +74,14 @@ def main():
|
|||
db_root_kwargs['required'] = False
|
||||
db_root_kwargs['default'] = os.path.join(database_dir, database)
|
||||
|
||||
parser.add_argument(
|
||||
'--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('fasm_file', help='Input FASM file')
|
||||
parser.add_argument('--canonical', help='Output canonical bitstream.',
|
||||
action='store_true')
|
||||
parser.add_argument(
|
||||
'--canonical', help='Output canonical bitstream.', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.db_root, args.fasm_file, args.canonical)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import argparse
|
|||
import os
|
||||
import os.path
|
||||
|
||||
|
||||
def dump_frames_verbose(frames):
|
||||
print()
|
||||
print("Frames: %d" % len(frames))
|
||||
|
|
@ -16,6 +17,7 @@ def dump_frames_verbose(frames):
|
|||
'0x%08X ' % addr + ', '.join(['0x%08X' % w for w in words]) +
|
||||
'...')
|
||||
|
||||
|
||||
def dump_frames_sparse(frames):
|
||||
print()
|
||||
print("Frames: %d" % len(frames))
|
||||
|
|
@ -34,6 +36,7 @@ def dump_frames_sparse(frames):
|
|||
if w:
|
||||
print(' % 3d: 0x%08X' % (i, w))
|
||||
|
||||
|
||||
def dump_frm(f, frames):
|
||||
'''Write a .frm file given a list of frames, each containing a list of 101 32 bit words'''
|
||||
for addr in sorted(frames.keys()):
|
||||
|
|
@ -41,6 +44,7 @@ def dump_frm(f, frames):
|
|||
f.write(
|
||||
'0x%08X ' % addr + ','.join(['0x%08X' % w for w in words]) + '\n')
|
||||
|
||||
|
||||
def run(db_root, filename_in, f_out, sparse=False, debug=False):
|
||||
assembler = fasm_assembler.FasmAssembler(db.Database(db_root))
|
||||
assembler.parse_fasm_filename(filename_in)
|
||||
|
|
@ -67,15 +71,12 @@ def main():
|
|||
db_root_kwargs['required'] = False
|
||||
db_root_kwargs['default'] = os.path.join(database_dir, database)
|
||||
|
||||
parser.add_argument(
|
||||
'--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument(
|
||||
'--sparse', action='store_true', help="Don't zero fill all frames")
|
||||
parser.add_argument(
|
||||
'--debug', action='store_true', help="Print debug dump")
|
||||
parser.add_argument(
|
||||
'fn_in',
|
||||
help='Input FPGA assembly (.fasm) file')
|
||||
parser.add_argument('fn_in', help='Input FPGA assembly (.fasm) file')
|
||||
parser.add_argument(
|
||||
'fn_out',
|
||||
default='/dev/stdout',
|
||||
|
|
@ -88,8 +89,8 @@ def main():
|
|||
filename_in=args.fn_in,
|
||||
f_out=open(args.fn_out, 'w'),
|
||||
sparse=args.sparse,
|
||||
debug=args.debug
|
||||
)
|
||||
debug=args.debug)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@ import os.path
|
|||
import fasm
|
||||
from prjxray import db
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description=
|
||||
'Convert FASM to pip list'
|
||||
)
|
||||
parser = argparse.ArgumentParser(description='Convert FASM to pip list')
|
||||
|
||||
database_dir = os.getenv("XRAY_DATABASE_DIR")
|
||||
database = os.getenv("XRAY_DATABASE")
|
||||
|
|
@ -22,11 +20,8 @@ def main():
|
|||
db_root_kwargs['required'] = False
|
||||
db_root_kwargs['default'] = os.path.join(database_dir, database)
|
||||
|
||||
parser.add_argument(
|
||||
'--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument(
|
||||
'fn_in',
|
||||
help='Input FPGA assembly (.fasm) file')
|
||||
parser.add_argument('--db_root', help="Database root.", **db_root_kwargs)
|
||||
parser.add_argument('fn_in', help='Input FPGA assembly (.fasm) file')
|
||||
|
||||
args = parser.parse_args()
|
||||
database = db.Database(args.db_root)
|
||||
|
|
@ -47,7 +42,10 @@ def main():
|
|||
if pip.net_from == parts[2] and pip.net_to == parts[1]:
|
||||
yield '{}/{}.{}'.format(tile, gridinfo.tile_type, pip.name)
|
||||
|
||||
print('highlight_objects [concat {}]'.format(' '.join('[get_pips {}]'.format(pip) for pip in inner())))
|
||||
print(
|
||||
'highlight_objects [concat {}]'.format(
|
||||
' '.join('[get_pips {}]'.format(pip) for pip in inner())))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue