All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.tool.routing.SeaOfGates Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: SeaOfGates.java
 * Routing tool: Sea of Gates control
 * Written by: Steven M. Rubin
 *
 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
 *
 * Electric(tm) 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.
 *
 * Electric(tm) 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 */
package com.sun.electric.tool.routing;

import com.sun.electric.database.EditingPreferences;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.topology.ArcInst;
import com.sun.electric.database.topology.Geometric;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.variable.EditWindow_;
import com.sun.electric.database.variable.UserInterface;
import com.sun.electric.database.variable.Variable;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.Layer;
import com.sun.electric.technology.Technology;
import com.sun.electric.technology.technologies.Generic;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.routing.seaOfGates.SeaOfGatesEngine;
import com.sun.electric.tool.routing.seaOfGates.SeaOfGatesEngineFactory.SeaOfGatesEngineType;
import com.sun.electric.tool.routing.seaOfGates.SeaOfGatesHandlers;
import com.sun.electric.util.ElapseTimer;
import com.sun.electric.util.TextUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Class to control sea-of-gates routing.
 */
public class SeaOfGates
{
    /**
     * Method to run Sea-of-Gates routing on the current cell.
     * Presumes that it is inside of a Job.
     * @param justSubCells true to run the router on all sub-cells of the current cell
     * (but not on the current cell itself).
     */
    public static void seaOfGatesRoute(boolean justSubCells)
    {
    	if (justSubCells)
    	{
            // get cell
            UserInterface ui = Job.getUserInterface();
            Cell cell = ui.needCurrentCell();
            if (cell == null) return;
            Set subCells =  new HashSet();
            for(Iterator it = cell.getNodes(); it.hasNext(); )
            {
            	NodeInst ni = it.next();
            	if (ni.isCellInstance()) subCells.add((Cell)ni.getProto());
            }
            for(Cell subCell : subCells)
            {
                List selected = new ArrayList();
                for (Iterator it = subCell.getArcs(); it.hasNext(); )
                {
                	ArcInst ai = it.next();
                    if (ai.getProto() != Generic.tech().unrouted_arc) continue;
                    selected.add(ai);
                }
                if (!selected.isEmpty())
                {
                    // Run seaOfGatesRoute on subcell
                    SeaOfGatesHandlers.startInJob(subCell, selected, SeaOfGatesEngineType.defaultVersion);
                }
            }
    	} else
    	{
    		seaOfGatesRoute(SeaOfGatesEngineType.defaultVersion);
    	}
    }

    /**
     * Method to run Sea-of-Gates routing on the current cell, using a specified routing engine type.
     * Presumes that it is inside of a Job.
     */
    public static void seaOfGatesRoute(SeaOfGatesEngineType version)
    {
        // get cell and network information
        UserInterface ui = Job.getUserInterface();
        Cell cell = ui.needCurrentCell();
        if (cell == null) return;

        // get list of selected nets
        List selected = getSelected();
        if (selected == null) return;

        // make sure there is something to route
        if (selected.isEmpty())
        {
            ui.showErrorMessage("There are no Unrouted Arcs in this cell", "Routing Error");
            return;
        }

        // Run seaOfGatesRoute on selected unrouted arcs in a separate job
        SeaOfGatesHandlers.startInJob(cell, selected, version);
    }
    
    /**
     * Method to run Sea-of-Gates routing on the current cell, using a specified routing engine.
     * Presumes that it is inside of a Job.
     */
    public static void seaOfGatesRoute(EditingPreferences ep, SeaOfGatesEngine router)
    {
        if (router == null) {
            throw new NullPointerException();
        }

        // get cell and network information
        UserInterface ui = Job.getUserInterface();
        Cell cell = ui.needCurrentCell();
        if (cell == null) return;

        // get list of selected nets
        List selected = getSelected();

        // make sure there is something to route
        if (selected.isEmpty())
        {
            ui.showErrorMessage("There are no Unrouted Arcs in this cell", "Routing Error");
            return;
        }

        // Run seaOfGatesRoute on selected unrouted arcs
        Job job = Job.getRunningJob();
		router.routeIt(SeaOfGatesHandlers.getDefault(cell, job, ep), cell, selected);
    }

    private static List getSelected() {
        EditWindow_ wnd = Job.getUserInterface().getCurrentEditWindow_();
        if (wnd == null) return null;
        Cell cell = wnd.getCell();
        if (cell == null) return null;
        
        // get list of selected nets
        List selected = new ArrayList();
        List highlighted = wnd.getHighlightedEObjs(false, true);
        for(Geometric h : highlighted)
        {
            ArcInst ai = (ArcInst)h;
            if (ai.getProto() != Generic.tech().unrouted_arc) continue;
            selected.add(ai);
        }
        if (selected.isEmpty())
        {
            for (Iterator it = cell.getArcs(); it.hasNext(); )
            {
            	ArcInst ai = it.next();
                if (ai.getProto() != Generic.tech().unrouted_arc) continue;
                selected.add(ai);
            }
        }
        return selected;
    }

     /**
     * Class to hold preferences during Sea-of-Gates routing run.
     */
    public static class SeaOfGatesOptions implements Serializable
    {
        public boolean useParallelFromToRoutes;
        public boolean useParallelRoutes;
        public double maxArcWidth;
        public int complexityLimit;
        public boolean useGlobalRouter, reRunFailedRoutes;
        public int forcedNumberOfThreads;
        public ElapseTimer theTimer;

