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

com.sun.electric.tool.placement.PlacementMinCut Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: PlacementMinCut.java
 *
 * Copyright (c) 2009, 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.placement;

import com.sun.electric.tool.Job;
import com.sun.electric.util.math.MutableInteger;
import com.sun.electric.util.math.Orientation;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Placement algorithm to do Min-Cut placement.
 */
public class PlacementMinCut extends PlacementFrame
{
	private final double PADDING = 5;
	private final boolean DEBUG = false;

	private Map> connectivityMap;

	/**
	 * Method to return the name of this placement algorithm.
	 * @return the name of this placement algorithm.
	 */
	public String getAlgorithmName() { return "Min-Cut"; }

	/**
	 * Method to do Min-Cut Placement.
	 * @param nodesToPlace a list of all nodes that are to be placed.
	 * @param allNetworks a list of all networks that connect the nodes.
	 * @param cellName the name of the cell being placed.
	 * @param job the Job (for testing abort).
	 */
	protected void runPlacement(List nodesToPlace, List allNetworks, String cellName, Job job)
	{
		// build the connectivity map with the number of connections between any two PlacementNodes
		connectivityMap = new HashMap>();
		for(PlacementNetwork plNet : allNetworks)
		{
			// add all combinations of the nodes on this net to the connectivity map
			List portsInNetwork = plNet.getPortsOnNet();
			for(int i=0; i singletons = new ArrayList();
		Partition topPart = new Partition(0);
		for(PlacementNode plNode : nodesToPlace)
		{
			boolean connected = false;
			for(PlacementPort plPort : plNode.getPorts())
			{
				PlacementNetwork net = plPort.getPlacementNetwork();
				if (net == null) continue;
				for(PlacementPort otherPort : net.getPortsOnNet())
				{
					if (otherPort.getPlacementNode() != plNode) { connected = true;   break; }
				}
				if (connected) break;
			}
			if (connected) topPart.allNodes.add(plNode); else
				singletons.add(plNode);
		}

//		// determine standard cell size
//		double scSize = getStandardCellSize(nodesToPlace, null);
//		double macroSize = scSize * scSize * 100;
//		System.out.println("Standard cell size is " + scSize + " so macro cells are " + macroSize + " square units or more");

		// build list of partitions to organize
		List partitionsToOrganize = new ArrayList();
		partitionsToOrganize.add(topPart);

		// iteratively go through list and organize them
		while (partitionsToOrganize.size() > 0)
		{
			// get partition
			Partition part = partitionsToOrganize.get(0);
			partitionsToOrganize.remove(0);
			if (part.allNodes.size() <= 2) continue;

			// split the partition randomly
			part.splitRandomly();
			if (DEBUG)
			{
				System.out.print("INITIAL NODES IN GROUP 1:");
				for(PlacementNode plNode : part.part1.allNodes) System.out.print(" "+plNode);
				System.out.println();
				System.out.print("INITIAL NODES IN GROUP 2:");
				for(PlacementNode plNode : part.part2.allNodes) System.out.print(" "+plNode);
				System.out.println();
			}

			// organize the two halves properly
			part.organize();
			if (DEBUG)
			{
				System.out.print("FINAL NODES IN GROUP 1:");
				for(PlacementNode plNode : part.part1.allNodes) System.out.print(" "+plNode);
				System.out.println();
				System.out.print("FINAL NODES IN GROUP 2:");
				for(PlacementNode plNode : part.part2.allNodes) System.out.print(" "+plNode);
				System.out.println();
			}

			if (part.part1.allNodes.size() > 2) partitionsToOrganize.add(part.part1);
			if (part.part2.allNodes.size() > 2) partitionsToOrganize.add(part.part2);
		}

		Point2D lastOffset = placePartitions(topPart, new Point2D.Double(0, 0));
		double x = lastOffset.getX(), y = lastOffset.getY();
		for(PlacementNode plNode : singletons)
		{
			plNode.setPlacement(x, y);
			x += PADDING;
		}
	}

	private Point2D placePartitions(Partition part, Point2D offset)
	{
		String indent = "";
		if (DEBUG)
		{
			for(int i=0; i properOrientation = findOrientations(part.allNodes);
			for(PlacementNode plNode : part.allNodes)
			{
				Orientation or = properOrientation.get(plNode);
				if (or != null)
					plNode.setOrientation(or);
			}
			off = new Point2D.Double(widestX, widestY);
		}
		if (DEBUG) System.out.println(indent+"NEW OFFSET ("+off.getX()+","+off.getY()+")");
		return off;
	}

	private static class OrientationConnection
	{
		PlacementPort thisPP;
		PlacementNode otherPN;
		PlacementPort otherPP;
	}

	/**
	 * Method to find the ideal orientation for all of the nodes at the bottom point.
	 * @param allNodes a List of PlacementNodes that have location, but not ideal orientation.
	 * @return a Map assigning orientation to each of the PlacementNodes in the list.
	 */
	private Map findOrientations(List allNodes)
	{
		Map properOrientation = new HashMap();
		if (allNodes.size() > 1)
		{
//boolean debug = currentCellName.equals("spiceHier{sch}");
//if (debug) System.out.println("FINDING ORIENTATIONS FOR PARTITION WITH "+allNodes.size()+" NODES");
			Map> allPossibilities = new HashMap>();
			for(PlacementNode plNode : allNodes)
			{
				// create a List of OrientationConnection objects for this NodeInst
				List oc = new ArrayList();
				allPossibilities.put(plNode, oc);
			}

			// add all of the connections to other nodes in the partition
			for(PlacementNode plNode : allNodes)
			{
				List oc = allPossibilities.get(plNode);

				for(PlacementPort plPort : plNode.getPorts())
				{
					PlacementNetwork plNet = plPort.getPlacementNetwork();
					if (plNet == null) continue;
					for(PlacementPort otherPlPort : plNet.getPortsOnNet())
					{
						PlacementNode otherPlNode = otherPlPort.getPlacementNode();
						if (otherPlNode == plNode) continue;
						if (allPossibilities.get(otherPlNode) == null) continue;

						OrientationConnection orc = new OrientationConnection();
						orc.thisPP = plPort;
						orc.otherPN = otherPlNode;
						orc.otherPP = otherPlPort;
						oc.add(orc);
					}
				}
			}

			// now find the optimal orientation choice for each NodeInst
			Orientation [] standardEight = new Orientation[] {Orientation.IDENT, Orientation.R, Orientation.RR, Orientation.RRR,
				Orientation.X, Orientation.XR, Orientation.XRR, Orientation.XRRR};
//			if (allNodes.size() == 2)
//			{
//				// try all combinations of the two
//				PlacementNode plNode1 = allNodes.get(0);
//				PlacementNode plNode2 = allNodes.get(1);
//				List oc = allPossibilities.get(plNode1);
//				Orientation betterOrientation1 = null;
//				Orientation betterOrientation2 = null;
//				double bestDist = Double.MAX_VALUE;
//				for(int i=0; i oc = allPossibilities.get(plNode);
					double bestDist = Double.MAX_VALUE;
					Orientation betterOrientation = null;
					for(int i=0; i destMap = connectivityMap.get(plNode1);
		if (destMap == null) return 0;
		MutableInteger mi = destMap.get(plNode2);
		if (mi == null) return 0;
		return mi.intValue();
	}

	/**
	 * Method to build the connectivity map by adding a connection between two PlacementNodes.
	 * This method is usually called twice with the PlacementNodes in both orders because
	 * the mapping is not symmetric.
	 * @param plNode1 the first PlacementNode.
	 * @param plNode2 the second PlacementNode.
	 */
	private void incrementMap(PlacementNode plNode1, PlacementNode plNode2)
	{
		Map destMap = connectivityMap.get(plNode1);
		if (destMap == null)
			connectivityMap.put(plNode1, destMap = new HashMap());
		MutableInteger mi = destMap.get(plNode2);
		if (mi == null) destMap.put(plNode2, mi = new MutableInteger(0));
		mi.increment();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy