blob: 2ba0c1f056783f42cae4bf2006c552188e687299 [file] [log] [blame] [edit]
import os.path
import simplejson as json
from utils import grid
from utils import tile
from utils import tile_segbits
from utils import site_type
from utils import connections
def get_available_databases(prjxray_root):
""" Return set of available directory to databases given the root directory
of prjxray-db
"""
db_types = set()
for d in os.listdir(prjxray_root):
if d.startswith("."):
continue
dpath = os.path.join(prjxray_root, d)
if os.path.exists(os.path.join(dpath, "settings.sh")):
db_types.add(dpath)
return db_types
class Database(object):
def __init__(self, db_root, part):
""" Create project x-ray Database at given db_root.
db_root: Path to directory containing settings.sh, *.db, tilegrid.json and
tileconn.json
"""
self.db_root = db_root
self.part = part
# tilegrid.json JSON object
self.tilegrid = None
self.tileconn = None
self.tile_types = None
self.tile_types = {}
self.tile_segbits = {}
self.site_types = {}
self.required_features = {}
for f in os.listdir(self.db_root):
if f.endswith('.json') and f.startswith('tile_type_'):
tile_type = f[len('tile_type_'):-len('.json')].lower()
segbits = os.path.join(self.db_root,
'segbits_{}.db'.format(tile_type))
if not os.path.isfile(segbits):
segbits = None
block_ram_segbits = os.path.join(
self.db_root, 'segbits_{}.block_ram.db'.format(tile_type))
if not os.path.isfile(block_ram_segbits):
block_ram_segbits = None
ppips = os.path.join(self.db_root,
'ppips_{}.db'.format(tile_type))
if not os.path.isfile(ppips):
ppips = None
mask = os.path.join(self.db_root,
'mask_{}.db'.format(tile_type))
if not os.path.isfile(mask):
mask = None
tile_type_file = os.path.join(
self.db_root,
'tile_type_{}.json'.format(tile_type.upper()))
if not os.path.isfile(tile_type_file):
tile_type_file = None
self.tile_types[tile_type.upper()] = tile.TileDbs(
segbits=segbits,
block_ram_segbits=block_ram_segbits,
ppips=ppips,
mask=mask,
tile_type=tile_type_file,
)
if f.endswith('.json') and f.startswith('site_type_'):
site_type_name = f[len('site_type_'):-len('.json')]
self.site_types[site_type_name] = os.path.join(self.db_root, f)
required_features_path = os.path.join(self.db_root, self.part,
"required_features.fasm")
if os.path.isfile(required_features_path):
with open(required_features_path, "r") as fp:
features = []
for line in fp:
line = line.strip()
if len(line) > 0:
features.append(line)
self.required_features[self.part] = set(features)
self.tile_types_obj = {}
def get_tile_types(self):
""" Return list of tile types """
return self.tile_types.keys()
def get_tile_type(self, tile_type):
""" Return Tile object for given tilename. """
if tile_type not in self.tile_types_obj:
self.tile_types_obj[tile_type] = tile.Tile(
tile_type, self.tile_types[tile_type])
return self.tile_types_obj[tile_type]
def _read_tilegrid(self):
""" Read tilegrid database if not already read. """
if not self.tilegrid:
with open(os.path.join(self.db_root, self.part,
'tilegrid.json')) as f:
self.tilegrid = json.load(f)
def _read_tileconn(self):
""" Read tileconn database if not already read. """
if not self.tileconn:
with open(os.path.join(self.db_root, self.part,
'tileconn.json')) as f:
self.tileconn = json.load(f)
def grid(self):
""" Return Grid object for database. """
self._read_tilegrid()
return grid.Grid(self, self.tilegrid)
def _read_tile_types(self):
for tile_type, db in self.tile_types.items():
with open(db.tile_type) as f:
self.tile_types[tile_type] = json.load(f)
def connections(self):
self._read_tilegrid()
self._read_tileconn()
self._read_tile_types()
tile_wires = dict((tile_type, db['wires'])
for tile_type, db in self.tile_types.items())
return connections.Connections(self.tilegrid, self.tileconn,
tile_wires)
def get_site_types(self):
return self.site_types.keys()
def get_site_type(self, site_type_name):
with open(self.site_types[site_type_name]) as f:
site_type_data = json.load(f)
return site_type.SiteType(site_type_data)
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()])
return self.tile_segbits[tile_type]
def get_required_fasm_features(self, part=None):
"""
Assembles a set of required fasm features for given part. Returns a list
of fasm features.
"""
# No required features in the db, return empty list
if self.required_features is None:
return set()
# Return list of part specific features
return self.required_features.get(part, set())