        public SeaOfGatesOptions()
        {
            useParallelFromToRoutes = true;
            useParallelRoutes = false;
            maxArcWidth = 10;
            complexityLimit = 200000;
            useGlobalRouter = false;
            reRunFailedRoutes = false;
            forcedNumberOfThreads = 0;
        }

        public void getOptionsFromPreferences()
        {
            useParallelFromToRoutes = Routing.isSeaOfGatesUseParallelFromToRoutes();
            useParallelRoutes = Routing.isSeaOfGatesUseParallelRoutes();
            maxArcWidth = Routing.getSeaOfGatesMaxWidth();
            complexityLimit = Routing.getSeaOfGatesComplexityLimit();
            useGlobalRouter = Routing.isSeaOfGatesUseGlobalRouting();
            reRunFailedRoutes = Routing.isSeaOfGatesRerunFailedRoutes();
            forcedNumberOfThreads = Routing.getSeaOfGatesForcedProcessorCount();
        }
    }

    /**
     * Class to define Sea-of-Gates routing parameters that apply only to a specific Cell.
     */
    public static class SeaOfGatesCellParameters implements Serializable
	{
    	private Cell cell;
    	private boolean steinerDone, favorHorVer, horEven;
    	private Map horizontalGrid, verticalGrid, horizontalGridOff, verticalGridOff;
    	private Set preventedArcs, favoredArcs;

		/** key of Variable holding SOG parameters. */	private static final Variable.Key ROUTING_SOG_PARAMETERS_KEY = Variable.newKey("ATTR_ROUTING_SOG_PARAMETERS");

		public SeaOfGatesCellParameters(Cell cell)
		{
			this.cell = cell;
			this.steinerDone = false;
			this.favorHorVer = true;
			this.horEven = false;
			this.horizontalGrid = new HashMap();
			this.verticalGrid = new HashMap();
			this.horizontalGridOff = new HashMap();
			this.verticalGridOff = new HashMap();
			this.preventedArcs = new HashSet();
			this.favoredArcs = new HashSet();
			Variable var = cell.getVar(ROUTING_SOG_PARAMETERS_KEY);
			if (var != null)
			{
				String[] lines = (String[])var.getObject();
				for(int i=0; i= 3)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							double gridSize = TextUtils.atof(parts[2]);
							horizontalGrid.put(ap, new Double(gridSize));
							continue;
						}
					}
					if (parts[0].equalsIgnoreCase("ArcVGrid") && parts.length >= 3)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							double gridSize = TextUtils.atof(parts[2]);
							verticalGrid.put(ap, new Double(gridSize));
							continue;
						}
					}
					if (parts[0].equalsIgnoreCase("ArcHGridOff") && parts.length >= 3)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							double gridSize = TextUtils.atof(parts[2]);
							horizontalGridOff.put(ap, new Double(gridSize));
							continue;
						}
					}
					if (parts[0].equalsIgnoreCase("ArcVGridOff") && parts.length >= 3)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							double gridSize = TextUtils.atof(parts[2]);
							verticalGridOff.put(ap, new Double(gridSize));
							continue;
						}
					}
					if (parts[0].equalsIgnoreCase("ArcAvoid") && parts.length >= 2)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							preventedArcs.add(ap);
							continue;
						}
					}
					if (parts[0].equalsIgnoreCase("ArcFavor") && parts.length >= 2)
					{
						int colonPos = parts[1].indexOf(':');
						if (colonPos >= 0)
						{
							String techName = parts[1].substring(0, colonPos);
							String layerName = parts[1].substring(colonPos+1);
							Technology tech = Technology.findTechnology(techName);
							ArcProto ap = tech.findArcProto(layerName);
							favoredArcs.add(ap);
							continue;
						}
					}
				}
			}
		}

		public void saveParameters(EditingPreferences ep)
		{
			List strings = new ArrayList();

			// header
			strings.add("; Parameters for Cell " + cell.describe(false));

			// steiner trees
			if (steinerDone) strings.add("SteinerTreesDone");
			if (!favorHorVer) strings.add("IgnoreHorVer");
			if (horEven) strings.add("HorizontalEven");

			// ArcProto information
			for(ArcProto ap : horizontalGrid.keySet())
			{
				Double grid = horizontalGrid.get(ap);
				strings.add("ArcHGrid " + ap.getTechnology().getTechName() + ":" + ap.getName() + " " + TextUtils.formatDouble(grid.doubleValue()));
			}
			for(ArcProto ap : horizontalGridOff.keySet())
			{
				Double grid = horizontalGridOff.get(ap);
				strings.add("ArcHGridOff " + ap.getTechnology().getTechName() + ":" + ap.getName() + " " + TextUtils.formatDouble(grid.doubleValue()));
			}
			for(ArcProto ap : verticalGrid.keySet())
			{
				Double grid = verticalGrid.get(ap);
				strings.add("ArcVGrid " + ap.getTechnology().getTechName() + ":" + ap.getName() + " " + TextUtils.formatDouble(grid.doubleValue()));
			}
			for(ArcProto ap : verticalGridOff.keySet())
			{
				Double grid = verticalGridOff.get(ap);
				strings.add("ArcVGridOff " + ap.getTechnology().getTechName() + ":" + ap.getName() + " " + TextUtils.formatDouble(grid.doubleValue()));
			}
			for(ArcProto ap : preventedArcs)
			{
				strings.add("ArcAvoid " + ap.getTechnology().getTechName() + ":" + ap.getName());
			}
			for(ArcProto ap : favoredArcs)
			{
				strings.add("ArcFavor " + ap.getTechnology().getTechName() + ":" + ap.getName());
			}

			String[] paramArray = new String[strings.size()];
			for(int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy