blob: b4df1168c5417648694a2e252d49f1f5231e5211 [file] [log] [blame]
import json
import csv
import argparse
from collections import namedtuple
def get_module_ports(j, module):
if module not in j['modules']:
raise LookupError(
'module %s not in module list %s' %
(module, ', '.join(j['modules'].keys()))
)
for port in j['modules'][module]['ports']:
bits = j['modules'][module]['ports'][port]['bits']
if len(bits) > 1:
for idx, _ in enumerate(bits):
yield j['modules'][module]['ports'][port][
'direction'], '%s[%d]' % (port, idx)
else:
yield j['modules'][module]['ports'][port]['direction'], port
Pin = namedtuple('Pin', 'name is_clock is_input is_output')
def get_free_pin(available_pins, direction):
possible_pins = []
for pin in available_pins:
if pin.is_input and not pin.is_clock and direction == 'input':
possible_pins.append(pin)
if pin.is_output and direction == 'output':
possible_pins.append(pin)
assert possible_pins, "Did not find any *%s* pins in:\n%s" % (
direction, "\n ".join(str(x) for x in available_pins)
)
return possible_pins.pop(0)
def main():
parser = argparse.ArgumentParser(
description='Creates a pinmap file for a module for a given package.'
)
parser.add_argument('--design_json', help='Yosys JSON design input.')
parser.add_argument('--pinmap_csv', help='CSV pinmap definition.')
parser.add_argument(
'--module', help='Name of module to generate pindef for.'
)
args = parser.parse_args()
# Read in the pin map
pins = []
with open(args.pinmap_csv) as f:
for row in csv.DictReader(f):
if 'is_clock' in row:
is_clock = int(row['is_clock']) != 0
else:
is_clock = False
if 'is_input' in row:
is_input = int(row['is_input']) != 0
else:
is_input = True
if 'is_output' in row:
is_output = int(row['is_output']) != 0
else:
is_output = True
pins.append(
Pin(
name=row['name'],
is_clock=is_clock,
is_input=is_input,
is_output=is_output,
)
)
available_pins = list(pins)
# Read in the design and assign pins
import sys
with open(args.design_json) as f:
j = json.load(f)
for direction, port in get_module_ports(j, args.module):
pin = get_free_pin(available_pins, direction)
sys.stderr.write(
"Assigned %s to %s # %s\n" % (port, pin.name, direction)
)
print('set_io %s %s' % (port, pin.name))
available_pins.remove(pin)
if __name__ == '__main__':
main()