2022-01-15 00:38:05 -07:00
|
|
|
#!/usr/bin/python3 -tt
|
2022-01-15 00:28:49 -07:00
|
|
|
# -*- coding: utf-8 -*-
|
2022-01-15 01:43:52 -07:00
|
|
|
# Copyright (C) 2014 Chris Hinsley All Rights Reserved
|
|
|
|
# Copyright (C) 2022 Jeff Moe
|
2022-01-15 00:28:49 -07:00
|
|
|
|
|
|
|
import sys, argparse, router
|
|
|
|
from copy import deepcopy
|
|
|
|
from ast import literal_eval
|
|
|
|
from mymath import *
|
|
|
|
|
|
|
|
def main():
|
2022-01-15 13:41:38 -07:00
|
|
|
parser = argparse.ArgumentParser(description = 'Pcb layout optimizer.', formatter_class = argparse.RawTextHelpFormatter)
|
|
|
|
parser.add_argument('infile', nargs = '?', type = argparse.FileType('r'), default = sys.stdin, help = 'filename, default stdin')
|
|
|
|
parser.add_argument('--t', nargs = 1, type = int, default = [600], help = 'timeout in seconds, default 600')
|
|
|
|
parser.add_argument('--v', nargs = 1, type = int, default = [0], choices = range(0, 2), help = 'verbosity level 0..1, default 0')
|
|
|
|
parser.add_argument('--s', nargs = 1, type = int, default = [1], help = 'number of samples, default 1')
|
|
|
|
parser.add_argument('--r', nargs = 1, type = int, default = [1], choices = range(1, 5), help = 'grid resolution 1..4, default 1')
|
|
|
|
parser.add_argument('--z', nargs = 1, type = int, default = [0], choices = range(0, 2), help = 'minimize vias 0..1, default 0')
|
|
|
|
parser.add_argument('--d', nargs = 1, type = int, default = [0], choices = range(0, 6), \
|
|
|
|
help = 'distance metric 0..5, default 0.\n' \
|
|
|
|
'0 -> manhattan\n1 -> squared_euclidean\n2 -> euclidean\n3 -> chebyshev\n4 -> reciprocal\n5 -> random')
|
|
|
|
parser.add_argument('--fr', nargs = 1, type = int, default = [2], choices = range(1, 6), help = 'flood range 1..5, default 2')
|
|
|
|
parser.add_argument('--xr', nargs = 1, type = int, default = [1], choices = range(0, 6), help = 'even layer x range 0..5, default 1')
|
|
|
|
parser.add_argument('--yr', nargs = 1, type = int, default = [1], choices = range(0, 6), help = 'odd layer y range 0..5, default 1')
|
|
|
|
args = parser.parse_args()
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
flood_range = args.fr[0]
|
|
|
|
flood_range_x_even_layer = args.xr[0]
|
|
|
|
flood_range_y_odd_layer = args.yr[0]
|
|
|
|
path_range = flood_range + 0
|
|
|
|
path_range_x_even_layer = flood_range_x_even_layer + 0
|
|
|
|
path_range_y_odd_layer = flood_range_y_odd_layer + 0
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
routing_flood_vectors = [[(x, y, 0) for x in range(-flood_range_x_even_layer, flood_range_x_even_layer + 1) for y in range(-flood_range, flood_range + 1) \
|
|
|
|
if length_2d((x, y)) > 0.1 and length_2d((x, y)) <= flood_range] + [(0, 0, -1), (0, 0, 1)], \
|
|
|
|
[(x, y, 0) for x in range(-flood_range, flood_range + 1) for y in range(-flood_range_y_odd_layer, flood_range_y_odd_layer + 1) \
|
|
|
|
if length_2d((x, y)) > 0.1 and length_2d((x, y)) <= flood_range] + [(0, 0, -1), (0, 0, 1)]]
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
routing_path_vectors = [[(x, y, 0) for x in range(-path_range_x_even_layer, path_range_x_even_layer + 1) for y in range(-path_range, path_range + 1) \
|
|
|
|
if length_2d((x, y)) > 0.1 and length_2d((x, y)) <= path_range] + [(0, 0, -1), (0, 0, 1)], \
|
|
|
|
[(x, y, 0) for x in range(-path_range, path_range + 1) for y in range(-path_range_y_odd_layer, path_range_y_odd_layer + 1) \
|
|
|
|
if length_2d((x, y)) > 0.1 and length_2d((x, y)) <= path_range] + [(0, 0, -1), (0, 0, 1)]]
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
dfunc = [manhattan_distance, squared_euclidean_distance, euclidean_distance, \
|
|
|
|
chebyshev_distance, reciprical_distance, random_distance][args.d[0]]
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
dimensions = literal_eval(args.infile.readline().strip())
|
|
|
|
pcb = router.Pcb(dimensions, routing_flood_vectors, routing_path_vectors, dfunc, args.r[0], args.v[0], args.z[0])
|
|
|
|
for line in args.infile:
|
|
|
|
track = literal_eval(line.strip())
|
|
|
|
if not track:
|
|
|
|
break
|
|
|
|
pcb.add_track(track)
|
|
|
|
args.infile.close()
|
2022-01-15 00:28:49 -07:00
|
|
|
|
2022-01-15 13:41:38 -07:00
|
|
|
pcb.print_pcb()
|
|
|
|
best_cost = None
|
|
|
|
best_pcb = None
|
|
|
|
for i in range(args.s[0]):
|
|
|
|
if not pcb.route(args.t[0]):
|
|
|
|
pcb.shuffle_netlist()
|
|
|
|
continue
|
|
|
|
cost = pcb.cost()
|
|
|
|
if best_cost == None or cost < best_cost:
|
|
|
|
best_cost = cost
|
|
|
|
best_pcb = deepcopy(pcb)
|
|
|
|
pcb.shuffle_netlist()
|
|
|
|
if best_pcb != None:
|
|
|
|
best_pcb.print_netlist()
|
|
|
|
best_pcb.print_stats()
|
|
|
|
else:
|
|
|
|
print([])
|
2022-01-15 00:28:49 -07:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2022-01-15 13:41:38 -07:00
|
|
|
main()
|