#!/usr/bin/python3 -tt # -*- coding: utf-8 -*- # Copyright (C) 2014 Chris Hinsley All Rights Reserved # Copyright (C) 2022 Jeff Moe import sys, argparse, router from copy import deepcopy from ast import literal_eval from mymath import * def main(): 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() 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 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)]] 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)]] dfunc = [manhattan_distance, squared_euclidean_distance, euclidean_distance, \ chebyshev_distance, reciprical_distance, random_distance][args.d[0]] 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() 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([]) if __name__ == '__main__': main()