2020-05-06 04:42:15 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
#
|
|
|
|
|
# Copyright (C) 2017-2020 The Project X-Ray Authors.
|
|
|
|
|
#
|
|
|
|
|
# Use of this source code is governed by a ISC-style
|
|
|
|
|
# license that can be found in the LICENSE file or at
|
|
|
|
|
# https://opensource.org/licenses/ISC
|
|
|
|
|
#
|
|
|
|
|
# SPDX-License-Identifier: ISC
|
2019-02-20 20:45:03 +01:00
|
|
|
import xjson
|
2018-10-23 23:37:44 +02:00
|
|
|
import csv
|
|
|
|
|
import argparse
|
|
|
|
|
import sys
|
2019-02-13 02:25:52 +01:00
|
|
|
import fasm
|
2018-10-30 17:14:34 +01:00
|
|
|
from prjxray.db import Database
|
|
|
|
|
from prjxray.roi import Roi
|
2020-01-15 16:55:12 +01:00
|
|
|
from prjxray.util import get_db_root, get_part
|
2020-02-18 15:43:53 +01:00
|
|
|
from prjxray.xjson import extract_numbers
|
2018-10-23 23:37:44 +02:00
|
|
|
|
2018-10-24 00:15:47 +02:00
|
|
|
|
2018-10-30 17:14:34 +01:00
|
|
|
def set_port_wires(ports, name, pin, wires_outside_roi):
|
|
|
|
|
for port in ports:
|
|
|
|
|
if name == port['name']:
|
2020-02-18 15:43:53 +01:00
|
|
|
port['wires_outside_roi'] = sorted(
|
|
|
|
|
wires_outside_roi, key=extract_numbers)
|
2018-10-30 17:14:34 +01:00
|
|
|
assert port['pin'] == pin
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
assert False, name
|
|
|
|
|
|
2018-10-30 21:15:15 +01:00
|
|
|
|
2018-10-23 23:37:44 +02:00
|
|
|
def main():
|
2018-10-24 00:15:47 +02:00
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
|
description=
|
|
|
|
|
"Creates design.json from output of ROI generation tcl script.")
|
2018-10-23 23:37:44 +02:00
|
|
|
parser.add_argument('--design_txt', required=True)
|
|
|
|
|
parser.add_argument('--design_info_txt', required=True)
|
2018-10-30 17:14:34 +01:00
|
|
|
parser.add_argument('--pad_wires', required=True)
|
2019-02-13 02:25:52 +01:00
|
|
|
parser.add_argument('--design_fasm', required=True)
|
2018-10-23 23:37:44 +02:00
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
2019-02-14 17:27:43 +01:00
|
|
|
design_json = {}
|
|
|
|
|
design_json['ports'] = []
|
|
|
|
|
design_json['info'] = {}
|
2018-10-23 23:37:44 +02:00
|
|
|
with open(args.design_txt) as f:
|
|
|
|
|
for d in csv.DictReader(f, delimiter=' '):
|
2019-02-14 17:27:43 +01:00
|
|
|
design_json['ports'].append(d)
|
2018-10-23 23:37:44 +02:00
|
|
|
|
|
|
|
|
with open(args.design_info_txt) as f:
|
|
|
|
|
for l in f:
|
|
|
|
|
name, value = l.strip().split(' = ')
|
|
|
|
|
|
2019-02-14 17:27:43 +01:00
|
|
|
design_json['info'][name] = int(value)
|
2018-10-23 23:37:44 +02:00
|
|
|
|
2020-01-15 16:55:12 +01:00
|
|
|
db = Database(get_db_root(), get_part())
|
2018-10-30 17:14:34 +01:00
|
|
|
grid = db.grid()
|
|
|
|
|
|
|
|
|
|
roi = Roi(
|
2018-10-30 21:15:15 +01:00
|
|
|
db=db,
|
2019-02-14 17:27:43 +01:00
|
|
|
x1=design_json['info']['GRID_X_MIN'],
|
|
|
|
|
y1=design_json['info']['GRID_Y_MIN'],
|
|
|
|
|
x2=design_json['info']['GRID_X_MAX'],
|
|
|
|
|
y2=design_json['info']['GRID_Y_MAX'],
|
2018-10-30 21:15:15 +01:00
|
|
|
)
|
2018-10-30 17:14:34 +01:00
|
|
|
|
|
|
|
|
with open(args.pad_wires) as f:
|
|
|
|
|
for l in f:
|
|
|
|
|
parts = l.strip().split(' ')
|
|
|
|
|
name = parts[0]
|
|
|
|
|
pin = parts[1]
|
|
|
|
|
wires = parts[2:]
|
|
|
|
|
|
|
|
|
|
wires_outside_roi = []
|
|
|
|
|
|
|
|
|
|
for wire in wires:
|
|
|
|
|
tile = wire.split('/')[0]
|
|
|
|
|
|
|
|
|
|
loc = grid.loc_of_tilename(tile)
|
|
|
|
|
|
|
|
|
|
if not roi.tile_in_roi(loc):
|
|
|
|
|
wires_outside_roi.append(wire)
|
|
|
|
|
|
2019-02-14 17:27:43 +01:00
|
|
|
set_port_wires(design_json['ports'], name, pin, wires_outside_roi)
|
2018-10-30 17:14:34 +01:00
|
|
|
|
2019-02-13 02:25:52 +01:00
|
|
|
frames_in_use = set()
|
|
|
|
|
for tile in roi.gen_tiles():
|
|
|
|
|
gridinfo = grid.gridinfo_at_tilename(tile)
|
|
|
|
|
|
|
|
|
|
for bit in gridinfo.bits.values():
|
|
|
|
|
frames_in_use.add(bit.base_address)
|
|
|
|
|
|
|
|
|
|
required_features = []
|
|
|
|
|
for fasm_line in fasm.parse_fasm_filename(args.design_fasm):
|
|
|
|
|
if fasm_line.annotations:
|
|
|
|
|
for annotation in fasm_line.annotations:
|
|
|
|
|
if annotation.name != 'unknown_segment':
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
unknown_base_address = int(annotation.value, 0)
|
|
|
|
|
|
2019-03-21 16:40:18 +01:00
|
|
|
assert False, "Found unknown bit in base address 0x{:08x}".format(
|
2019-02-13 02:37:30 +01:00
|
|
|
unknown_base_address)
|
2019-02-13 02:25:52 +01:00
|
|
|
|
|
|
|
|
if not fasm_line.set_feature:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
tile = fasm_line.set_feature.feature.split('.')[0]
|
|
|
|
|
|
|
|
|
|
loc = grid.loc_of_tilename(tile)
|
|
|
|
|
gridinfo = grid.gridinfo_at_tilename(tile)
|
|
|
|
|
|
|
|
|
|
not_in_roi = not roi.tile_in_roi(loc)
|
|
|
|
|
|
2019-03-21 16:40:18 +01:00
|
|
|
if not_in_roi:
|
2019-02-13 02:25:52 +01:00
|
|
|
required_features.append(fasm_line)
|
|
|
|
|
|
2020-02-14 18:29:29 +01:00
|
|
|
design_json['required_features'] = sorted(
|
|
|
|
|
fasm.fasm_tuple_to_string(required_features,
|
2020-02-18 15:43:53 +01:00
|
|
|
canonical=True).split('\n'),
|
|
|
|
|
key=extract_numbers)
|
2020-02-14 18:29:29 +01:00
|
|
|
|
2020-02-18 15:43:53 +01:00
|
|
|
design_json['ports'].sort(key=lambda x: extract_numbers(x['name']))
|
2019-02-13 02:25:52 +01:00
|
|
|
|
2019-02-20 20:45:03 +01:00
|
|
|
xjson.pprint(sys.stdout, design_json)
|
2018-10-23 23:37:44 +02:00
|
|
|
|
2018-10-24 00:15:47 +02:00
|
|
|
|
2018-10-23 23:37:44 +02:00
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|