/* * Copyright (C) 2014 Alfons Wirtz * website www.freerouting.net * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License at <http://www.gnu.org/licenses/> * for more details. * * AutorouteSettings.java * * Created on 27. Juli 2006, 09:16 * */ package interactive; import board.RoutingBoard; import autoroute.AutorouteControl.ExpansionCostFactor; /** * Contains the interactive settings for the autorouter. * * @author Alfons Wirtz */ public class AutorouteSettings implements java.io.Serializable { /** Creates a new instance of AutorouteSettings */ public AutorouteSettings(int p_layer_count) { layer_active_arr = new boolean[p_layer_count]; preferred_direction_is_horizontal_arr = new boolean[p_layer_count]; preferred_direction_trace_cost_arr = new double[p_layer_count]; against_preferred_direction_trace_cost_arr = new double[p_layer_count]; } /** Creates a new instance of AutorouteSettings */ public AutorouteSettings(RoutingBoard p_board) { this(p_board.get_layer_count()); // set default values start_ripup_costs = 100; start_pass_no = 1; vias_allowed = true; with_fanout = false; with_autoroute = true; with_postroute = true; via_costs = 50; plane_via_costs = 5; double horizontal_width = p_board.bounding_box.width(); double vertical_width = p_board.bounding_box.height(); int layer_count = p_board.get_layer_count(); // additional costs aagainst preferred direcction with 1 digit behind the decimal point. double horizontal_add_costs_against_preferred_dir = 0.1 * Math.round(10 * horizontal_width / vertical_width); double vertical_add_costs_against_preferred_dir = 0.1 * Math.round(10 * vertical_width / horizontal_width); // make more horizontal pefered direction, if the board is horizontal. boolean curr_preferred_direction_is_horizontal = horizontal_width < vertical_width; for (int i = 0; i < layer_count; ++i) { layer_active_arr[i] = p_board.layer_structure.arr[i].is_signal; if (p_board.layer_structure.arr[i].is_signal) { curr_preferred_direction_is_horizontal = !curr_preferred_direction_is_horizontal; } preferred_direction_is_horizontal_arr[i] = curr_preferred_direction_is_horizontal; preferred_direction_trace_cost_arr[i] = 1; against_preferred_direction_trace_cost_arr[i] = 1; if (curr_preferred_direction_is_horizontal) { against_preferred_direction_trace_cost_arr[i] += horizontal_add_costs_against_preferred_dir; } else { against_preferred_direction_trace_cost_arr[i] += vertical_add_costs_against_preferred_dir; } } int signal_layer_count = p_board.layer_structure.signal_layer_count(); if (signal_layer_count > 2) { double outer_add_costs = 0.2 * signal_layer_count; // increase costs on the outer layers. preferred_direction_trace_cost_arr[0] += outer_add_costs; preferred_direction_trace_cost_arr[layer_count - 1] += outer_add_costs; against_preferred_direction_trace_cost_arr[0] += outer_add_costs; against_preferred_direction_trace_cost_arr[layer_count - 1] += outer_add_costs; } } /** * Copy constructor */ public AutorouteSettings(AutorouteSettings p_settings) { start_ripup_costs = p_settings.start_ripup_costs; start_pass_no = p_settings.start_pass_no; via_costs = p_settings.via_costs; plane_via_costs = p_settings.plane_via_costs; layer_active_arr = new boolean[p_settings.layer_active_arr.length]; System.arraycopy(p_settings.layer_active_arr, 0, this.layer_active_arr, 0, layer_active_arr.length); preferred_direction_is_horizontal_arr = new boolean[p_settings.preferred_direction_is_horizontal_arr.length]; System.arraycopy(p_settings.preferred_direction_is_horizontal_arr, 0, this.preferred_direction_is_horizontal_arr, 0, preferred_direction_is_horizontal_arr.length); preferred_direction_trace_cost_arr = new double[p_settings.preferred_direction_trace_cost_arr.length]; System.arraycopy(p_settings.preferred_direction_trace_cost_arr, 0, preferred_direction_trace_cost_arr, 0, preferred_direction_trace_cost_arr.length); against_preferred_direction_trace_cost_arr = new double[p_settings.against_preferred_direction_trace_cost_arr.length]; System.arraycopy(p_settings.against_preferred_direction_trace_cost_arr, 0, against_preferred_direction_trace_cost_arr, 0, against_preferred_direction_trace_cost_arr.length); } public void set_start_ripup_costs(int p_value) { start_ripup_costs = Math.max(p_value, 1); } public int get_start_ripup_costs() { return start_ripup_costs; } public void set_pass_no(int p_value) { start_pass_no = Math.max(p_value, 1); start_pass_no = Math.min(start_pass_no, 99); } public int get_pass_no() { return start_pass_no; } public void increment_pass_no() { ++start_pass_no; } public void set_with_fanout(boolean p_value) { with_fanout = p_value; } public boolean get_with_fanout() { return with_fanout; } public void set_with_autoroute(boolean p_value) { with_autoroute = p_value; } public boolean get_with_autoroute() { return with_autoroute; } public void set_with_postroute(boolean p_value) { with_postroute = p_value; } public boolean get_with_postroute() { return with_postroute; } public void set_vias_allowed(boolean p_value) { vias_allowed = p_value; } public boolean get_vias_allowed() { return vias_allowed; } public void set_via_costs(int p_value) { via_costs = Math.max(p_value, 1); } public int get_via_costs() { return via_costs; } public void set_plane_via_costs(int p_value) { plane_via_costs = Math.max(p_value, 1); } public int get_plane_via_costs() { return plane_via_costs; } public void set_layer_active(int p_layer, boolean p_value) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.set_layer_active: p_layer out of range"); return; } layer_active_arr[p_layer] = p_value; } public boolean get_layer_active(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_layer_active: p_layer out of range"); return false; } return layer_active_arr[p_layer]; } public void set_preferred_direction_is_horizontal(int p_layer, boolean p_value) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.set_preferred_direction_is_horizontal: p_layer out of range"); return; } preferred_direction_is_horizontal_arr[p_layer] = p_value; } public boolean get_preferred_direction_is_horizontal(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_preferred_direction_is_horizontal: p_layer out of range"); return false; } return preferred_direction_is_horizontal_arr[p_layer]; } public void set_preferred_direction_trace_costs(int p_layer, double p_value) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.set_preferred_direction_trace_costs: p_layer out of range"); return; } preferred_direction_trace_cost_arr[p_layer] = Math.max(p_value, 0.1); } public double get_preferred_direction_trace_costs(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_preferred_direction_trace_costs: p_layer out of range"); return 0; } return preferred_direction_trace_cost_arr[p_layer]; } public double get_against_preferred_direction_trace_costs(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_against_preferred_direction_trace_costs: p_layer out of range"); return 0; } return against_preferred_direction_trace_cost_arr[p_layer]; } public double get_horizontal_trace_costs(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_preferred_direction_trace_costs: p_layer out of range"); return 0; } double result; if (preferred_direction_is_horizontal_arr[p_layer]) { result = preferred_direction_trace_cost_arr[p_layer]; } else { result = against_preferred_direction_trace_cost_arr[p_layer]; } return result; } public void set_against_preferred_direction_trace_costs(int p_layer, double p_value) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.set_against_preferred_direction_trace_costs: p_layer out of range"); return; } against_preferred_direction_trace_cost_arr[p_layer] = Math.max(p_value, 0.1); } public double get_vertical_trace_costs(int p_layer) { if (p_layer < 0 || p_layer >= layer_active_arr.length) { System.out.println("AutorouteSettings.get_against_preferred_direction_trace_costs: p_layer out of range"); return 0; } double result; if (preferred_direction_is_horizontal_arr[p_layer]) { result = against_preferred_direction_trace_cost_arr[p_layer]; } else { result = preferred_direction_trace_cost_arr[p_layer]; } return result; } public ExpansionCostFactor[] get_trace_cost_arr() { ExpansionCostFactor[] result = new ExpansionCostFactor[preferred_direction_trace_cost_arr.length]; for (int i = 0; i < result.length; ++i) { result[i] = new ExpansionCostFactor(get_horizontal_trace_costs(i), get_vertical_trace_costs(i)); } return result; } private boolean with_fanout; private boolean with_autoroute; private boolean with_postroute; private boolean vias_allowed; private int via_costs; private int plane_via_costs; private int start_ripup_costs; private int start_pass_no; private final boolean[] layer_active_arr; private final boolean[] preferred_direction_is_horizontal_arr; private final double[] preferred_direction_trace_cost_arr; private final double[] against_preferred_direction_trace_cost_arr; }